diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2286fd6277..3f595dc9df 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -60,8 +60,9 @@ jobs: engine-free: runs-on: ubuntu-latest - # Successful legs took 26-48 min on 2026-10-07..08 (n=22). - timeout-minutes: 75 + # Successful legs took 64-74 min on 2026-10-26, and a Python 3.14 leg on + # microcosm#1404 hit the old 75-minute cap; 120 is about 1.6x the slowest. + timeout-minutes: 120 strategy: fail-fast: false matrix: diff --git a/changelog.d/1301-uk-dense-signoff-2026-10-26.changed.md b/changelog.d/1301-uk-dense-signoff-2026-10-26.changed.md new file mode 100644 index 0000000000..94012961f5 --- /dev/null +++ b/changelog.d/1301-uk-dense-signoff-2026-10-26.changed.md @@ -0,0 +1 @@ +Sign dense build 1's gate-only failures for the local line (microcosm#1301, attempt uk-local-candidate-f100-s42-20261026T091056Z-824870f6): 1 national target-fit row, 6 local target-fit cells and 0 areas below the support floor, approved 2026-10-26; 24 entries that build 2 would fail are retired. Every signed row stays bound in the solve, each entry suppresses only the local line's release fence, and a build in which a signed row passes fails its entry as stale. diff --git a/changelog.d/uk-childcare-take-up-refit-2151.changed.md b/changelog.d/uk-childcare-take-up-refit-2151.changed.md new file mode 100644 index 0000000000..9fdc7c3d05 --- /dev/null +++ b/changelog.d/uk-childcare-take-up-refit-2151.changed.md @@ -0,0 +1 @@ +The UK childcare take-up rates are refitted with the tool-version-7 fitter on policyengine-uk 2.151.0, on the release-candidate spine built after microcosm#1383 (feed abf0921): Tax-Free Childcare 0.9134 (was 0.9697), working-parent hours 0.8217 (0.8262), targeted hours for 2-year-olds 0.8687 (0.6551) and under-2 usage at DfE age 0 0.7000 (0.6962). Age-1 usage stays at its upper bound of 1 and the conditional universal rate at its lower bound of 0, each with its reason restated on the new fit. The targeted rate rises because policyengine-uk 2.148.1 reads Universal Credit earnings before the work allowance, so fewer families qualify for the targeted two-year-old offer against the same DfE count. The DfE rows for working-parent children aged 2 to 4 and at 9 to 11 months and for early learning at 2 meet their targets; the age-1 row keeps its shortfall at the bound, and the two HMRC Tax-Free Childcare rows still cannot both be met. Each rate's fitting receipt names the input spine, engine and contract digests. diff --git a/changelog.d/uk-dense-signoff-withheld-national-rows.fixed.md b/changelog.d/uk-dense-signoff-withheld-national-rows.fixed.md new file mode 100644 index 0000000000..ba978ddbe8 --- /dev/null +++ b/changelog.d/uk-dense-signoff-withheld-national-rows.fixed.md @@ -0,0 +1 @@ +The dense sign-off drafter reads withheld national rows. Since María's rule of 2026-10-21 a thin national or regional row is withheld as a local cell is, so `targets.csv` leaves its figures blank; the drafter refused any such row, and it checked the national fit gate's withheld count against national rows alone, where the gate counts the surface's whole withheld set. It now carries the withheld national rows beside the local ones, signs none of them, matches the national gate's count, and compares them between the two builds. diff --git a/changelog.d/uk-drop-model-figure-withholding.changed.md b/changelog.d/uk-drop-model-figure-withholding.changed.md new file mode 100644 index 0000000000..ddf6578a14 --- /dev/null +++ b/changelog.d/uk-drop-model-figure-withholding.changed.md @@ -0,0 +1 @@ +UK builds no longer withhold model figures (María's ruling of 2026-10-26: the releases go only to the licensed private repository, and their users need the full diagnostics). A target row resting on fewer than ten source households, and a row that would give one back by difference, keep their estimates and errors in the calibration diagnostics, `targets.csv`, the gate reports and the run's evidence summaries; the fit gates judge every row; totals, losses and the size receipt are the solve's own; staged epochs carry their loss; and BRMA rows no longer carry a carrier verdict. This removes the differencing check, which ran for hours on the dense surface, and `--withhold-thin-rows-only`. Release certification refuses a run built while rows were withheld, and the release contract still checks the withheld rows of earlier releases. diff --git a/changelog.d/uk-orrery-publication-opt-in.changed.md b/changelog.d/uk-orrery-publication-opt-in.changed.md new file mode 100644 index 0000000000..037ed1caf2 --- /dev/null +++ b/changelog.d/uk-orrery-publication-opt-in.changed.md @@ -0,0 +1 @@ +UK builds no longer submit their saved graph to the public Orrery unless `--publish-orrery` asks for it (María's ruling of 2026-10-26). Before, a build that staged to Hugging Face published by default and `--no-publish-orrery` turned it off; that flag now states the default, and staging to the private repositories is unchanged. diff --git a/changelog.d/uk-orrery-summaries-no-row-figures.changed.md b/changelog.d/uk-orrery-summaries-no-row-figures.changed.md new file mode 100644 index 0000000000..cc69a2ca29 --- /dev/null +++ b/changelog.d/uk-orrery-summaries-no-row-figures.changed.md @@ -0,0 +1 @@ +The UK graph summaries that `--publish-orrery` submits no longer carry a target row's estimates and errors, the size summary's largest change in one row, or the gates' failure lines; a gate summary counts its failure lines instead. The build's private diagnostics and gate reports keep all of them. Since the build no longer withholds the rows resting on fewer than ten source households, the summaries could not tell those rows apart. The export now checks the summaries before it preserves anything for publication, and stops with the `unpublishable_summary` error code if one carries either. Without a preserved inventory, neither the build nor the emitter's retry command can submit them. diff --git a/changelog.d/uk-ship-area-support-figures.changed.md b/changelog.d/uk-ship-area-support-figures.changed.md new file mode 100644 index 0000000000..1e048d80c3 --- /dev/null +++ b/changelog.d/uk-ship-area-support-figures.changed.md @@ -0,0 +1 @@ +UK dense releases ship per-area support figures again (María's ruling of 2026-10-26, which drops the withholding of microcosm#1301): the area-support gate states an area's rows, Kish ESS and distinct sources beside the floors it misses, in its failures and its reviewed exclusions, and reports each level's minima; the weakest-area and support-limited rows of the diagnostics carry the figures beside `support_below_floor`; and the candidate manifest's support block states the minima. The release contract, the candidate pre-flight and the sign-off drafter's verify no longer walk the shipped files for these figures. The drafter still walks the entries it drafts, which go into a public pull request. diff --git a/changelog.d/uk-small-cell-rules-flag-only.changed.md b/changelog.d/uk-small-cell-rules-flag-only.changed.md new file mode 100644 index 0000000000..d7a755d5fd --- /dev/null +++ b/changelog.d/uk-small-cell-rules-flag-only.changed.md @@ -0,0 +1,4 @@ +A stage receipt's small-cell rule no longer fails a UK build (María's ruling of 2026-10-26); it flags. +- The gambling top-up and the annual-income stage refuse only when their fits cannot run: fewer than two donor households on either side of a gambling key, or no household reporting both pay measures. With one to nine, they run, and the receipt prints "<10" as before. A pay-concept ratio measured on one to nine households is held to its plausibility bounds rather than refused; on ten or more, a ratio past them still refuses. +- A stage gate that reads a figure its receipt prints "<10" now names what it left unchecked in its details, and passes on it. That covers the gambling key withheld nationally, a property purchase kind, a UC family type's caseloads, the annual-income ratios, a region's rewritten rows, the excise residuals and the legacy-closure flags. +- Counts a gate requires to be zero, and the declared donor-support floors, fail as before. diff --git a/changelog.d/uk-under-two-usage-signal-bound.changed.md b/changelog.d/uk-under-two-usage-signal-bound.changed.md new file mode 100644 index 0000000000..9ee563ba92 --- /dev/null +++ b/changelog.d/uk-under-two-usage-signal-bound.changed.md @@ -0,0 +1 @@ +The take-up signal gate holds the under-2 usage share (`max_free_entitlement_hours_used`, over the children of DfE age 0 or 1 in units that claim the working-parent hours) to ±0.10 of its ages' weighted contract rate, and every other flag to ±0.05 as before (`under_two_usage_maximum_share_deviation` in `uk/gates.json`). DfE's working-parent row at 9 to 11 months binds a thin cell of that draw's children: on the spine's own weights the draw meets its rates, but the calibrated weights move the share further from them than they move any other flag's, and the first national on policyengine-uk 2.151.0 failed release-cut certification on that share alone. The gate report records each flag's bound. The battery and release-cut gate digests are re-pinned; the spine, calibration-seam and dense local-gate digests do not move. diff --git a/docs/gate-battery-contract.md b/docs/gate-battery-contract.md index c1d8b8c62e..10662fa269 100644 --- a/docs/gate-battery-contract.md +++ b/docs/gate-battery-contract.md @@ -128,7 +128,7 @@ Canonical artifact keys: | `parity_evidence` | the UK national build | `export_surface`, `target_surface`, `target_fit` | | `input_mass_reference` | the UK national build, when the licensed sidecar is supplied | `input_mass_parity` (UK override) | | `reviewed_input_mass_exclusions` (optional override) | the UK national build | `input_mass_parity` (UK override) | -| `uk_area_support_summary`, `exclusions_evaluated_on` | the UK local rowwise build | `area_support` (UK binding; reviewed exclusions name the floors the area misses, never its figures, and stale entries fail; they are gate-only and defer none of the area's cells, microcosm#1301) | +| `uk_area_support_summary`, `exclusions_evaluated_on` | the UK local rowwise build | `area_support` (UK binding; reviewed exclusions state the area's figures beside the floors it misses, and stale entries fail; they are gate-only and defer none of the area's cells, microcosm#1301) | | `local_target_diagnostics`, `exclusions_evaluated_on` | the UK local rowwise build | `per_family_fit` (the diagnostics only); `target_fit` on `surface: local_candidate` (UK binding; the local cells stand on `local_target_fit_reviewed_exclusions.json`, keyed `family/area_code/metric`, which lifts the fence only and is evaluated on the build's review date, microcosm#1301) | | `cgt_projection` | the UK calibration seam: read from the installed engine's growth path and exempt amounts, or stated from the manifest pins when no engine is installed (the receipt's `projection_engine` names the source, and the release certifier refuses a seam part whose fence read the pins) | `cgt_projection_entrants` (UK binding; the count is a cumulative stock by year, the bound is the vendored HMRC thin-band taxpayer count as a plausibility ceiling, and the growth path and exempt amount are pinned in the manifest and drift-checked, microcosm#970) | diff --git a/docs/orrery-publication.md b/docs/orrery-publication.md index e073acd931..47db198b1c 100644 --- a/docs/orrery-publication.md +++ b/docs/orrery-publication.md @@ -2,9 +2,10 @@ UK full, dense, size and national builds export `graph.orrery.json` from the saved graph schema and recorded execution evidence. They preserve the explicit -public-safe file inventory in the attempt directory, attempt publication before -Hugging Face artifact staging, and register graph/evidence files and an -`orrery.publication.json` receipt snapshot in the artifact manifest. +allowlisted file inventory in the attempt directory, attempt publication before +Hugging Face artifact staging when `--publish-orrery` asks for it, and register +graph/evidence files and an `orrery.publication.json` receipt snapshot in the +artifact manifest. When execution was recorded, they also write the execution overlay that `graph.orrery.json` embeds as `graph.execution.json` and register it in the @@ -55,10 +56,28 @@ publication API. Producer tests do not contact either hosted service. No new Microcosm runtime variable or secret is required. Tests isolate ambient credentials and caches and use fake HTTP or explicit loopback services. -`--staging-local-only`, `--no-staging` and `--no-staged-dataset` export locally -without remote submission. `--publish-orrery` explicitly enables submission; -`--no-publish-orrery` disables it independently. A publication failure does not -replace the dataset's validation result or prevent HF artifact staging. +A build exports locally without remote submission unless `--publish-orrery` +enables it (María's ruling of 2026-10-26), whatever its staging: +`--no-publish-orrery` states the default, and `--publish-orrery` submits even +when dataset staging is local-only. A publication failure does not replace +the dataset's validation result or prevent HF artifact staging. + +Since the same ruling the build no longer withholds the figures of target rows +resting on fewer than ten source households, or the per-area support figures +in the gates' failure lines, so the summaries never carry them: + +- a calibration summary keeps each target row's target, tolerance and source, + but no row's estimates or errors, and the size summary keeps the losses but + not the largest change in one row; +- a gate summary keeps each gate's verdict and its count of failure lines, but + not the lines. + +The build's private diagnostics and gate reports keep all of them. Before it +preserves anything for publication, the export checks the summaries and stops, +with the `unpublishable_summary` error code, if one carries a row's estimates +or a failure line. With no `orrery.upload.json` inventory written, neither the +build nor the retry command below can submit them (Vahid's review of +microcosm#1396). Failed builds preserve recorded graph evidence before temporary-file cleanup. They publish it, with an `orrery.failure.json` marker, to `orrery-failure/` in diff --git a/docs/uk-dense-release-assembly-runbook-762.md b/docs/uk-dense-release-assembly-runbook-762.md index 5a4d989b1c..8eaf2185e6 100644 --- a/docs/uk-dense-release-assembly-runbook-762.md +++ b/docs/uk-dense-release-assembly-runbook-762.md @@ -120,6 +120,15 @@ at `/.graph-store` unless `--graph-store` says otherwise, and `--input-h5` must be a spine whose gate manifest matches the branch's gate declarations. +**Every row's figures ship (María's ruling of 2026-10-26).** The build no +longer withholds the model figures of rows resting on fewer than ten source +households, nor of the rows that would give them back by difference +(microcosm#1262, #1383). Every row is judged by the fit gates and carries its +figures in the diagnostics, the targets table and the gate reports, so a +release goes only to the licensed private repository. The graph's evidence +summaries carry them too, which is why a build publishes to the public Orrery +only on `--publish-orrery`. + ### Sized release (microcosm#1124) A release candidate may add `--dataset-households 150000` to ship the exact-k @@ -253,10 +262,11 @@ tool cannot template it checks in three ways, and only these three: comment cited as "issue comment ", a date far from today (`2045-12-31`) and any other number (`K=15`, `150,000 households`, a plan code such as `c9`, a bare year), before the build is read. -- The drafted entries then go through the release contract's disclosure walk, - and a finding refuses the draft, though on a release directory the walk only - warns. On text, the walk catches only an area's support worded with its - measured value, such as `rows 7 < 50`. +- The drafted entries then go through the contract's disclosure walk, and a + finding refuses the draft: the entries go into a public pull request, though + a release directory itself ships per-area support figures since María's + ruling of 2026-10-26. On text, the walk catches only an area's support + worded with its measured value, such as `rows 7 < 50`. None of these checks catches a figure written in words, so scan the outputs as described under "The sign-off PR" below. The degenerate register is never @@ -399,9 +409,7 @@ Verification fails unless all of these hold: local line's input-mass entries included), has not passed. It warns when build 2 did not reuse build 1's solve, when its per-row errors -differ, when the disclosure walk a release directory gets finds a per-area -support figure in the signed local report, and when the assembly deadline is -two days away or less. The entries +differ, and when the assembly deadline is two days away or less. The entries expire: retire or renew them before `expires_on`, because engine-free tests evaluate the committed registers at today's date. @@ -422,15 +430,10 @@ exclusions and their windows, the holdout (recorded as not requested, or, when `--rotated-holdout` asked for it, measured with five folds and a finite mean, and in agreement with the request), the Logbook row, the artifact digest. -It also runs the release's disclosure walk over the files assembly ships byte -for byte: the candidate manifest, the original diagnostics, the signed local -report and, when the run directory holds them, `score_vs_incumbent.json` and -`incumbent_surface_evaluation.json`. Add `--incumbent-manifest -/incumbent_local_surface_manifest.json` to walk the extraction -manifest you will attach too. Each file is read as the contract reads it, so -one carrying NaN, or nested too deep to walk, is reported as a file the walk -cannot rule out. A finding prints a `WARN` line naming the file and the paths, -never a value, and never fails the pre-flight. +`--incumbent-manifest /incumbent_local_surface_manifest.json` +checks that the extraction manifest you will attach exists. The pre-flight no +longer walks the shipped files for per-area support figures: a release ships +them since María's ruling of 2026-10-26 (microcosm#1301). ## Optional diagnostics (microcosm#1301) @@ -538,20 +541,11 @@ directory with `releases/microcosm-uk-2024-25-dense/`. Re-assembling requires removing the previous directory first. The JSON summary prints the publication command. -The validator's disclosure walk warns rather than refuses (microcosm#1301). A -shipped JSON document carrying an area's rows, ESS or distinct sources, or a -minimum, maximum or median of one, prints a `warning:` line naming the file and -the first paths to the figures, never their values, and the summary lists it -under `warnings`; so does a shipped JSON document the walk cannot read. Weigh -each warning before publishing. A figure in the signed `uk_local_gates.json` -cannot be edited out without failing its signature, nor one in -`source_calibration_diagnostics.json` without failing the candidate manifest's -hash of it; a figure in a file the assembler writes is fixed at its source and -the directory re-assembled. The pre-flight's `--candidate-dir` runs the same -walk over the files the assembler ships byte for byte (step 3), so a finding -shows right after each build. The walk reads key names and the shortfall -wording only: a figure under another name, in other prose or outside the -top-level JSON files is not found, so the manual scan stays. +A release directory ships per-area support figures (rows, Kish ESS and +distinct sources, and their minima) in the signed `uk_local_gates.json`, the +diagnostics and the candidate manifest: María's ruling of 2026-10-26 dropped +their withholding and the validator's disclosure walk with it (microcosm#1301). +The release goes only to the licensed private repository. The manifest's `reviewed_limitations` record what the release does not claim, and the contract checks them against the coverage: `engine_measurement` @@ -605,12 +599,12 @@ uv run python -m microcosm.data.publish_cli releases/microcosm-uk-2024-25-dense revision without a main-branch commit. The artifact is reachable by its tag and by the registry key `("uk", 2025, "dense")` only. -The disclosure walk's warnings reach the publisher's JSON output as well as -stderr: `--preflight-only` adds them to its verdict under `contract_warnings`, -and publication lists them the same way beside the pointer it prints. Neither -refuses on them. The immutable tag's message records that the release was -published past them and how many there were, never what they say, since they -name paths in the shipped files. +A contract warning reaches the publisher's JSON output as well as stderr: +`--preflight-only` adds it to its verdict under `contract_warnings`, and +publication lists it the same way beside the pointer it prints. Neither +refuses on one. The immutable tag's message records that the release was +published past them and how many there were, never what they say. No dense +release raises any since the disclosure walk was dropped. ## Promotion is a separate change diff --git a/docs/uk-full-build-graph.md b/docs/uk-full-build-graph.md index 182c1d336b..b3753f5d30 100644 --- a/docs/uk-full-build-graph.md +++ b/docs/uk-full-build-graph.md @@ -110,7 +110,7 @@ The shared store defaults to `/.graph-store`. `--graph-store` can reuse ano Each attempt also keeps its checkpoint manifests and small stage, gate and provenance reports under `/uk-full-attempts/`. Its `request.json` carries the request bindings and the attempt's Logbook build id and staging run id (`attempt`). The rowwise manifest's `execution` block records the graph store, the attempt directory, how many graph nodes the attempt reused from the store rather than computed (the first run to reach a node decides), and the earlier attempts on the same store that ran the same request (their directories and ids, the twenty most recent, beside counts of every earlier attempt on the store and of the matching ones), so a resumed build names the attempts whose work it reused; the same counts reach the staging run as a `graph_execution` stage event. The block sits outside the run parameters, so it does not change the candidate identity. A failed run's `failure.json` links to this evidence, including a persisted spine gate verdict before downstream admission stops execution. A previously completed output bundle remains intact. -The output bundle is named from the role's posture and the FRS release vintage: `microcosm_uk_2024_25_local.h5`, its local gate report `microcosm_uk_2024_25_local.local_gates.json`, and the `.diagnostics.json`, `.targets.csv`, `.area_support.csv`, `.holdout.json` and `.target_selection.json` siblings on the same stem, beside `graph.json`, `operations.json`, the stored source/stage/gate evidence and the graph manifests. `candidate.json` is the immutable graph package inventory: it binds the dataset, its evidence, the target selector and the independent K/k request. Comparison inputs refer to this candidate identity. Adding comparison evidence does not rewrite the candidate package. `rowwise_candidate_manifest.json` is projected from the stored artifacts in the schema-4 shape the rowwise tool wrote (`graph_terminal.rowwise_candidate_manifest_from_graph`), so the dense release pre-flight and assembler read a graph build as they read a rowwise-tool build; it records the release role, the release verdict, `staging_delivery` and `staged_dataset`. Per-area support figures (rows, ESS and distinct sources) stay in `.area_support.csv` (microcosm#1301): the manifest's `support` block counts the areas checked and below the floor by level, the weakest-area and support-limited rows carry `support_below_floor` in their place, and the support gate names the floors an area misses, never its figures. The dense release contract warns, without refusing, on a shipped JSON document that carries one. +The output bundle is named from the role's posture and the FRS release vintage: `microcosm_uk_2024_25_local.h5`, its local gate report `microcosm_uk_2024_25_local.local_gates.json`, and the `.diagnostics.json`, `.targets.csv`, `.area_support.csv`, `.holdout.json` and `.target_selection.json` siblings on the same stem, beside `graph.json`, `operations.json`, the stored source/stage/gate evidence and the graph manifests. `candidate.json` is the immutable graph package inventory: it binds the dataset, its evidence, the target selector and the independent K/k request. Comparison inputs refer to this candidate identity. Adding comparison evidence does not rewrite the candidate package. `rowwise_candidate_manifest.json` is projected from the stored artifacts in the schema-4 shape the rowwise tool wrote (`graph_terminal.rowwise_candidate_manifest_from_graph`), so the dense release pre-flight and assembler read a graph build as they read a rowwise-tool build; it records the release role, the release verdict, `staging_delivery` and `staged_dataset`. Every area's support figures (rows, ESS and distinct sources) are in `.area_support.csv`, and since María's ruling of 2026-10-26 dropped their withholding (microcosm#1301) the shipped files carry them too: the manifest's `support` block counts the areas checked and below the floor by level and states the minima, the weakest-area and support-limited rows carry them beside `support_below_floor`, and the support gate states an area's figures beside the floors it misses. The graph evaluates every declared UK gate once; `uk.full.gates.calibrated.gate_report.json` is that full terminal document, the one the package inventory binds (`outputs.full_gate_report`). The local gate report is the seven-gate local battery the dense release contract verifies: the driver projects the seven `UK_LOCAL_GATE_SCOPE` outcomes from the full document (nothing is re-evaluated; the projection checks the declarations are the same), replays them through the gate battery without raising (the graph's own enforcement still sets the exit status), and writes the report before any refusal, so a blocked candidate leaves it too. Its `release_id` is the Logbook attempt's build id. It is signed when the attempt is bound and `MICROCOSM_UK_TERMINAL_GATE_SIGNING_KEY` holds a 32-byte key; otherwise it is written unsigned, with `signing_error`, and is never shippable. A build whose `--target-geographies` select no local targets drops the local fit claim: it writes no local gate report (`outputs.local_gate_report` is null and `local_gate_report_absence` says why) rather than recording the excluded local gates as not applicable. The Logbook receipts of the seven local gates resolve in the local report (`#/gates/`); the other gates' receipts resolve in the full document (`#/report/outcomes/`). diff --git a/packages/microcosm-build/src/microcosm/build/gates.py b/packages/microcosm-build/src/microcosm/build/gates.py index 95da4f0244..47b41e6cb0 100644 --- a/packages/microcosm-build/src/microcosm/build/gates.py +++ b/packages/microcosm-build/src/microcosm/build/gates.py @@ -2540,20 +2540,24 @@ def area_support_shortfalls( ) -> list[str]: """The support floors one area misses, worded as :func:`area_support_gate` reports them. - Each shortfall names the floor, never the area's measured value: the - gate's failures and its reviewed-exclusion details ship in a signed - release file, and an area's rows, ESS and distinct sources are per-area - support figures a release withholds (microcosm#1301). The figures stay - in the build's area-support table. + Each shortfall states the area's measured value beside the floor: the + release ships per-area support figures since María's ruling of + 2026-10-26, which dropped their withholding (microcosm#1301). """ shortfalls = [] if rows < minimum_rows: - shortfalls.append(f"rows < {minimum_rows}") + shortfalls.append(f"rows {int(rows)} < {minimum_rows}") if effective_sample_size < minimum_effective_sample_size: - shortfalls.append(f"ESS < {float(minimum_effective_sample_size):.6g}") + shortfalls.append( + "ESS " + f"{float(effective_sample_size):.6g} < " + f"{float(minimum_effective_sample_size):.6g}" + ) if sources < minimum_distinct_sources: - shortfalls.append(f"distinct sources < {minimum_distinct_sources}") + shortfalls.append( + f"distinct sources {int(sources)} < {minimum_distinct_sources}" + ) return shortfalls @@ -2605,11 +2609,10 @@ def area_support_gate( declared ``area_roster`` is load-bearing: a missing weak area cannot make the gate look better by disappearing from the evidence table. - The details and failures carry no per-area support figures - (microcosm#1301): a failure and a reviewed exclusion name the floors the - area misses, and each geography level reports how many areas were - checked and how many sit below a floor. A level's minima would be one - area's figures, so they are not reported either. + A failure and a reviewed exclusion state the area's measured support + beside the floors it misses, and each geography level reports how many + areas were checked and sit below a floor, and its minima (María's ruling + of 2026-10-26 dropped the withholding of microcosm#1301). """ levels = tuple(str(level) for level in geography_levels) @@ -2717,7 +2720,13 @@ def area_support_gate( below_floor[row.geography_level] += 1 record = exclusions.get(key) if record is not None and shortfalls: - used_exclusions[key] = {"shortfalls": shortfalls, "record": dict(record)} + used_exclusions[key] = { + "shortfalls": shortfalls, + "rows": int(row.nonzero_households), + "ess": float(row.effective_sample_size), + "sources": int(row.nonzero_source_households), + "record": dict(record), + } elif record is not None: stale_exclusions.append(key) failures.append( @@ -2734,13 +2743,20 @@ def area_support_gate( for key in unknown_exclusions ) - by_level = { - level: { - "areas_checked": int((rows["geography_level"] == level).sum()), + by_level: dict[str, dict[str, object]] = {} + for level in levels: + level_rows = rows.loc[rows["geography_level"] == level] + by_level[level] = { + "areas_checked": int(len(level_rows)), "areas_below_floor": below_floor[level], + "minimum_rows": int(level_rows["nonzero_households"].min()), + "minimum_effective_sample_size": float( + level_rows["effective_sample_size"].min() + ), + "minimum_distinct_sources": int( + level_rows["nonzero_source_households"].min() + ), } - for level in levels - } return GateResult( name="area_support", passed=not failures, diff --git a/packages/microcosm-build/src/microcosm/build/uk/gates.json b/packages/microcosm-build/src/microcosm/build/uk/gates.json index 9d2252a605..9090c9b70f 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/gates.json +++ b/packages/microcosm-build/src/microcosm/build/uk/gates.json @@ -1317,9 +1317,10 @@ "phase": "terminal", "criticality": "release_blocking", "parameters": { - "maximum_share_deviation": 0.05 + "maximum_share_deviation": 0.05, + "under_two_usage_maximum_share_deviation": 0.1 }, - "notes": "Every contract-driven stochastic flag must be non-constant and have a weighted share within +/-0.05 of its contract target. would_claim_pc is measured by uk_stage_pension_credit_take_up instead (microcosm#1069 R9), would_claim_child_benefit and child_benefit_opts_out by uk_stage_child_benefit_take_up (microcosm#1063), and would_claim_uc by uk_stage_uc_take_up (microcosm#1334): frs_take_up and spi_benefit_coherence draw it at the contract rate, and uc_take_up redraws every entitled unit by award band and family type. would_claim_universal_childcare is nested under would_claim_extended_childcare, so its target is the nested marginal r_e + (1 - r_e) * r_u of the contract's conditional universal rate, and the gate fails on any benefit unit that claims the extended hours without the universal ones. max_free_entitlement_hours_used carries the under-2 usage draw: its share of persons with hours is measured over the children of DfE age 0 or 1 in units that claim the extended hours, against the weighted mean of their ages' contract rates (extended_childcare_age_0_usage, extended_childcare_age_1_usage)." + "notes": "Every contract-driven stochastic flag must be non-constant and have a weighted share within +/-0.05 of its contract target. would_claim_pc is measured by uk_stage_pension_credit_take_up instead (microcosm#1069 R9), would_claim_child_benefit and child_benefit_opts_out by uk_stage_child_benefit_take_up (microcosm#1063), and would_claim_uc by uk_stage_uc_take_up (microcosm#1334): frs_take_up and spi_benefit_coherence draw it at the contract rate, and uc_take_up redraws every entitled unit by award band and family type. would_claim_universal_childcare is nested under would_claim_extended_childcare, so its target is the nested marginal r_e + (1 - r_e) * r_u of the contract's conditional universal rate, and the gate fails on any benefit unit that claims the extended hours without the universal ones. max_free_entitlement_hours_used carries the under-2 usage draw: its share of persons with hours is measured over the children of DfE age 0 or 1 in units that claim the extended hours, against the weighted mean of their ages' contract rates (extended_childcare_age_0_usage, extended_childcare_age_1_usage), within +/-0.10: the DfE working-parent row at 9 to 11 months binds a thin cell of that draw's children, so the calibrated weights move the share from its rates where the spine's own weights hold it to them (ruling of 2026-10-25); tools/report_uk_childcare_realised_take_up.py records the share a file realises." }, { "id": "uk_brma_enum_domain", diff --git a/packages/microcosm-build/src/microcosm/build/uk/local_target_fit_reviewed_exclusions.json b/packages/microcosm-build/src/microcosm/build/uk/local_target_fit_reviewed_exclusions.json index bc222da68d..ce64c40f6b 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/local_target_fit_reviewed_exclusions.json +++ b/packages/microcosm-build/src/microcosm/build/uk/local_target_fit_reviewed_exclusions.json @@ -22,26 +22,6 @@ "local" ] }, - "age_structure/E14001081/age/20_30": { - "reason": "Gate-only sign-off of the local cell age_structure/E14001081/age/20_30 on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261018T161007Z-35fb4c89 (full gate report sha256 46d42e6abf5fa8eaf08e3301a982703f113838c41cb7869340a3a41bafc6407f) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", - "approved_by": "juaristi22", - "adjudication": "Gate-only sign-off of the local release's measured build, drafted from its run (microcosm#1301, microcosm#1310).", - "approved_on": "2026-10-19", - "expires_on": "2026-11-16", - "release_lines": [ - "local" - ] - }, - "age_structure/E14001086/age/20_30": { - "reason": "Gate-only sign-off of the local cell age_structure/E14001086/age/20_30 on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261018T161007Z-35fb4c89 (full gate report sha256 46d42e6abf5fa8eaf08e3301a982703f113838c41cb7869340a3a41bafc6407f) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", - "approved_by": "juaristi22", - "adjudication": "Gate-only sign-off of the local release's measured build, drafted from its run (microcosm#1301, microcosm#1310).", - "approved_on": "2026-10-19", - "expires_on": "2026-11-16", - "release_lines": [ - "local" - ] - }, "age_structure/E14001096/age/20_30": { "reason": "Gate-only sign-off of the local cell age_structure/E14001096/age/20_30 on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261018T161007Z-35fb4c89 (full gate report sha256 46d42e6abf5fa8eaf08e3301a982703f113838c41cb7869340a3a41bafc6407f) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", "approved_by": "juaristi22", @@ -52,16 +32,6 @@ "local" ] }, - "age_structure/E14001120/age/20_30": { - "reason": "Gate-only sign-off of the local cell age_structure/E14001120/age/20_30 on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261018T161007Z-35fb4c89 (full gate report sha256 46d42e6abf5fa8eaf08e3301a982703f113838c41cb7869340a3a41bafc6407f) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", - "approved_by": "juaristi22", - "adjudication": "Gate-only sign-off of the local release's measured build, drafted from its run (microcosm#1301, microcosm#1310).", - "approved_on": "2026-10-19", - "expires_on": "2026-11-16", - "release_lines": [ - "local" - ] - }, "age_structure/E14001131/age/20_30": { "reason": "Gate-only sign-off of the local cell age_structure/E14001131/age/20_30 on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261018T161007Z-35fb4c89 (full gate report sha256 46d42e6abf5fa8eaf08e3301a982703f113838c41cb7869340a3a41bafc6407f) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", "approved_by": "juaristi22", @@ -112,16 +82,6 @@ "local" ] }, - "age_structure/E14001352/age/20_30": { - "reason": "Gate-only sign-off of the local cell age_structure/E14001352/age/20_30 on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261018T161007Z-35fb4c89 (full gate report sha256 46d42e6abf5fa8eaf08e3301a982703f113838c41cb7869340a3a41bafc6407f) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", - "approved_by": "juaristi22", - "adjudication": "Gate-only sign-off of the local release's measured build, drafted from its run (microcosm#1301, microcosm#1310).", - "approved_on": "2026-10-19", - "expires_on": "2026-11-16", - "release_lines": [ - "local" - ] - }, "age_structure/E14001353/age/20_30": { "reason": "Gate-only sign-off of the local cell age_structure/E14001353/age/20_30 on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261018T161007Z-35fb4c89 (full gate report sha256 46d42e6abf5fa8eaf08e3301a982703f113838c41cb7869340a3a41bafc6407f) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", "approved_by": "juaristi22", @@ -152,16 +112,6 @@ "local" ] }, - "age_structure/S14000085/age/20_30": { - "reason": "Gate-only sign-off of the local cell age_structure/S14000085/age/20_30 on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261018T161007Z-35fb4c89 (full gate report sha256 46d42e6abf5fa8eaf08e3301a982703f113838c41cb7869340a3a41bafc6407f) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", - "approved_by": "juaristi22", - "adjudication": "Gate-only sign-off of the local release's measured build, drafted from its run (microcosm#1301, microcosm#1310).", - "approved_on": "2026-10-19", - "expires_on": "2026-11-16", - "release_lines": [ - "local" - ] - }, "age_structure/W07000091/age/20_30": { "reason": "Gate-only sign-off of the local cell age_structure/W07000091/age/20_30 on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261018T161007Z-35fb4c89 (full gate report sha256 46d42e6abf5fa8eaf08e3301a982703f113838c41cb7869340a3a41bafc6407f) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", "approved_by": "juaristi22", @@ -182,16 +132,6 @@ "local" ] }, - "council_tax/E09000033/council_tax/band_g": { - "reason": "Gate-only sign-off of the local cell council_tax/E09000033/council_tax/band_g on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261018T161007Z-35fb4c89 (full gate report sha256 46d42e6abf5fa8eaf08e3301a982703f113838c41cb7869340a3a41bafc6407f) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", - "approved_by": "juaristi22", - "adjudication": "Gate-only sign-off of the local release's measured build, drafted from its run (microcosm#1301, microcosm#1310).", - "approved_on": "2026-10-19", - "expires_on": "2026-11-16", - "release_lines": [ - "local" - ] - }, "council_tax/S12000013/council_tax/band_a": { "reason": "Gate-only sign-off of the local cell council_tax/S12000013/council_tax/band_a on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261018T161007Z-35fb4c89 (full gate report sha256 46d42e6abf5fa8eaf08e3301a982703f113838c41cb7869340a3a41bafc6407f) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", "approved_by": "juaristi22", @@ -232,82 +172,62 @@ "local" ] }, - "domestic_energy/S12000027/energy/electricity_kwh": { - "reason": "Gate-only sign-off of the local cell domestic_energy/S12000027/energy/electricity_kwh on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261018T161007Z-35fb4c89 (full gate report sha256 46d42e6abf5fa8eaf08e3301a982703f113838c41cb7869340a3a41bafc6407f) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", + "age_structure/E14001301/age/20_30": { + "reason": "Gate-only sign-off of the local cell age_structure/E14001301/age/20_30 on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261026T091056Z-824870f6 (full gate report sha256 abf245413ca0809f9f261e650c352ef310d11e19960b8e4c5ade3bc57dddf411) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", "approved_by": "juaristi22", - "adjudication": "Gate-only sign-off of the local release's measured build, drafted from its run (microcosm#1301, microcosm#1310).", - "approved_on": "2026-10-19", - "expires_on": "2026-11-16", + "adjudication": "Gate-only sign-off of the local release's measured build, drafted from its run (microcosm#1301, microcosm#1396).", + "approved_on": "2026-10-26", + "expires_on": "2026-11-23", "release_lines": [ "local" ] }, - "hmrc_income_by_area/E14001538/hmrc/self_employment_income/count": { - "reason": "Gate-only sign-off of the local cell hmrc_income_by_area/E14001538/hmrc/self_employment_income/count on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261018T161007Z-35fb4c89 (full gate report sha256 46d42e6abf5fa8eaf08e3301a982703f113838c41cb7869340a3a41bafc6407f) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", + "council_tax/E09000020/council_tax/band_b": { + "reason": "Gate-only sign-off of the local cell council_tax/E09000020/council_tax/band_b on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261026T091056Z-824870f6 (full gate report sha256 abf245413ca0809f9f261e650c352ef310d11e19960b8e4c5ade3bc57dddf411) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", "approved_by": "juaristi22", - "adjudication": "Gate-only sign-off of the local release's measured build, drafted from its run (microcosm#1301, microcosm#1310).", - "approved_on": "2026-10-19", - "expires_on": "2026-11-16", + "adjudication": "Gate-only sign-off of the local release's measured build, drafted from its run (microcosm#1301, microcosm#1396).", + "approved_on": "2026-10-26", + "expires_on": "2026-11-23", "release_lines": [ "local" ] }, - "private_rent/E06000043/rent/private_rent": { - "reason": "Gate-only sign-off of the local cell private_rent/E06000043/rent/private_rent on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261018T161007Z-35fb4c89 (full gate report sha256 46d42e6abf5fa8eaf08e3301a982703f113838c41cb7869340a3a41bafc6407f) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", + "council_tax/E09000033/council_tax/band_b": { + "reason": "Gate-only sign-off of the local cell council_tax/E09000033/council_tax/band_b on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261026T091056Z-824870f6 (full gate report sha256 abf245413ca0809f9f261e650c352ef310d11e19960b8e4c5ade3bc57dddf411) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", "approved_by": "juaristi22", - "adjudication": "Gate-only sign-off of the local release's measured build, drafted from its run (microcosm#1301, microcosm#1310).", - "approved_on": "2026-10-19", - "expires_on": "2026-11-16", + "adjudication": "Gate-only sign-off of the local release's measured build, drafted from its run (microcosm#1301, microcosm#1396).", + "approved_on": "2026-10-26", + "expires_on": "2026-11-23", "release_lines": [ "local" ] }, - "private_rent/E08000003/rent/private_rent": { - "reason": "Gate-only sign-off of the local cell private_rent/E08000003/rent/private_rent on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261018T161007Z-35fb4c89 (full gate report sha256 46d42e6abf5fa8eaf08e3301a982703f113838c41cb7869340a3a41bafc6407f) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", + "domestic_energy/W06000008/energy/gas_connected_households": { + "reason": "Gate-only sign-off of the local cell domestic_energy/W06000008/energy/gas_connected_households on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261026T091056Z-824870f6 (full gate report sha256 abf245413ca0809f9f261e650c352ef310d11e19960b8e4c5ade3bc57dddf411) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", "approved_by": "juaristi22", - "adjudication": "Gate-only sign-off of the local release's measured build, drafted from its run (microcosm#1301, microcosm#1310).", - "approved_on": "2026-10-19", - "expires_on": "2026-11-16", + "adjudication": "Gate-only sign-off of the local release's measured build, drafted from its run (microcosm#1301, microcosm#1396).", + "approved_on": "2026-10-26", + "expires_on": "2026-11-23", "release_lines": [ "local" ] }, - "private_rent/E09000033/rent/private_rent": { - "reason": "Gate-only sign-off of the local cell private_rent/E09000033/rent/private_rent on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261018T161007Z-35fb4c89 (full gate report sha256 46d42e6abf5fa8eaf08e3301a982703f113838c41cb7869340a3a41bafc6407f) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", + "tenure/E09000020/tenure/owned_outright": { + "reason": "Gate-only sign-off of the local cell tenure/E09000020/tenure/owned_outright on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261026T091056Z-824870f6 (full gate report sha256 abf245413ca0809f9f261e650c352ef310d11e19960b8e4c5ade3bc57dddf411) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", "approved_by": "juaristi22", - "adjudication": "Gate-only sign-off of the local release's measured build, drafted from its run (microcosm#1301, microcosm#1310).", - "approved_on": "2026-10-19", - "expires_on": "2026-11-16", - "release_lines": [ - "local" - ] - }, - "tenure/E09000012/tenure/private_rent": { - "reason": "Gate-only sign-off of the local cell tenure/E09000012/tenure/private_rent on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261018T161007Z-35fb4c89 (full gate report sha256 46d42e6abf5fa8eaf08e3301a982703f113838c41cb7869340a3a41bafc6407f) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", - "approved_by": "juaristi22", - "adjudication": "Gate-only sign-off of the local release's measured build, drafted from its run (microcosm#1301, microcosm#1310).", - "approved_on": "2026-10-19", - "expires_on": "2026-11-16", - "release_lines": [ - "local" - ] - }, - "tenure/E09000019/tenure/private_rent": { - "reason": "Gate-only sign-off of the local cell tenure/E09000019/tenure/private_rent on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261018T161007Z-35fb4c89 (full gate report sha256 46d42e6abf5fa8eaf08e3301a982703f113838c41cb7869340a3a41bafc6407f) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", - "approved_by": "juaristi22", - "adjudication": "Gate-only sign-off of the local release's measured build, drafted from its run (microcosm#1301, microcosm#1310).", - "approved_on": "2026-10-19", - "expires_on": "2026-11-16", + "adjudication": "Gate-only sign-off of the local release's measured build, drafted from its run (microcosm#1301, microcosm#1396).", + "approved_on": "2026-10-26", + "expires_on": "2026-11-23", "release_lines": [ "local" ] }, - "tenure/E09000019/tenure/social_rent": { - "reason": "Gate-only sign-off of the local cell tenure/E09000019/tenure/social_rent on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261018T161007Z-35fb4c89 (full gate report sha256 46d42e6abf5fa8eaf08e3301a982703f113838c41cb7869340a3a41bafc6407f) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", + "tenure/S12000029/tenure/private_rent": { + "reason": "Gate-only sign-off of the local cell tenure/S12000029/tenure/private_rent on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261026T091056Z-824870f6 (full gate report sha256 abf245413ca0809f9f261e650c352ef310d11e19960b8e4c5ade3bc57dddf411) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", "approved_by": "juaristi22", - "adjudication": "Gate-only sign-off of the local release's measured build, drafted from its run (microcosm#1301, microcosm#1310).", - "approved_on": "2026-10-19", - "expires_on": "2026-11-16", + "adjudication": "Gate-only sign-off of the local release's measured build, drafted from its run (microcosm#1301, microcosm#1396).", + "approved_on": "2026-10-26", + "expires_on": "2026-11-23", "release_lines": [ "local" ] diff --git a/packages/microcosm-build/src/microcosm/build/uk/take_up_contract.json b/packages/microcosm-build/src/microcosm/build/uk/take_up_contract.json index 45c85c89c4..f7fcad63ab 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/take_up_contract.json +++ b/packages/microcosm-build/src/microcosm/build/uk/take_up_contract.json @@ -168,7 +168,7 @@ "entity": "benunit", "values": { "2015-01-01": 0.586, - "2024-04-06": 0.9697 + "2024-04-06": 0.9134 }, "source": { "source": "FRS empirical fit and HMRC Tax-Free Childcare statistics, June 2025 release", @@ -178,17 +178,17 @@ "status": "fitted_offline" }, "fitting_receipt": { - "source": "tools/fit_uk_childcare_takeup.py (microcosm#1338 round 3, licensed lane)", + "source": "tools/fit_uk_childcare_takeup.py (refit on policyengine-uk 2.151.0 after microcosm#1383, licensed lane)", "tool_version": 7, - "receipt_sha256": "7a9e44ff6d9da027199edb57ef529bbc82807dbc321d9ded00967a63afc573c6", + "receipt_sha256": "f41dc35911db339606b7a825d7a0d5d9d7b89bdbfb114a1cf5698e82f23a3881", "seed": 0, - "engine_version": "2.147.2", + "engine_version": "2.151.0", "model_period": 2025, "vintage_overrides": {}, - "input_h5_sha256": "f8e02d9da1ad15ca03c77878c14d047bee738c0abb128ba3fc3836b997ac9412", - "input_spine": "local unsigned spine built at 6aea1ec00 (uk-childcare-100k-fixes-v2 on main 8b0224e06; policyengine-uk 2.147.2, feed abf0921), sha256 f8e02d9da1ad15ca03c77878c14d047bee738c0abb128ba3fc3836b997ac9412; the fit overrides the take-up columns and reads only the stored ages and months, so the later commits leave it valid", + "input_h5_sha256": "bd8b4095565d5c1e6b8b88d3384a7a138348730585e40bd0a44b9e42990fcbd0", + "input_spine": "release-candidate spine built at fe1e2ad2c (main after microcosm#1383; policyengine-uk 2.151.0, feed abf0921), sha256 bd8b4095565d5c1e6b8b88d3384a7a138348730585e40bd0a44b9e42990fcbd0; the fit overrides the take-up columns and reads only the stored ages and months, so the later commits leave it valid", "ledger_facts_sha256": "2b64fecfe746164203dac1726aae6ffdb3e5d8e478bd3d64d118ac76cb00780b", - "stochastic_contract_sha256_at_fit": "1a9feb2bc9741b12c57d95f3c9c4364cad4cb43472782bb5be3bd19b410b44c5", + "stochastic_contract_sha256_at_fit": "dbbd3767cb35c6eabc35a80f384918c925cc27fac0c13f284b1ff3d769690272", "expectation_basis": "dfe_spring_term", "estimand": "The rate at which the spine reproduces HMRC's two Tax-Free Childcare rows (children with used accounts and the government top-up) given the other childcare rates: a fit across all users that trades the two rows against each other, not a take-up estimate for families newly eligible above £100,000, which a costing that removes the limit assumes equal to it.", "params_at_bound": [ @@ -197,7 +197,7 @@ ], "optimizer": { "eps": 1e-06, - "loss": 0.01538992050511465, + "loss": 0.013582517727076585, "maxiter": 50, "method": "L-BFGS-B", "success": true @@ -205,58 +205,58 @@ "achieved": { "dfe.funded_childcare.early_learning_2_year_olds": { "target": 95031.0, - "value": 95031.139, + "value": 95030.952, "ratio": 1.0 }, "dfe.funded_childcare.universal_only_children": { "target": 396965.0, - "value": 417767.817, - "ratio": 1.0524 + "value": 415750.362, + "ratio": 1.0473 }, "dfe.funded_childcare.working_parent_children_2_to_4": { "target": 621482.0, - "value": 620601.293, - "ratio": 0.9986 + "value": 618818.748, + "ratio": 0.9957 }, "dfe.funded_childcare.working_parent_children_9_to_11_months": { "target": 29155.0, - "value": 29154.994, + "value": 29154.976, "ratio": 1.0 }, "dfe.funded_childcare.working_parent_children_age_1": { "target": 195104.0, - "value": 183986.326, - "ratio": 0.943 + "value": 185825.116, + "ratio": 0.9524 }, "hmrc.tfc.children_with_used_accounts": { "target": 1151515.0, - "value": 1224841.813, - "ratio": 1.0637 + "value": 1223636.066, + "ratio": 1.0626 }, "hmrc.tfc.government_top_up": { "target": 599800000.0, - "value": 555971050.246, - "ratio": 0.9269 + "value": 556797174.046, + "ratio": 0.9283 } }, "diagnostic_rows": { "dfe.funded_childcare.universal_nursery_children_age_3": { "target": 565954.0, - "value": 571139.593, - "ratio": 1.0092 + "value": 568044.122, + "ratio": 1.0037 }, "dfe.funded_childcare.working_parent_children_age_2": { "target": 242453.0, - "value": 264624.601, - "ratio": 1.0914 + "value": 265018.154, + "ratio": 1.0931 }, "dfe.funded_childcare.working_parent_children_age_3": { "target": 278640.0, - "value": 260082.533, - "ratio": 0.9334 + "value": 257405.548, + "ratio": 0.9238 } }, - "status": "fitted at model year 2025 with the expectation basis of tool version 7: the DfE rows measured at the spring term by the age on 31 December (dfe_spring_term.py, policyengine-uk 2.147.2's date-of-birth school start and working-parent term start), universal take-up nested under working-parent take-up, targeted and universal hours allocated from the gross working-parent hours, and each under-2 usage share scaling the claiming families' children of its DfE age (the age on 31 December, as DfE counts them). At a bound: childcare_age_1_usage, universal_childcare." + "status": "fitted at model year 2025 with the expectation basis of tool version 7: the DfE rows measured at the spring term by the age on 31 December (dfe_spring_term.py, policyengine-uk 2.151.0's date-of-birth school start and working-parent term start), universal take-up nested under working-parent take-up, targeted and universal hours allocated from the gross working-parent hours, and each under-2 usage share scaling the claiming families' children of its DfE age (the age on 31 December, as DfE counts them). At a bound: childcare_age_1_usage, universal_childcare." } }, { @@ -265,7 +265,7 @@ "entity": "benunit", "values": { "2015-01-01": 0.812, - "2024-04-06": 0.8262 + "2024-04-06": 0.8217 }, "source": { "source": "FRS empirical fit", @@ -274,17 +274,17 @@ "status": "fitted_offline" }, "fitting_receipt": { - "source": "tools/fit_uk_childcare_takeup.py (microcosm#1338 round 3, licensed lane)", + "source": "tools/fit_uk_childcare_takeup.py (refit on policyengine-uk 2.151.0 after microcosm#1383, licensed lane)", "tool_version": 7, - "receipt_sha256": "7a9e44ff6d9da027199edb57ef529bbc82807dbc321d9ded00967a63afc573c6", + "receipt_sha256": "f41dc35911db339606b7a825d7a0d5d9d7b89bdbfb114a1cf5698e82f23a3881", "seed": 0, - "engine_version": "2.147.2", + "engine_version": "2.151.0", "model_period": 2025, "vintage_overrides": {}, - "input_h5_sha256": "f8e02d9da1ad15ca03c77878c14d047bee738c0abb128ba3fc3836b997ac9412", - "input_spine": "local unsigned spine built at 6aea1ec00 (uk-childcare-100k-fixes-v2 on main 8b0224e06; policyengine-uk 2.147.2, feed abf0921), sha256 f8e02d9da1ad15ca03c77878c14d047bee738c0abb128ba3fc3836b997ac9412; the fit overrides the take-up columns and reads only the stored ages and months, so the later commits leave it valid", + "input_h5_sha256": "bd8b4095565d5c1e6b8b88d3384a7a138348730585e40bd0a44b9e42990fcbd0", + "input_spine": "release-candidate spine built at fe1e2ad2c (main after microcosm#1383; policyengine-uk 2.151.0, feed abf0921), sha256 bd8b4095565d5c1e6b8b88d3384a7a138348730585e40bd0a44b9e42990fcbd0; the fit overrides the take-up columns and reads only the stored ages and months, so the later commits leave it valid", "ledger_facts_sha256": "2b64fecfe746164203dac1726aae6ffdb3e5d8e478bd3d64d118ac76cb00780b", - "stochastic_contract_sha256_at_fit": "1a9feb2bc9741b12c57d95f3c9c4364cad4cb43472782bb5be3bd19b410b44c5", + "stochastic_contract_sha256_at_fit": "dbbd3767cb35c6eabc35a80f384918c925cc27fac0c13f284b1ff3d769690272", "expectation_basis": "dfe_spring_term", "estimand": "The share of benefit units that claim working-parent hours, fitted to DfE's working parent registrations aged 2 to 4 at the spring term.", "params_at_bound": [ @@ -293,7 +293,7 @@ ], "optimizer": { "eps": 1e-06, - "loss": 0.01538992050511465, + "loss": 0.013582517727076585, "maxiter": 50, "method": "L-BFGS-B", "success": true @@ -301,58 +301,58 @@ "achieved": { "dfe.funded_childcare.early_learning_2_year_olds": { "target": 95031.0, - "value": 95031.139, + "value": 95030.952, "ratio": 1.0 }, "dfe.funded_childcare.universal_only_children": { "target": 396965.0, - "value": 417767.817, - "ratio": 1.0524 + "value": 415750.362, + "ratio": 1.0473 }, "dfe.funded_childcare.working_parent_children_2_to_4": { "target": 621482.0, - "value": 620601.293, - "ratio": 0.9986 + "value": 618818.748, + "ratio": 0.9957 }, "dfe.funded_childcare.working_parent_children_9_to_11_months": { "target": 29155.0, - "value": 29154.994, + "value": 29154.976, "ratio": 1.0 }, "dfe.funded_childcare.working_parent_children_age_1": { "target": 195104.0, - "value": 183986.326, - "ratio": 0.943 + "value": 185825.116, + "ratio": 0.9524 }, "hmrc.tfc.children_with_used_accounts": { "target": 1151515.0, - "value": 1224841.813, - "ratio": 1.0637 + "value": 1223636.066, + "ratio": 1.0626 }, "hmrc.tfc.government_top_up": { "target": 599800000.0, - "value": 555971050.246, - "ratio": 0.9269 + "value": 556797174.046, + "ratio": 0.9283 } }, "diagnostic_rows": { "dfe.funded_childcare.universal_nursery_children_age_3": { "target": 565954.0, - "value": 571139.593, - "ratio": 1.0092 + "value": 568044.122, + "ratio": 1.0037 }, "dfe.funded_childcare.working_parent_children_age_2": { "target": 242453.0, - "value": 264624.601, - "ratio": 1.0914 + "value": 265018.154, + "ratio": 1.0931 }, "dfe.funded_childcare.working_parent_children_age_3": { "target": 278640.0, - "value": 260082.533, - "ratio": 0.9334 + "value": 257405.548, + "ratio": 0.9238 } }, - "status": "fitted at model year 2025 with the expectation basis of tool version 7: the DfE rows measured at the spring term by the age on 31 December (dfe_spring_term.py, policyengine-uk 2.147.2's date-of-birth school start and working-parent term start), universal take-up nested under working-parent take-up, targeted and universal hours allocated from the gross working-parent hours, and each under-2 usage share scaling the claiming families' children of its DfE age (the age on 31 December, as DfE counts them). At a bound: childcare_age_1_usage, universal_childcare." + "status": "fitted at model year 2025 with the expectation basis of tool version 7: the DfE rows measured at the spring term by the age on 31 December (dfe_spring_term.py, policyengine-uk 2.151.0's date-of-birth school start and working-parent term start), universal take-up nested under working-parent take-up, targeted and universal hours allocated from the gross working-parent hours, and each under-2 usage share scaling the claiming families' children of its DfE age (the age on 31 December, as DfE counts them). At a bound: childcare_age_1_usage, universal_childcare." } }, { @@ -360,7 +360,7 @@ "output": "max_free_entitlement_hours_used", "entity": "person", "values": { - "2024-04-06": 0.6962 + "2024-04-06": 0.7 }, "source": { "source": "DfE Funded early education and childcare, January 2025 (reporting year 2025 headline figures)", @@ -371,17 +371,17 @@ }, "population": "children of DfE age 0 (age on 31 December of the model year) in benefit units that claim the working-parent hours (would_claim_extended_childcare)", "fitting_receipt": { - "source": "tools/fit_uk_childcare_takeup.py (microcosm#1338 round 3, licensed lane)", + "source": "tools/fit_uk_childcare_takeup.py (refit on policyengine-uk 2.151.0 after microcosm#1383, licensed lane)", "tool_version": 7, - "receipt_sha256": "7a9e44ff6d9da027199edb57ef529bbc82807dbc321d9ded00967a63afc573c6", + "receipt_sha256": "f41dc35911db339606b7a825d7a0d5d9d7b89bdbfb114a1cf5698e82f23a3881", "seed": 0, - "engine_version": "2.147.2", + "engine_version": "2.151.0", "model_period": 2025, "vintage_overrides": {}, - "input_h5_sha256": "f8e02d9da1ad15ca03c77878c14d047bee738c0abb128ba3fc3836b997ac9412", - "input_spine": "local unsigned spine built at 6aea1ec00 (uk-childcare-100k-fixes-v2 on main 8b0224e06; policyengine-uk 2.147.2, feed abf0921), sha256 f8e02d9da1ad15ca03c77878c14d047bee738c0abb128ba3fc3836b997ac9412; the fit overrides the take-up columns and reads only the stored ages and months, so the later commits leave it valid", + "input_h5_sha256": "bd8b4095565d5c1e6b8b88d3384a7a138348730585e40bd0a44b9e42990fcbd0", + "input_spine": "release-candidate spine built at fe1e2ad2c (main after microcosm#1383; policyengine-uk 2.151.0, feed abf0921), sha256 bd8b4095565d5c1e6b8b88d3384a7a138348730585e40bd0a44b9e42990fcbd0; the fit overrides the take-up columns and reads only the stored ages and months, so the later commits leave it valid", "ledger_facts_sha256": "2b64fecfe746164203dac1726aae6ffdb3e5d8e478bd3d64d118ac76cb00780b", - "stochastic_contract_sha256_at_fit": "1a9feb2bc9741b12c57d95f3c9c4364cad4cb43472782bb5be3bd19b410b44c5", + "stochastic_contract_sha256_at_fit": "dbbd3767cb35c6eabc35a80f384918c925cc27fac0c13f284b1ff3d769690272", "expectation_basis": "dfe_spring_term", "estimand": "The share of children of DfE age 0 (age on 31 December of the model year) who use the hours their family's working-parent claim gives them, fitted with the other age's share to DfE's working parent registrations at 9 to 11 months and at age 1 at the spring term.", "params_at_bound": [ @@ -390,7 +390,7 @@ ], "optimizer": { "eps": 1e-06, - "loss": 0.01538992050511465, + "loss": 0.013582517727076585, "maxiter": 50, "method": "L-BFGS-B", "success": true @@ -398,58 +398,58 @@ "achieved": { "dfe.funded_childcare.early_learning_2_year_olds": { "target": 95031.0, - "value": 95031.139, + "value": 95030.952, "ratio": 1.0 }, "dfe.funded_childcare.universal_only_children": { "target": 396965.0, - "value": 417767.817, - "ratio": 1.0524 + "value": 415750.362, + "ratio": 1.0473 }, "dfe.funded_childcare.working_parent_children_2_to_4": { "target": 621482.0, - "value": 620601.293, - "ratio": 0.9986 + "value": 618818.748, + "ratio": 0.9957 }, "dfe.funded_childcare.working_parent_children_9_to_11_months": { "target": 29155.0, - "value": 29154.994, + "value": 29154.976, "ratio": 1.0 }, "dfe.funded_childcare.working_parent_children_age_1": { "target": 195104.0, - "value": 183986.326, - "ratio": 0.943 + "value": 185825.116, + "ratio": 0.9524 }, "hmrc.tfc.children_with_used_accounts": { "target": 1151515.0, - "value": 1224841.813, - "ratio": 1.0637 + "value": 1223636.066, + "ratio": 1.0626 }, "hmrc.tfc.government_top_up": { "target": 599800000.0, - "value": 555971050.246, - "ratio": 0.9269 + "value": 556797174.046, + "ratio": 0.9283 } }, "diagnostic_rows": { "dfe.funded_childcare.universal_nursery_children_age_3": { "target": 565954.0, - "value": 571139.593, - "ratio": 1.0092 + "value": 568044.122, + "ratio": 1.0037 }, "dfe.funded_childcare.working_parent_children_age_2": { "target": 242453.0, - "value": 264624.601, - "ratio": 1.0914 + "value": 265018.154, + "ratio": 1.0931 }, "dfe.funded_childcare.working_parent_children_age_3": { "target": 278640.0, - "value": 260082.533, - "ratio": 0.9334 + "value": 257405.548, + "ratio": 0.9238 } }, - "status": "fitted at model year 2025 with the expectation basis of tool version 7: the DfE rows measured at the spring term by the age on 31 December (dfe_spring_term.py, policyengine-uk 2.147.2's date-of-birth school start and working-parent term start), universal take-up nested under working-parent take-up, targeted and universal hours allocated from the gross working-parent hours, and each under-2 usage share scaling the claiming families' children of its DfE age (the age on 31 December, as DfE counts them). At a bound: childcare_age_1_usage, universal_childcare." + "status": "fitted at model year 2025 with the expectation basis of tool version 7: the DfE rows measured at the spring term by the age on 31 December (dfe_spring_term.py, policyengine-uk 2.151.0's date-of-birth school start and working-parent term start), universal take-up nested under working-parent take-up, targeted and universal hours allocated from the gross working-parent hours, and each under-2 usage share scaling the claiming families' children of its DfE age (the age on 31 December, as DfE counts them). At a bound: childcare_age_1_usage, universal_childcare." } }, { @@ -468,17 +468,17 @@ }, "population": "children of DfE age 1 (age on 31 December of the model year) in benefit units that claim the working-parent hours (would_claim_extended_childcare)", "fitting_receipt": { - "source": "tools/fit_uk_childcare_takeup.py (microcosm#1338 round 3, licensed lane)", + "source": "tools/fit_uk_childcare_takeup.py (refit on policyengine-uk 2.151.0 after microcosm#1383, licensed lane)", "tool_version": 7, - "receipt_sha256": "7a9e44ff6d9da027199edb57ef529bbc82807dbc321d9ded00967a63afc573c6", + "receipt_sha256": "f41dc35911db339606b7a825d7a0d5d9d7b89bdbfb114a1cf5698e82f23a3881", "seed": 0, - "engine_version": "2.147.2", + "engine_version": "2.151.0", "model_period": 2025, "vintage_overrides": {}, - "input_h5_sha256": "f8e02d9da1ad15ca03c77878c14d047bee738c0abb128ba3fc3836b997ac9412", - "input_spine": "local unsigned spine built at 6aea1ec00 (uk-childcare-100k-fixes-v2 on main 8b0224e06; policyengine-uk 2.147.2, feed abf0921), sha256 f8e02d9da1ad15ca03c77878c14d047bee738c0abb128ba3fc3836b997ac9412; the fit overrides the take-up columns and reads only the stored ages and months, so the later commits leave it valid", + "input_h5_sha256": "bd8b4095565d5c1e6b8b88d3384a7a138348730585e40bd0a44b9e42990fcbd0", + "input_spine": "release-candidate spine built at fe1e2ad2c (main after microcosm#1383; policyengine-uk 2.151.0, feed abf0921), sha256 bd8b4095565d5c1e6b8b88d3384a7a138348730585e40bd0a44b9e42990fcbd0; the fit overrides the take-up columns and reads only the stored ages and months, so the later commits leave it valid", "ledger_facts_sha256": "2b64fecfe746164203dac1726aae6ffdb3e5d8e478bd3d64d118ac76cb00780b", - "stochastic_contract_sha256_at_fit": "1a9feb2bc9741b12c57d95f3c9c4364cad4cb43472782bb5be3bd19b410b44c5", + "stochastic_contract_sha256_at_fit": "dbbd3767cb35c6eabc35a80f384918c925cc27fac0c13f284b1ff3d769690272", "expectation_basis": "dfe_spring_term", "estimand": "The share of children of DfE age 1 (age on 31 December of the model year) who use the hours their family's working-parent claim gives them, fitted with the other age's share to DfE's working parent registrations at 9 to 11 months and at age 1 at the spring term.", "params_at_bound": [ @@ -487,7 +487,7 @@ ], "optimizer": { "eps": 1e-06, - "loss": 0.01538992050511465, + "loss": 0.013582517727076585, "maxiter": 50, "method": "L-BFGS-B", "success": true @@ -495,59 +495,59 @@ "achieved": { "dfe.funded_childcare.early_learning_2_year_olds": { "target": 95031.0, - "value": 95031.139, + "value": 95030.952, "ratio": 1.0 }, "dfe.funded_childcare.universal_only_children": { "target": 396965.0, - "value": 417767.817, - "ratio": 1.0524 + "value": 415750.362, + "ratio": 1.0473 }, "dfe.funded_childcare.working_parent_children_2_to_4": { "target": 621482.0, - "value": 620601.293, - "ratio": 0.9986 + "value": 618818.748, + "ratio": 0.9957 }, "dfe.funded_childcare.working_parent_children_9_to_11_months": { "target": 29155.0, - "value": 29154.994, + "value": 29154.976, "ratio": 1.0 }, "dfe.funded_childcare.working_parent_children_age_1": { "target": 195104.0, - "value": 183986.326, - "ratio": 0.943 + "value": 185825.116, + "ratio": 0.9524 }, "hmrc.tfc.children_with_used_accounts": { "target": 1151515.0, - "value": 1224841.813, - "ratio": 1.0637 + "value": 1223636.066, + "ratio": 1.0626 }, "hmrc.tfc.government_top_up": { "target": 599800000.0, - "value": 555971050.246, - "ratio": 0.9269 + "value": 556797174.046, + "ratio": 0.9283 } }, "diagnostic_rows": { "dfe.funded_childcare.universal_nursery_children_age_3": { "target": 565954.0, - "value": 571139.593, - "ratio": 1.0092 + "value": 568044.122, + "ratio": 1.0037 }, "dfe.funded_childcare.working_parent_children_age_2": { "target": 242453.0, - "value": 264624.601, - "ratio": 1.0914 + "value": 265018.154, + "ratio": 1.0931 }, "dfe.funded_childcare.working_parent_children_age_3": { "target": 278640.0, - "value": 260082.533, - "ratio": 0.9334 + "value": 257405.548, + "ratio": 0.9238 } }, - "status": "fitted at model year 2025 with the expectation basis of tool version 7: the DfE rows measured at the spring term by the age on 31 December (dfe_spring_term.py, policyengine-uk 2.147.2's date-of-birth school start and working-parent term start), universal take-up nested under working-parent take-up, targeted and universal hours allocated from the gross working-parent hours, and each under-2 usage share scaling the claiming families' children of its DfE age (the age on 31 December, as DfE counts them). At a bound: childcare_age_1_usage, universal_childcare.", - "at_bound_reason": "The age-1 usage share stops at its upper bound of 1: even with every child of DfE age 1 in a claiming family using the hours, the frame's working-parent children at DfE age 1 fall short of DfE's January count at the 2-to-4 rate (ratio 0.943). The bound is kept and the residual recorded; the national calibration binds the row." + "status": "fitted at model year 2025 with the expectation basis of tool version 7: the DfE rows measured at the spring term by the age on 31 December (dfe_spring_term.py, policyengine-uk 2.151.0's date-of-birth school start and working-parent term start), universal take-up nested under working-parent take-up, targeted and universal hours allocated from the gross working-parent hours, and each under-2 usage share scaling the claiming families' children of its DfE age (the age on 31 December, as DfE counts them). At a bound: childcare_age_1_usage, universal_childcare.", + "at_bound_reason": "The age-1 usage share stops at its upper bound of 1: even with every child of DfE age 1 in a claiming family using the hours, the frame's working-parent children at DfE age 1 fall short of DfE's January count at the 2-to-4 rate (ratio 0.952). The bound is kept and the residual recorded; the national calibration binds the row." } }, { @@ -566,17 +566,17 @@ "status": "fitted_offline" }, "fitting_receipt": { - "source": "tools/fit_uk_childcare_takeup.py (microcosm#1338 round 3, licensed lane)", + "source": "tools/fit_uk_childcare_takeup.py (refit on policyengine-uk 2.151.0 after microcosm#1383, licensed lane)", "tool_version": 7, - "receipt_sha256": "7a9e44ff6d9da027199edb57ef529bbc82807dbc321d9ded00967a63afc573c6", + "receipt_sha256": "f41dc35911db339606b7a825d7a0d5d9d7b89bdbfb114a1cf5698e82f23a3881", "seed": 0, - "engine_version": "2.147.2", + "engine_version": "2.151.0", "model_period": 2025, "vintage_overrides": {}, - "input_h5_sha256": "f8e02d9da1ad15ca03c77878c14d047bee738c0abb128ba3fc3836b997ac9412", - "input_spine": "local unsigned spine built at 6aea1ec00 (uk-childcare-100k-fixes-v2 on main 8b0224e06; policyengine-uk 2.147.2, feed abf0921), sha256 f8e02d9da1ad15ca03c77878c14d047bee738c0abb128ba3fc3836b997ac9412; the fit overrides the take-up columns and reads only the stored ages and months, so the later commits leave it valid", + "input_h5_sha256": "bd8b4095565d5c1e6b8b88d3384a7a138348730585e40bd0a44b9e42990fcbd0", + "input_spine": "release-candidate spine built at fe1e2ad2c (main after microcosm#1383; policyengine-uk 2.151.0, feed abf0921), sha256 bd8b4095565d5c1e6b8b88d3384a7a138348730585e40bd0a44b9e42990fcbd0; the fit overrides the take-up columns and reads only the stored ages and months, so the later commits leave it valid", "ledger_facts_sha256": "2b64fecfe746164203dac1726aae6ffdb3e5d8e478bd3d64d118ac76cb00780b", - "stochastic_contract_sha256_at_fit": "1a9feb2bc9741b12c57d95f3c9c4364cad4cb43472782bb5be3bd19b410b44c5", + "stochastic_contract_sha256_at_fit": "dbbd3767cb35c6eabc35a80f384918c925cc27fac0c13f284b1ff3d769690272", "expectation_basis": "dfe_spring_term", "estimand": "The universal claim rate among benefit units that do not claim working-parent hours (nested), fitted to DfE's universal-only registrations at the spring term.", "params_at_bound": [ @@ -585,7 +585,7 @@ ], "optimizer": { "eps": 1e-06, - "loss": 0.01538992050511465, + "loss": 0.013582517727076585, "maxiter": 50, "method": "L-BFGS-B", "success": true @@ -593,59 +593,59 @@ "achieved": { "dfe.funded_childcare.early_learning_2_year_olds": { "target": 95031.0, - "value": 95031.139, + "value": 95030.952, "ratio": 1.0 }, "dfe.funded_childcare.universal_only_children": { "target": 396965.0, - "value": 417767.817, - "ratio": 1.0524 + "value": 415750.362, + "ratio": 1.0473 }, "dfe.funded_childcare.working_parent_children_2_to_4": { "target": 621482.0, - "value": 620601.293, - "ratio": 0.9986 + "value": 618818.748, + "ratio": 0.9957 }, "dfe.funded_childcare.working_parent_children_9_to_11_months": { "target": 29155.0, - "value": 29154.994, + "value": 29154.976, "ratio": 1.0 }, "dfe.funded_childcare.working_parent_children_age_1": { "target": 195104.0, - "value": 183986.326, - "ratio": 0.943 + "value": 185825.116, + "ratio": 0.9524 }, "hmrc.tfc.children_with_used_accounts": { "target": 1151515.0, - "value": 1224841.813, - "ratio": 1.0637 + "value": 1223636.066, + "ratio": 1.0626 }, "hmrc.tfc.government_top_up": { "target": 599800000.0, - "value": 555971050.246, - "ratio": 0.9269 + "value": 556797174.046, + "ratio": 0.9283 } }, "diagnostic_rows": { "dfe.funded_childcare.universal_nursery_children_age_3": { "target": 565954.0, - "value": 571139.593, - "ratio": 1.0092 + "value": 568044.122, + "ratio": 1.0037 }, "dfe.funded_childcare.working_parent_children_age_2": { "target": 242453.0, - "value": 264624.601, - "ratio": 1.0914 + "value": 265018.154, + "ratio": 1.0931 }, "dfe.funded_childcare.working_parent_children_age_3": { "target": 278640.0, - "value": 260082.533, - "ratio": 0.9334 + "value": 257405.548, + "ratio": 0.9238 } }, - "status": "fitted at model year 2025 with the expectation basis of tool version 7: the DfE rows measured at the spring term by the age on 31 December (dfe_spring_term.py, policyengine-uk 2.147.2's date-of-birth school start and working-parent term start), universal take-up nested under working-parent take-up, targeted and universal hours allocated from the gross working-parent hours, and each under-2 usage share scaling the claiming families' children of its DfE age (the age on 31 December, as DfE counts them). At a bound: childcare_age_1_usage, universal_childcare.", - "at_bound_reason": "The conditional universal rate stops at its lower bound of 0: universal take-up is nested under the working-parent flag, which is drawn for every benefit unit, including families that can never get working-parent hours, so no family's universal take-up falls below the working-parent rate. The claiming families alone already give more universal-only children at the spring term than DfE's January count (ratio 1.052 at a rate of 0). The bound is kept and the residual recorded; the national calibration binds the row." + "status": "fitted at model year 2025 with the expectation basis of tool version 7: the DfE rows measured at the spring term by the age on 31 December (dfe_spring_term.py, policyengine-uk 2.151.0's date-of-birth school start and working-parent term start), universal take-up nested under working-parent take-up, targeted and universal hours allocated from the gross working-parent hours, and each under-2 usage share scaling the claiming families' children of its DfE age (the age on 31 December, as DfE counts them). At a bound: childcare_age_1_usage, universal_childcare.", + "at_bound_reason": "The conditional universal rate stops at its lower bound of 0: universal take-up is nested under the working-parent flag, which is drawn for every benefit unit, including families that can never get working-parent hours, so no family's universal take-up falls below the working-parent rate. The claiming families alone already give more universal-only children at the spring term than DfE's January count (ratio 1.047 at a rate of 0). The bound is kept and the residual recorded; the national calibration binds the row." } }, { @@ -654,7 +654,7 @@ "entity": "benunit", "values": { "2015-01-01": 0.597, - "2024-04-06": 0.6551 + "2024-04-06": 0.8687 }, "source": { "source": "FRS empirical fit", @@ -663,17 +663,17 @@ "status": "fitted_offline" }, "fitting_receipt": { - "source": "tools/fit_uk_childcare_takeup.py (microcosm#1338 round 3, licensed lane)", + "source": "tools/fit_uk_childcare_takeup.py (refit on policyengine-uk 2.151.0 after microcosm#1383, licensed lane)", "tool_version": 7, - "receipt_sha256": "7a9e44ff6d9da027199edb57ef529bbc82807dbc321d9ded00967a63afc573c6", + "receipt_sha256": "f41dc35911db339606b7a825d7a0d5d9d7b89bdbfb114a1cf5698e82f23a3881", "seed": 0, - "engine_version": "2.147.2", + "engine_version": "2.151.0", "model_period": 2025, "vintage_overrides": {}, - "input_h5_sha256": "f8e02d9da1ad15ca03c77878c14d047bee738c0abb128ba3fc3836b997ac9412", - "input_spine": "local unsigned spine built at 6aea1ec00 (uk-childcare-100k-fixes-v2 on main 8b0224e06; policyengine-uk 2.147.2, feed abf0921), sha256 f8e02d9da1ad15ca03c77878c14d047bee738c0abb128ba3fc3836b997ac9412; the fit overrides the take-up columns and reads only the stored ages and months, so the later commits leave it valid", + "input_h5_sha256": "bd8b4095565d5c1e6b8b88d3384a7a138348730585e40bd0a44b9e42990fcbd0", + "input_spine": "release-candidate spine built at fe1e2ad2c (main after microcosm#1383; policyengine-uk 2.151.0, feed abf0921), sha256 bd8b4095565d5c1e6b8b88d3384a7a138348730585e40bd0a44b9e42990fcbd0; the fit overrides the take-up columns and reads only the stored ages and months, so the later commits leave it valid", "ledger_facts_sha256": "2b64fecfe746164203dac1726aae6ffdb3e5d8e478bd3d64d118ac76cb00780b", - "stochastic_contract_sha256_at_fit": "1a9feb2bc9741b12c57d95f3c9c4364cad4cb43472782bb5be3bd19b410b44c5", + "stochastic_contract_sha256_at_fit": "dbbd3767cb35c6eabc35a80f384918c925cc27fac0c13f284b1ff3d769690272", "expectation_basis": "dfe_spring_term", "estimand": "The share of qualifying benefit units that claim early learning for 2-year-olds on their own, fitted to DfE's registrations at the spring term.", "params_at_bound": [ @@ -682,7 +682,7 @@ ], "optimizer": { "eps": 1e-06, - "loss": 0.01538992050511465, + "loss": 0.013582517727076585, "maxiter": 50, "method": "L-BFGS-B", "success": true @@ -690,58 +690,58 @@ "achieved": { "dfe.funded_childcare.early_learning_2_year_olds": { "target": 95031.0, - "value": 95031.139, + "value": 95030.952, "ratio": 1.0 }, "dfe.funded_childcare.universal_only_children": { "target": 396965.0, - "value": 417767.817, - "ratio": 1.0524 + "value": 415750.362, + "ratio": 1.0473 }, "dfe.funded_childcare.working_parent_children_2_to_4": { "target": 621482.0, - "value": 620601.293, - "ratio": 0.9986 + "value": 618818.748, + "ratio": 0.9957 }, "dfe.funded_childcare.working_parent_children_9_to_11_months": { "target": 29155.0, - "value": 29154.994, + "value": 29154.976, "ratio": 1.0 }, "dfe.funded_childcare.working_parent_children_age_1": { "target": 195104.0, - "value": 183986.326, - "ratio": 0.943 + "value": 185825.116, + "ratio": 0.9524 }, "hmrc.tfc.children_with_used_accounts": { "target": 1151515.0, - "value": 1224841.813, - "ratio": 1.0637 + "value": 1223636.066, + "ratio": 1.0626 }, "hmrc.tfc.government_top_up": { "target": 599800000.0, - "value": 555971050.246, - "ratio": 0.9269 + "value": 556797174.046, + "ratio": 0.9283 } }, "diagnostic_rows": { "dfe.funded_childcare.universal_nursery_children_age_3": { "target": 565954.0, - "value": 571139.593, - "ratio": 1.0092 + "value": 568044.122, + "ratio": 1.0037 }, "dfe.funded_childcare.working_parent_children_age_2": { "target": 242453.0, - "value": 264624.601, - "ratio": 1.0914 + "value": 265018.154, + "ratio": 1.0931 }, "dfe.funded_childcare.working_parent_children_age_3": { "target": 278640.0, - "value": 260082.533, - "ratio": 0.9334 + "value": 257405.548, + "ratio": 0.9238 } }, - "status": "fitted at model year 2025 with the expectation basis of tool version 7: the DfE rows measured at the spring term by the age on 31 December (dfe_spring_term.py, policyengine-uk 2.147.2's date-of-birth school start and working-parent term start), universal take-up nested under working-parent take-up, targeted and universal hours allocated from the gross working-parent hours, and each under-2 usage share scaling the claiming families' children of its DfE age (the age on 31 December, as DfE counts them). At a bound: childcare_age_1_usage, universal_childcare." + "status": "fitted at model year 2025 with the expectation basis of tool version 7: the DfE rows measured at the spring term by the age on 31 December (dfe_spring_term.py, policyengine-uk 2.151.0's date-of-birth school start and working-parent term start), universal take-up nested under working-parent take-up, targeted and universal hours allocated from the gross working-parent hours, and each under-2 usage share scaling the claiming families' children of its DfE age (the age on 31 December, as DfE counts them). At a bound: childcare_age_1_usage, universal_childcare." } }, { diff --git a/packages/microcosm-build/src/microcosm/build/uk/target_fit_reviewed_exclusions.json b/packages/microcosm-build/src/microcosm/build/uk/target_fit_reviewed_exclusions.json index 5cc678ba07..241fce262b 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/target_fit_reviewed_exclusions.json +++ b/packages/microcosm-build/src/microcosm/build/uk/target_fit_reviewed_exclusions.json @@ -2,86 +2,6 @@ "schema_version": 2, "description": "Reviewed target-fit exclusions for the UK terminal battery (schema 2 per #610). Each entry defers one calibration target whose |relative error| breaches the 25% release bound, with the defect diagnosed, tracked, and owned elsewhere; the receipt records the reasoning, approver, adjudication reference, approval date, and expiry. The gate keeps the target BOUND in calibration (exclusion applies to the release fence only, never the solve), reports dormant entries, FAILS stale ones (targets back inside the bound), and FAILS expired ones until the adjudication is renewed, so this register cannot rot.", "exclusions": { - "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_0_to_1_200@2025": { - "reason": "Gate-only sign-off of the national target row dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_0_to_1_200@2025 on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261018T161007Z-35fb4c89 (full gate report sha256 46d42e6abf5fa8eaf08e3301a982703f113838c41cb7869340a3a41bafc6407f) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", - "approved_by": "juaristi22", - "adjudication": "Gate-only sign-off of the local release's measured build, drafted from its run (microcosm#1301, microcosm#1310).", - "approved_on": "2026-10-19", - "expires_on": "2026-11-16", - "release_lines": [ - "local" - ] - }, - "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_1_200_to_2_400@2025": { - "reason": "Gate-only sign-off of the national target row dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_1_200_to_2_400@2025 on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261018T161007Z-35fb4c89 (full gate report sha256 46d42e6abf5fa8eaf08e3301a982703f113838c41cb7869340a3a41bafc6407f) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", - "approved_by": "juaristi22", - "adjudication": "Gate-only sign-off of the local release's measured build, drafted from its run (microcosm#1301, microcosm#1310).", - "approved_on": "2026-10-19", - "expires_on": "2026-11-16", - "release_lines": [ - "local" - ] - }, - "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_2_400_to_3_600@2025": { - "reason": "Gate-only sign-off of the national target row dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_2_400_to_3_600@2025 on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261018T161007Z-35fb4c89 (full gate report sha256 46d42e6abf5fa8eaf08e3301a982703f113838c41cb7869340a3a41bafc6407f) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", - "approved_by": "juaristi22", - "adjudication": "Gate-only sign-off of the local release's measured build, drafted from its run (microcosm#1301, microcosm#1310).", - "approved_on": "2026-10-19", - "expires_on": "2026-11-16", - "release_lines": [ - "local" - ] - }, - "dwp/uc_payment_dist/SINGLE_annual_payment_2_400_to_3_600@2025": { - "reason": "Gate-only sign-off of the national target row dwp/uc_payment_dist/SINGLE_annual_payment_2_400_to_3_600@2025 on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261018T161007Z-35fb4c89 (full gate report sha256 46d42e6abf5fa8eaf08e3301a982703f113838c41cb7869340a3a41bafc6407f) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", - "approved_by": "juaristi22", - "adjudication": "Gate-only sign-off of the local release's measured build, drafted from its run (microcosm#1301, microcosm#1310).", - "approved_on": "2026-10-19", - "expires_on": "2026-11-16", - "release_lines": [ - "local" - ] - }, - "hmrc.itl.taxpayers_by_total_income_band.band_2000000_plus@2025": { - "reason": "Gate-only sign-off of the national target row hmrc.itl.taxpayers_by_total_income_band.band_2000000_plus@2025 on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261018T161007Z-35fb4c89 (full gate report sha256 46d42e6abf5fa8eaf08e3301a982703f113838c41cb7869340a3a41bafc6407f) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", - "approved_by": "juaristi22", - "adjudication": "Gate-only sign-off of the local release's measured build, drafted from its run (microcosm#1301, microcosm#1310).", - "approved_on": "2026-10-19", - "expires_on": "2026-11-16", - "release_lines": [ - "local" - ] - }, - "hmrc.spi.savings_interest_income.count_by_total_income_band.band_150000@2025": { - "reason": "Gate-only sign-off of the national target row hmrc.spi.savings_interest_income.count_by_total_income_band.band_150000@2025 on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261018T161007Z-35fb4c89 (full gate report sha256 46d42e6abf5fa8eaf08e3301a982703f113838c41cb7869340a3a41bafc6407f) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", - "approved_by": "juaristi22", - "adjudication": "Gate-only sign-off of the local release's measured build, drafted from its run (microcosm#1301, microcosm#1310).", - "approved_on": "2026-10-19", - "expires_on": "2026-11-16", - "release_lines": [ - "local" - ] - }, - "hmrc.spi_region.taxpayers_by_region_200000_plus@E12000004@2025": { - "reason": "Gate-only sign-off of the national target row hmrc.spi_region.taxpayers_by_region_200000_plus@E12000004@2025 on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261018T161007Z-35fb4c89 (full gate report sha256 46d42e6abf5fa8eaf08e3301a982703f113838c41cb7869340a3a41bafc6407f) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", - "approved_by": "juaristi22", - "adjudication": "Gate-only sign-off of the local release's measured build, drafted from its run (microcosm#1301, microcosm#1310).", - "approved_on": "2026-10-19", - "expires_on": "2026-11-16", - "release_lines": [ - "local" - ] - }, - "hmrc/dividend_income_income_band_15_000_to_20_000@2025": { - "reason": "Gate-only sign-off of the national target row hmrc/dividend_income_income_band_15_000_to_20_000@2025 on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261018T161007Z-35fb4c89 (full gate report sha256 46d42e6abf5fa8eaf08e3301a982703f113838c41cb7869340a3a41bafc6407f) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", - "approved_by": "juaristi22", - "adjudication": "Gate-only sign-off of the local release's measured build, drafted from its run (microcosm#1301, microcosm#1310).", - "approved_on": "2026-10-19", - "expires_on": "2026-11-16", - "release_lines": [ - "local" - ] - }, "hmrc/dividend_income_income_band_20_000_to_30_000@2025": { "reason": "Gate-only sign-off of the national target row hmrc/dividend_income_income_band_20_000_to_30_000@2025 on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261018T161007Z-35fb4c89 (full gate report sha256 46d42e6abf5fa8eaf08e3301a982703f113838c41cb7869340a3a41bafc6407f) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", "approved_by": "juaristi22", @@ -132,22 +52,12 @@ "local" ] }, - "hmrc/property_income_income_band_12_570_to_15_000@2025": { - "reason": "Gate-only sign-off of the national target row hmrc/property_income_income_band_12_570_to_15_000@2025 on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261018T161007Z-35fb4c89 (full gate report sha256 46d42e6abf5fa8eaf08e3301a982703f113838c41cb7869340a3a41bafc6407f) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", - "approved_by": "juaristi22", - "adjudication": "Gate-only sign-off of the local release's measured build, drafted from its run (microcosm#1301, microcosm#1310).", - "approved_on": "2026-10-19", - "expires_on": "2026-11-16", - "release_lines": [ - "local" - ] - }, - "hmrc/property_income_income_band_15_000_to_20_000@2025": { - "reason": "Gate-only sign-off of the national target row hmrc/property_income_income_band_15_000_to_20_000@2025 on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261018T161007Z-35fb4c89 (full gate report sha256 46d42e6abf5fa8eaf08e3301a982703f113838c41cb7869340a3a41bafc6407f) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", + "hmrc/state_pension_count_income_band_500_000_to_1_000_000@2025": { + "reason": "Gate-only sign-off of the national target row hmrc/state_pension_count_income_band_500_000_to_1_000_000@2025 on the local line (microcosm#1301). On dense build-1 attempt uk-local-candidate-f100-s42-20261026T091056Z-824870f6 (full gate report sha256 abf245413ca0809f9f261e650c352ef310d11e19960b8e4c5ade3bc57dddf411) it breached the target-fit release bound (max_abs_relative_error 0.25). It stays bound in the solve: this entry suppresses only the release fence on the local line, and a build in which it is back inside the bound fails the entry as stale.", "approved_by": "juaristi22", - "adjudication": "Gate-only sign-off of the local release's measured build, drafted from its run (microcosm#1301, microcosm#1310).", - "approved_on": "2026-10-19", - "expires_on": "2026-11-16", + "adjudication": "Gate-only sign-off of the local release's measured build, drafted from its run (microcosm#1301, microcosm#1396).", + "approved_on": "2026-10-26", + "expires_on": "2026-11-23", "release_lines": [ "local" ] diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/battery_bindings.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/battery_bindings.py index 377842ee47..f842130325 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/battery_bindings.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/battery_bindings.py @@ -62,10 +62,7 @@ UK_CGT_PROJECTION_ARTIFACT_KEY, UKCGTProjection, ) -from microcosm.build.uk_runtime.diagnostics import ( - uk_support_family_weights, - uk_withheld_gate_keys, -) +from microcosm.build.uk_runtime.diagnostics import uk_support_family_weights from microcosm.build.uk_runtime.frs_take_up import uk_take_up_signal_gate from microcosm.build.uk_runtime.geography_ladder import uk_geography_ladder_gate from microcosm.build.uk_runtime.high_value_home_gates import ( @@ -1455,35 +1452,12 @@ def _local_target_error_items(evidence: object) -> tuple[tuple[str, float], ...] def _evaluate_per_family_fit( context: EvidenceContext, parameters: Mapping[str, Any] ) -> GateResult: - """Each family's fit over its published rows (microcosm#1262). - - A row whose model figures are withheld stays out of every rollup, so the - family shares, sizes and the decision rest on the published rows and the - details count the withheld ones by family: a share over every row, set - beside the published rows' errors, would give a withheld row's fit back. - """ - - evidence = context.artifacts["local_target_diagnostics"] - items = _local_target_error_items(evidence) - withheld = uk_withheld_gate_keys(evidence) - published = [(name, error) for name, error in items if name not in withheld] - result = per_family_fit_gate( - (name for name, _ in published), - (error for _, error in published), + items = _local_target_error_items(context.artifacts["local_target_diagnostics"]) + return per_family_fit_gate( + (name for name, _ in items), + (error for _, error in items), **dict(parameters), ) - if not withheld: - return result - counts: dict[str, int] = {} - for name in withheld: - family = name.split("/", 1)[0] - counts[family] = counts.get(family, 0) + 1 - return GateResult( - name=result.name, - passed=result.passed, - failures=result.failures, - details={**result.details, "withheld_targets": dict(sorted(counts.items()))}, - ) def _evaluate_weights_audit( @@ -1745,38 +1719,18 @@ def _evaluate_target_fit( f"uk/gates.json names local exclusion register {register!r} but " f"the runtime loads {UK_LOCAL_TARGET_FIT_EXCLUSION_REGISTER_RESOURCE!r}." ) - evidence = context.artifacts["local_target_diagnostics"] - # María's ruling of 2026-10-19 on the third review of #1305: the gate - # decides on the published rows. A withheld BRMA row's status against - # the bound would be a two-sided bound on an estimate resting on fewer - # than ten households, so the gate neither checks it nor reads its - # register entry, and counts it only. - withheld = uk_withheld_gate_keys(evidence) - errors = { - key: error - for key, error in _local_target_error_items(evidence) - if key not in withheld - } + errors = dict( + _local_target_error_items(context.artifacts["local_target_diagnostics"]) + ) exclusions, out_of_line = _in_line( uk_default_local_target_fit_reviewed_exclusions(), context ) - exclusions = { - key: record for key, record in exclusions.items() if key not in withheld - } - out_of_line = [key for key in out_of_line if key not in withheld] result = uk_target_fit_gate( errors, reviewed_exclusions=exclusions, now=_exclusion_clock(context), **kwargs, ) - if withheld: - result = GateResult( - name=result.name, - passed=result.passed, - failures=result.failures, - details={**result.details, "withheld_targets": len(withheld)}, - ) return _with_out_of_line(result, context, out_of_line) if register != UK_TARGET_FIT_EXCLUSION_REGISTER_RESOURCE: raise ValueError( @@ -1786,34 +1740,12 @@ def _evaluate_target_fit( exclusions, _source = _resolve_target_fit_exclusions(context) exclusions, out_of_line = _in_line(exclusions, context) parity = context.artifacts["parity_evidence"] - # María's rule of 2026-10-21 binds a national row however few source - # households carry it, and keeps the figures of one under ten in the - # build; the gate decides on the published rows and counts the withheld - # ones, as it does for the local rows (her ruling of 2026-10-19). Every - # producer states the set, empty or not, so a missing one fails closed. - withheld = frozenset(parity.withheld_targets) - errors = { - name: error - for name, error in parity.target_relative_errors.items() - if name not in withheld - } - exclusions = { - name: record for name, record in exclusions.items() if name not in withheld - } - out_of_line = [name for name in out_of_line if name not in withheld] result = uk_target_fit_gate( - errors, + parity.target_relative_errors, reviewed_exclusions=exclusions, now=_exclusion_clock(context), **kwargs, ) - if withheld: - result = GateResult( - name=result.name, - passed=result.passed, - failures=result.failures, - details={**result.details, "withheld_targets": len(withheld)}, - ) return _with_out_of_line(result, context, out_of_line) @@ -2301,7 +2233,9 @@ def _ledger_compile_parity_required_artifacts( "take_up_signal": UKGateBinding( name="take_up_signal", evaluator=_evaluate_take_up_signal, - parameter_keys=frozenset({"maximum_share_deviation"}), + parameter_keys=frozenset( + {"maximum_share_deviation", "under_two_usage_maximum_share_deviation"} + ), ), "enum_domain": UKGateBinding( name="enum_domain", diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/diagnostics.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/diagnostics.py index dc447af60b..861c6d1663 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/diagnostics.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/diagnostics.py @@ -14,38 +14,26 @@ from __future__ import annotations -import functools import json import math -import sys -import time -import warnings -from collections.abc import Collection, Mapping, Sequence -from dataclasses import dataclass +from collections.abc import Mapping, Sequence from importlib import resources as importlib_resources from pathlib import Path -from types import SimpleNamespace from typing import Any import numpy as np import pandas as pd from pydantic import ValidationError -from scipy import linalg as scipy_linalg -from scipy import sparse from microcosm.calibrate import ( TargetRegistry, diagnostics_payload, effective_sample_size, ) -from microcosm.calibrate.diagnostics import past_cap_census from microcosm.calibrate.solve import CalibrationResult from microcosm.diagnostics import ( UK_DIAGNOSTICS_SCHEMA_VERSION, - UK_MODEL_FIGURE_FIELDS, UK_TARGET_GEOGRAPHY_LEVELS, - UK_WITHHELD_PUBLISHED_ITERATE_FIELDS, - UK_WITHHELD_PUBLISHED_OPTIONS, CalibrationDiagnosticsV8, DiagnosticsWriteOutcome, failed_diagnostics_outcome, @@ -79,26 +67,12 @@ _TARGET_PASS_RELATIVE_ERROR = 0.10 _AREA_FIT_LIMIT = 15 -#: A target row's model figures leave the build only when at least this many -#: distinct source households carry them (UKDS CD137 clause 8): María's ruling -#: of 2026-10-17 on the #1305 review for BRMA rows, extended to national and -#: regional rows by her rule of 2026-10-21, which binds a thin row rather -#: than leave it out (local rows keep the area-support rule). +#: The fewest distinct source households a published cell may rest on (UKDS +#: CD137 clause 8). The build no longer withholds model figures (María's +#: ruling of 2026-10-26), but the report tools that publish their own tables, +#: such as the single years of age and the council tax liability comparison, +#: still suppress the cells below it. UK_DIAGNOSTIC_MIN_SOURCE_HOUSEHOLDS = 10 -#: The BRMA rows' floor, the same ten under its own ruling of 2026-10-17 (the -#: support gate covers constituencies and authorities, not the partial BRMA -#: grain). -UK_BRMA_DIAGNOSTIC_MIN_SOURCE_HOUSEHOLDS = 10 -#: The fields of a target row that the model's weights produce (the shared -#: tuple the release contract checks too). -_MODEL_FIGURE_FIELDS = UK_MODEL_FIGURE_FIELDS -_WITHHELD_NOTE = ( - "model figures withheld: fewer than 10 distinct source households carry this row" -) -_COMPLEMENT_NOTE = ( - "model figures withheld: with the published rows they would give back a row " - "or a cell that fewer than 10 distinct source households carry" -) _COUNTRY_BY_AREA_PREFIX = { "E": "England", @@ -191,14 +165,20 @@ def uk_weakest_areas_by_fit( """Return bottom-by-fit local areas plus country-level fit rollups. ``area_support`` must cover every scored area. A row carries the area's - ``support_below_floor`` flag when the table has one, never its rows, ESS - or distinct sources: these diagnostics ship in a release, and per-area - support figures stay in the build's area-support table (microcosm#1301). + rows, Kish ESS and distinct sources, and its ``support_below_floor`` flag + when the table has one: María's ruling of 2026-10-26 dropped the + withholding of these per-area figures (microcosm#1301). """ if isinstance(limit, bool) or not isinstance(limit, int) or limit <= 0: raise ValueError("UK weakest-area limit must be a positive integer.") - required = {"geography_level", "area_code"} + required = { + "geography_level", + "area_code", + "nonzero_households", + "nonzero_source_households", + "effective_sample_size", + } missing = sorted(required - set(area_support.columns)) if missing: raise ValueError(f"UK area support is missing rollup column(s): {missing}.") @@ -248,6 +228,9 @@ def uk_weakest_areas_by_fit( "worst_target": worst_name, "worst_abs_relative_error": worst_error, "loss_contribution": math.fsum(item[2] for item in rows), + "nonzero_households": int(support.nonzero_households), + "nonzero_source_households": int(support.nonzero_source_households), + "effective_sample_size": float(support.effective_sample_size), **_support_flag(support.support_below_floor if flagged else None), } ) @@ -341,9 +324,9 @@ def uk_support_limited_misses( The per-grain rollups (failing cells, their share in the bottom ESS decile, the rank correlation of fit with ESS) are over many areas. The - worst areas are listed by code and fit, with ``support_below_floor`` when - the support table carries it; their rows, ESS and distinct sources stay - in the build's area-support table (microcosm#1301). + worst areas are listed by code and fit with their rows, ESS and distinct + sources, and ``support_below_floor`` when the support table carries it + (María's ruling of 2026-10-26 dropped the withholding of microcosm#1301). """ if not math.isfinite(max_abs_relative_error) or max_abs_relative_error < 0: @@ -356,7 +339,12 @@ def uk_support_limited_misses( result: dict[str, dict[str, object]] = {} for raw_grain, support in sorted(area_support.items()): grain = str(raw_grain) - required_support = {"area_code", "effective_sample_size"} + required_support = { + "area_code", + "assigned_households", + "effective_sample_size", + "nonzero_source_households", + } support_missing = sorted(required_support - set(support.columns)) if support_missing: raise ValueError( @@ -441,6 +429,9 @@ def uk_support_limited_misses( { "area_code": str(row["area_code"]), "worst_abs_relative_error": float(row["worst_abs_relative_error"]), + "rows": int(row["assigned_households"]), + "ess": float(row["effective_sample_size"]), + "sources": int(row["nonzero_source_households"]), **_support_flag(row.get("support_below_floor")), } for _, row in worst.iterrows() @@ -1075,1578 +1066,10 @@ def _declared_target_partition( return declared, compiled, skipped_names -#: The local area levels whose rows the area-support rule binds -#: (``uk_local_area_support``). Their figures follow the per-row floor below -#: like every other row's (María's ruling of 2026-10-23 on the local line): -#: the support rule still decides which local rows bind, the floor which -#: published figures are withheld. A local surface binds many families in -#: each area, so its rows are checked by region and by family -#: (:func:`_row_blocks`), and the report guard matches a withheld local row by -#: its own key, never by its bare area code as it does a BRMA's one family. -UK_AREA_SUPPORT_LEVELS = frozenset({"constituency", "local_authority"}) - - -#: How near a combination of withheld rows may come to the published rows' -#: span and still count as given back: the squared distance of its unit-normed -#: row, so within 0.1% in norm, which the published figures reproduce to the -#: same precision. Exact recoveries sit near 1e-9 and the rest above 1e-3. -_RECOVERY_TOLERANCE = 1e-6 -#: Below this share of the largest entry, an entry of a row-reduced -#: combination, of its values or of its published coefficients is rounding -#: (the eigenvectors carry errors near 1e-8). Treating a small entry as zero -#: can only shrink a combination's support, so it errs toward withholding. -_RECOVERY_ROUNDING = 1e-6 -#: How much work the exact residual search may do for one total: the share -#: entries it adds up and the source households it counts, over the sets it -#: tries, and at most ``_RESIDUAL_SEARCH_NODES`` sets. Counts, not a clock, so -#: the same problem always gets the same answer. A total whose search stops -#: there, or whose members times atoms pass ``_RESIDUAL_DENSE_LIMIT``, is -#: checked over greedy groups instead, and a warning names it. -_RESIDUAL_SEARCH_WORK = 200_000_000 -_RESIDUAL_SEARCH_NODES = 200_000 -_RESIDUAL_DENSE_LIMIT = 5_000_000 - - -def _row_level(geography_levels: Mapping[str, object] | None): - def level(name: str) -> str: - raw = (geography_levels or {}).get(name, "") - text = str(getattr(raw, "value", raw)).strip().lower() - return _GEOGRAPHY_LEVEL_ALIASES.get(text, text) - - return level - - -def _row_area(row: Mapping[str, object]) -> str: - """A local row's area code: its own field, its metadata's, or its name's.""" - - area = str(row.get("area_code") or "").strip() - if not area: - metadata = row.get("metadata") - if isinstance(metadata, Mapping): - area = str(metadata.get("geography_id") or "").strip() - if not area: - # Local row names are ``target_id@area_code@period``. - parts = str(row["name"]).split("@") - area = parts[-2] if len(parts) >= 3 else "" - if not area: - raise ValueError(f"UK local row {row['name']!r} names no area.") - return area - - -def _row_blocks( - target_rows: Sequence[Mapping[str, object]], - geography_levels: Mapping[str, object] | None, - span: _CarrierSpan | None = None, -) -> list[list[str]]: - """The rows each withholding check spans, each block sorted. - - The national, regional and BRMA rows form one block, as one span holds - them. A local surface is too large for one dense span, so its rows are - checked in blocks that may overlap (María's ruling of 2026-10-23 on the - local line; Vahid's review of #1383, item 1): - - - one per region, holding every row whose carriers all live in it: the - local rows of both grains and the region's own rows, so a region row - less its published local rows, or a region's constituencies less its - local authorities, is caught (:func:`_region_blocks`); - - one per local family and its higher-grain parents, the targets the - cross-grain declarations or a nested measurement tie it to, so a - national or Great Britain row less a family's published cells is caught - too (:func:`_family_blocks`). - - A local row whose carriers span regions, or that has none, is checked in - its own grain and area. Local rows need the frame's household region, so - a frame without one refuses, and each local row needs its contract - target, which ties it to its family and parents, so a row without one - refuses too rather than join no family block (Vahid's third review of - #1383, item 33). :func:`uk_withheld_row_sets` runs the blocks until none - withholds a row another needs. - """ - - level = _row_level(geography_levels) - national: set[str] = set() - local: dict[tuple[str, str], set[str]] = {} - untied: list[str] = [] - for row in target_rows: - name = str(row["name"]) - grain = level(name) - if grain in UK_AREA_SUPPORT_LEVELS: - local.setdefault((grain, _row_area(row)), set()).add(name) - metadata = row.get("metadata") - if not ( - isinstance(metadata, Mapping) and metadata.get("contract_target_id") - ): - untied.append(name) - else: - national.add(name) - if untied: - raise ValueError( - "UK local rows are checked with their family's parents, matched by " - f"contract target, but {len(untied)} name none: {sorted(untied)[:5]}." - ) - blocks = [sorted(national)] if national else [] - if not local: - return blocks - if span is None or span.regions is None: - raise ValueError( - "UK local rows are checked against their regions' rows, so the " - "frame's household table needs a region column." - ) - placed: set[str] = set() - for block in _region_blocks(target_rows, level, span): - blocks.append(block) - placed.update(block) - for _, names in sorted(local.items()): - unplaced = names - placed - if unplaced: - blocks.append(sorted(unplaced)) - blocks.extend(_family_blocks(target_rows, level)) - return blocks - - -def _region_blocks( - target_rows: Sequence[Mapping[str, object]], - level: Any, - span: _CarrierSpan, -) -> list[list[str]]: - """Per region, every row whose positive-weight carriers all live in it. - - Local authorities and constituencies nest in regions, so a region's - block holds both local grains beside its own rows. A row whose carriers - span regions, or that has none, is in no region block. Only regions with - a local row form a block. - """ - - by_region: dict[str, set[str]] = {} - local_regions: set[str] = set() - names = [str(row["name"]) for row in target_rows] - for name, regions in zip(names, span.row_regions(names), strict=True): - if len(regions) != 1: - continue - (region,) = regions - by_region.setdefault(region, set()).add(name) - if level(name) in UK_AREA_SUPPORT_LEVELS: - local_regions.add(region) - return [sorted(by_region[region]) for region in sorted(local_regions)] - - -def _family_blocks( - target_rows: Sequence[Mapping[str, object]], - level: Any, -) -> list[list[str]]: - """Per local family with higher-grain parents, its rows and theirs. - - A family is the local targets the cross-grain declarations' partitions - or a nested measurement tie together (:func:`uk_local_family_parents`); - its parents are the higher-grain targets tied to it. A row is matched to - its target by ``metadata.contract_target_id``, which :func:`_row_blocks` - requires of every local row. A parent the build does not bind is not - published, so its absence needs no refusal. - """ - - by_target: dict[str, set[str]] = {} - for row in target_rows: - metadata = row.get("metadata") - if not isinstance(metadata, Mapping): - continue - target_id = metadata.get("contract_target_id") - if target_id: - by_target.setdefault(str(target_id), set()).add(str(row["name"])) - if not by_target: - return [] - blocks: list[list[str]] = [] - for members, parents in uk_local_family_parents(): - local = set().union(*(by_target.get(target, set()) for target in members)) - higher = set().union(*(by_target.get(target, set()) for target in parents)) - if not local or not higher: - continue - if not any(level(name) in UK_AREA_SUPPORT_LEVELS for name in local): - continue - blocks.append(sorted(local | higher)) - return blocks - - -@functools.cache -def uk_local_family_parents() -> tuple[tuple[frozenset[str], frozenset[str]], ...]: - """The local contract families and the higher-grain targets each is tied to. - - Two targets are tied when a cross-grain declaration joins them (a bridge, - a fan-out or sum bridge, a band bridge or a partition), or when they share - a concept, entity and mapping and one's filters hold the other's: then one - measures a population inside the other's, as the cross-grain coverage - check reads the contract (microcosm#802, #1123). Local targets tied to - each other form one family (the census households and their tenure - shares; the UC households and their children's bands); a family's - parents are the targets outside the local grains tied to any of them. - """ - - from microcosm.build.uk_runtime.cross_grain_declarations import ( - UK_LOCAL_GEOGRAPHY_LEVELS, - load_uk_cross_grain_declarations, - uk_cross_grain_bridges, - uk_cross_grain_partitions, - uk_fanout_sum_bridges, - ) - from microcosm.build.uk_runtime.ledger_targets import ( - uk_cross_grain_contract_signatures, - ) - - contract = uk_cross_grain_contract_signatures() - declarations = load_uk_cross_grain_declarations() - local = { - target_id - for target_id, target in contract.items() - if set(target.get("geography_levels") or ()) & UK_LOCAL_GEOGRAPHY_LEVELS - } - ties: dict[str, set[str]] = {} - - def tie(left: str, right: str) -> None: - if left != right: - ties.setdefault(left, set()).add(right) - ties.setdefault(right, set()).add(left) - - for bridge in uk_cross_grain_bridges(declarations): - for higher in bridge.higher_target_ids: - tie(higher, bridge.lower_side.removeprefix("contract:")) - for fanout in uk_fanout_sum_bridges(declarations): - tie(fanout.higher_target_id, fanout.lower_target_id) - for partition in uk_cross_grain_partitions(declarations): - for member in partition.member_target_ids: - tie(partition.parent_target_id, member) - for entry in declarations.get("band_bridges", ()): - for lower in entry["lower_target_ids"]: - tie(str(entry["higher_target_id"]), str(lower)) - for entry in declarations.get("sum_bridges", ()): - for higher in entry["higher_target_ids"]: - for lower in entry["lower_target_ids"]: - tie(str(higher), str(lower)) - by_measure: dict[tuple[object, ...], list[str]] = {} - for target_id, target in contract.items(): - measurement = target.get("measurement") or {} - key = ( - measurement.get("concept"), - measurement.get("entity"), - measurement.get("map_to"), - ) - by_measure.setdefault(key, []).append(target_id) - - def filters(target_id: str) -> frozenset[str]: - measurement = contract[target_id].get("measurement") or {} - return frozenset( - json.dumps(predicate, sort_keys=True) - for predicate in measurement.get("filters") or () - ) - - for target_ids in by_measure.values(): - for left in target_ids: - if left not in local: - continue - for right in target_ids: - if filters(left) <= filters(right) or filters(right) <= filters(left): - tie(left, right) - families: list[tuple[frozenset[str], frozenset[str]]] = [] - seen: set[str] = set() - for start in sorted(local): - if start in seen: - continue - family = {start} - frontier = [start] - while frontier: - for other in ties.get(frontier.pop(), ()): - if other in local and other not in family: - family.add(other) - frontier.append(other) - seen |= family - parents = set().union(*(ties.get(target, set()) for target in family)) - local - families.append((frozenset(family), frozenset(parents))) - return tuple(families) - - -@dataclass(frozen=True) -class _CarrierSpan: - """The problem's rows over its positive-weight households, sliced once.""" - - matrix: sparse.csr_matrix - sources: np.ndarray - index: Mapping[str, int] - level: Any - #: The positive-weight households' regions, where the frame carries them. - regions: np.ndarray | None = None - - @classmethod - def build( - cls, - problem: Any, - weights: Sequence[float] | np.ndarray, - frame: Frame, - geography_levels: Mapping[str, object] | None, - ) -> _CarrierSpan: - household = frame.table("household") - if "source_household_id" not in household.columns: - raise ValueError( - "UK diagnostics need household source_household_id to count each " - "row's carriers." - ) - sources = household["source_household_id"].to_numpy() - positive = np.asarray(weights, dtype=float) > 0 - if positive.shape != sources.shape: - raise ValueError("UK row carriers need one weight per household.") - matrix = sparse.csr_matrix( - sparse.csr_matrix(problem.matrix)[:, np.flatnonzero(positive)] - ) - matrix.eliminate_zeros() - regions = ( - household["region"].astype(str).to_numpy()[positive] - if "region" in household.columns - else None - ) - return cls( - matrix=matrix, - sources=sources[positive], - index={str(name): position for position, name in enumerate(problem.names)}, - level=_row_level(geography_levels), - regions=regions, - ) - - def row_regions(self, names: Sequence[str]) -> list[frozenset[str]]: - """The regions of each row's carriers (none for a row nobody carries).""" - - if self.regions is None: - raise ValueError("UK row regions need the frame's household region.") - found: list[frozenset[str]] = [] - for name in names: - if name not in self.index: - raise ValueError(f"UK target diagnostic {name!r} has no problem row.") - row = self.index[name] - start, stop = self.matrix.indptr[row], self.matrix.indptr[row + 1] - found.append(frozenset(self.regions[self.matrix.indices[start:stop]])) - return found - - def rows( - self, names: Sequence[str] - ) -> tuple[list[str], sparse.csr_matrix, np.ndarray, np.ndarray, np.ndarray]: - """One block's rows (stored zeros dropped: a household with a zero entry - does not carry the row), the households' source ids, each row's - distinct source households and each row's floor.""" - - names = list(names) - if not names: - empty = np.zeros(0) - return [], sparse.csr_matrix((0, 0)), empty, empty, empty - for name in names: - if name not in self.index: - raise ValueError(f"UK target diagnostic {name!r} has no problem row.") - matrix = sparse.csr_matrix(self.matrix[[self.index[name] for name in names]]) - carriers = np.array( - [ - len(pd.unique(self.sources[matrix.indices[start:stop]])) - for start, stop in zip( - matrix.indptr[:-1], matrix.indptr[1:], strict=True - ) - ] - ) - floors = np.array( - [ - UK_BRMA_DIAGNOSTIC_MIN_SOURCE_HOUSEHOLDS - if self.level(name) == "brma" - else UK_DIAGNOSTIC_MIN_SOURCE_HOUSEHOLDS - for name in names - ] - ) - return names, matrix, self.sources, carriers, floors - - -def uk_thin_rows( - problem: Any, - weights: Sequence[float] | np.ndarray, - frame: Frame, - target_rows: Sequence[Mapping[str, object]], - geography_levels: Mapping[str, object] | None = None, -) -> set[str]: - """The rows whose model figures rest on fewer than ten source households. - - Every row: María's rule of 2026-10-21 binds a row however few households - carry it, and keeps its figures in the build, as BRMA rows' have been - kept since her ruling of 2026-10-17; her ruling of 2026-10-23 extends the - withholding to constituency and local-authority rows, whose binding the - area-support rule still decides (``UK_AREA_SUPPORT_LEVELS``). ``problem`` is - the numerical problem the rows were scored on (its ``matrix`` and - ``names``) and ``weights`` the weights they were scored at. A row's - carriers are the distinct ``source_household_id`` values of the - positive-weight households with a nonzero entry in its problem row, as the - area support counts them. - """ - - if not target_rows: - return set() - span = _CarrierSpan.build(problem, weights, frame, geography_levels) - names, _, _, carriers, floors = span.rows([str(row["name"]) for row in target_rows]) - return { - name - for name, count, floor in zip(names, carriers, floors, strict=True) - if count < floor - } - - -def uk_withheld_row_sets( - problem: Any, - weights: Sequence[float] | np.ndarray, - frame: Frame, - target_rows: Sequence[Mapping[str, object]], - geography_levels: Mapping[str, object] | None = None, -) -> tuple[set[str], set[str]]: - """The thin rows (:func:`uk_thin_rows`) and the published rows withheld beside them. - - A published row's model figure is its problem row times the weights, so a - combination of withheld rows is given back exactly when its row lies in - the span of the published rows over the positive-weight households (a - family total less its published bands gives back the bands withheld). - María's hard rule (UKDS CD171 section 5.2.1): no difference of published - figures may isolate fewer than ten cases, and where a total would give a - withheld cell back, one more cell is withheld (Vahid's second review of - #1333, item 10). While the published rows give back a combination of - withheld rows that rests on fewer source households than its rows' floor, - the published row with the fewest carriers among those that give it back - is withheld too (the next-smallest band beside a thin one, not its total), - and the span is measured again. The span sees only combinations of - withheld rows, so a published total less some of its published parts, - which gives back whatever they leave out, is checked first and on every - pass (:class:`_ResidualCheck`; Vahid's second review of #1344, item 17): - the UC family total less its bound bands gives back the unbound band - above GBP 2,500 a month, which is no row and may rest on a handful of - households. What neither check sees is set out in :class:`_ResidualCheck`. - Both checks run per block (:func:`_row_blocks`; María's ruling of - 2026-10-23): the national, regional and BRMA rows together; on a local - surface, each region's rows of every grain, and each local family with - its higher-grain parents (Vahid's review of #1383, item 1), so a local - family total less its published local bands is caught, and so are a - region or national row less its published local cells and a region's - constituencies less its local authorities. The blocks overlap, so a row - one block withholds beside a thin one is protected in every other block - that holds it: there, any combination that holds it counts as too small - to give back. Blocks run again until none withholds another row, which - ends, since a row once withheld stays withheld. - """ - - if not target_rows: - return set(), set() - started = time.perf_counter() - span = _CarrierSpan.build(problem, weights, frame, geography_levels) - blocks = _row_blocks(target_rows, geography_levels, span) - block_rows = [span.rows(block) for block in blocks] - membership: dict[str, list[int]] = {} - for position, block in enumerate(blocks): - for name in block: - membership.setdefault(name, []).append(position) - thin: set[str] = set() - for names, _, _, carriers, floors in block_rows: - thin.update( - name - for name, count, floor in zip(names, carriers, floors, strict=True) - if count < floor - ) - # A thin row is thin in every block that holds it; a row withheld beside - # one belongs to the block that withheld it. - owners = {name: set(membership[name]) for name in thin} - withheld = set(thin) - checked: dict[int, frozenset[str]] = {} - pending = list(range(len(blocks))) - checks = 0 - while pending: - position = pending.pop(0) - names = block_rows[position][0] - held = frozenset(name for name in names if name in withheld) - if checked.get(position) == held: - continue - protected = frozenset(name for name in held if position not in owners[name]) - added = _withheld_in_block( - *block_rows[position], held=held, protected=protected - ) - checks += 1 - checked[position] = held | added - for name in added: - owners.setdefault(name, set()).add(position) - withheld.add(name) - for other in membership[name]: - if other != position and other not in pending: - pending.append(other) - if len(blocks) > 1: - # A local surface checks overlapping blocks, each a dense span; the - # build's log times it (Vahid's third review of #1383, item 32). - print( - f"UK withholding: {len(blocks)} blocks, {checks} block checks, " - f"{len(withheld)} rows withheld, {time.perf_counter() - started:.1f} s.", - file=sys.stderr, - ) - return thin, withheld - thin - - -def _withheld_in_block( - names: list[str], - matrix: sparse.csr_matrix, - sources: np.ndarray, - carriers: np.ndarray, - floors: np.ndarray, - *, - held: Collection[str] = frozenset(), - protected: Collection[str] = frozenset(), -) -> set[str]: - """The published rows one block withholds beside the rows already withheld. - - ``held`` rows are withheld already: the block's thin rows and the rows - other blocks withheld. A ``protected`` row is one another block withheld - beside a thin row of its own, so any combination that holds it counts as - resting on too few households: no published row of this block may give - it back, even within a sum this block would let stand. - """ - - thin = { - name - for name, count, floor in zip(names, carriers, floors, strict=True) - if count < floor - } - already = thin | set(held) - withheld = set(already) - recovery_floors = np.asarray(floors, dtype=np.int64).copy() - for position, name in enumerate(names): - if name in protected: - recovery_floors[position] = np.iinfo(np.int64).max - residuals = _ResidualCheck(matrix, sources, carriers, floors, names) - norms = np.sqrt(np.asarray(matrix.multiply(matrix).sum(axis=1)).ravel()) - unit = matrix - gram: np.ndarray | None = None - for _ in range(len(names) + 1): - # A total less some of its published parts gives back whatever they - # leave out, which need not be a row at all (Vahid's second review of - # #1344, item 17). A row the span check withholds can change the - # greedy groups of a total too large to search exactly, so the - # residuals are measured again on each pass. - residuals.withhold(withheld) - hidden = [i for i, name in enumerate(names) if name in withheld and norms[i]] - published = [ - i for i, name in enumerate(names) if name not in withheld and norms[i] - ] - if not hidden or not published: - break - if gram is None: - scale = np.divide(1.0, norms, out=np.zeros_like(norms), where=norms > 0) - unit = sparse.csr_matrix(sparse.diags(scale) @ matrix) - gram = (unit @ unit.T).toarray() - recovery = _small_recovery( - unit, gram, sources, hidden, published, recovery_floors - ) - if recovery is None: - break - coefficients, leverage = recovery - size = np.abs(coefficients) - givers = np.flatnonzero(size > _RECOVERY_ROUNDING * size.max()) - if not len(givers): - raise ValueError( - "UK diagnostics found a thin combination the published rows give " - "back but no published row that gives it." - ) - # A giver that no other published row can stand in for (it sits in no - # dependency among them) carries the same coefficient in every way of - # giving the combination back, so withholding it breaks them all. When - # every giver has a stand-in, two relations give the combination back, - # and withholding a giver breaks one of them. - essential = [j for j in givers if leverage[j] > 1 - _RECOVERY_TOLERANCE] - pick = min( - (published[j] for j in (essential or givers)), - key=lambda i: (carriers[i], names[i]), - ) - withheld.add(names[pick]) - return withheld - already - - -class _ResidualCheck: - """Withholds rows until no published total less some of its parts is thin. - - A total's parts are the other rows inside it: each one's households are - among the total's. A part's share is its entry over the total's, household - by household. Households whose parts all hold the same shares form an - atom: every combination of the total and its parts takes one value across - an atom, so its rest (the households where it is not nothing) is a union - of atoms. - - That gives a test first. An atom that rests on at least the total's - floor of source households can lie in no thin rest, so a thin combination - must vanish on every such atom. When every other atom's share column lies - within ``_SPAN_DISTANCE`` of the span of those atoms' columns - (:func:`_span_covers`), a combination with weights between minus one and - one that vanishes on them is within that distance of the total's entry - everywhere, and the total is clear (a UC family total over its payment - bands, a regional council-tax stock total over its bands, whenever each - cell rests on ten households or more). - - Where the test does not clear a total (amounts, whose households mostly - hold shares of their own), three kinds of combination are searched, each - the total less some of its parts: - - - less any set of members whose shares, summed, stay within one on every - atom (:meth:`_search` tries every such set, not only the largest). A - part whose share is the same on all its households (a count of children - beside the count of their households, a monthly band under a yearly - total) also stands as a part of share one. A member's shares lie above - nothing and at most one: a UC payment band within its family total, a - band holding half the entry of a household whose two benefit units sit - in two bands, an income component within a total-income band. A part of - whole numbers inside a total that is not, which holds the whole of the - total on none of its households, is likely a count beside an amount, - which multiplies the sets without partitioning anything, so the search - runs over the other members first and then over all of them; - - less any part on its own; - - less any two parts, which gives back, among other things, two - overlapping parts' overlap (claimants of either of two benefits less - the claimants of each). - - While a combination rests on one to nine source households (fewer than - the total's floor), the part with the fewest carriers among those it - subtracts is withheld, which adds that part's households to the rest, and - the check runs again. A total whose search passes its work or node cap, - or whose members times atoms pass ``_RESIDUAL_DENSE_LIMIT`` (the UK - population total, whose hundreds of person and household counts each - hold part of its entry), is searched over greedy groups of its members - instead, and a warning names it. Withholding a part only removes - combinations, so a total found clean stays clean; a greedily searched - total is searched again whenever one of its members is withheld. - - Not checked here: a total that is no row (a sum of published regions less - national bands), a part that reaches a household outside its total, and, - on a total the exact test does not clear, combinations at other weights - than these (three or more overlapping parts at once, for instance). - """ - - def __init__( - self, - matrix: sparse.csr_matrix, - sources: np.ndarray, - carriers: np.ndarray, - floors: np.ndarray, - names: list[str], - ) -> None: - self.carriers = np.asarray(carriers) - self.floors = np.asarray(floors) - self.names = names - matrix = sparse.csr_matrix(matrix, dtype=float) - self.matrix = matrix - self.size = np.diff(matrix.indptr) - # A missing source id counts as one source household of its own kind. - codes = np.asarray( - pd.factorize(pd.Series(np.asarray(sources)), use_na_sentinel=False)[0] - ) - self.codes = codes - support = sparse.csr_matrix( - (np.ones_like(matrix.data), matrix.indices, matrix.indptr), - shape=matrix.shape, - ) - overlap = (support @ support.T).toarray() - source_count = int(codes.max()) + 1 if len(codes) else 0 - owner = sparse.csr_matrix( - (np.ones(len(codes)), (np.arange(len(codes)), codes)), - shape=(len(codes), source_count), - ) - row_sources = sparse.csr_matrix(support @ owner) - row_sources.data[:] = 1.0 - #: Distinct source households two rows share. - self.shared_sources = (row_sources @ row_sources.T).toarray() - #: Per total: its parts' rows, their shares over its households (a row - #: may stand twice, as itself and scaled to share one), which parts - #: are members, and which are counts beside an amount. - self.parts: dict[ - int, tuple[np.ndarray, sparse.csr_matrix, np.ndarray, np.ndarray] - ] = {} - for total in np.flatnonzero(self.size): - inside = np.flatnonzero(overlap[:, total] == self.size) - inside = inside[(inside != total) & (self.size[inside] > 0)] - if not len(inside): - continue - start, stop = matrix.indptr[total], matrix.indptr[total + 1] - columns = matrix.indices[start:stop] - position = np.full(matrix.shape[1], -1) - position[columns] = np.arange(len(columns)) - block = sparse.csr_matrix(matrix[inside]) - local = position[block.indices] - share = sparse.csr_matrix( - (block.data / matrix.data[start:stop][local], local, block.indptr), - shape=(len(inside), len(columns)), - ) - starts = share.indptr[:-1] - low = np.minimum.reduceat(share.data, starts) - high = np.maximum.reduceat(share.data, starts) - whole_share = ( - np.add.reduceat( - (np.abs(share.data - 1) <= _RECOVERY_ROUNDING).astype(int), starts - ) - > 0 - ) - constant = (low * high > 0) & ( - np.abs(high - low) <= _RECOVERY_ROUNDING * np.abs(high) - ) - scaled = constant & (np.abs(high - 1) > _RECOVERY_ROUNDING) - counts = _whole_entries(block) & ~whole_share - if _whole_entries(matrix[total]).all(): - counts[:] = False - rows, shares = [inside], [share] - if scaled.any(): - ones = sparse.csr_matrix(share[scaled]) - ones.data = np.ones_like(ones.data) - rows.append(inside[scaled]) - shares.append(ones) - extra = int(scaled.sum()) - low = np.concatenate([low, np.ones(extra)]) - high = np.concatenate([high, np.ones(extra)]) - counts = np.concatenate([counts, np.zeros(extra, dtype=bool)]) - member = (low > 0) & (high <= 1 + _RECOVERY_ROUNDING) - self.parts[int(total)] = ( - np.concatenate(rows), - sparse.csr_matrix(sparse.vstack(shares)), - member, - counts, - ) - self._clean: set[int] = set() - #: Totals searched greedily: the live members their groups were last - #: searched over, and whether their single and paired parts are clean. - self._greedy_members: dict[int, bytes] = {} - self._parts_clean: set[int] = set() - #: Totals the span test did not clear (not tried again). - self._uncertified: set[int] = set() - self.capped: set[str] = set() - - def withhold(self, withheld: set[str]) -> None: - """Add to ``withheld`` until no published total's rest is thin.""" - - for _ in range(len(self.names) + 1): - pick = self._first_thin_rest(withheld) - if pick is None: - return - withheld.add(self.names[pick]) - - def _first_thin_rest(self, withheld: set[str]) -> int | None: - for total, (rows, _, member, _) in self.parts.items(): - if total in self._clean or self.names[total] in withheld: - continue - live = np.array([self.names[row] not in withheld for row in rows]) - if ( - total in self._parts_clean - and self._greedy_members.get(total) == (live & member).tobytes() - ): - continue - pick = self._thin_rest(total, live) - if pick is not None: - return pick - if self.names[total] in self.capped: - self._greedy_members[total] = (live & member).tobytes() - self._parts_clean.add(total) - else: - self._clean.add(total) - return None - - def _thin_rest(self, total: int, live: np.ndarray) -> int | None: - """The row to withhold so this total's rests stop being thin, or ``None``.""" - - all_rows, all_share, all_member, all_counts = self.parts[total] - rows = all_rows[live] - if not len(rows): - return None - share = sparse.csr_matrix(all_share[np.flatnonzero(live)]) - member = all_member[live] - counts = all_counts[live] - floor = int(self.floors[total]) - start, stop = self.matrix.indptr[total], self.matrix.indptr[total + 1] - _, local_codes = np.unique( - self.codes[self.matrix.indices[start:stop]], return_inverse=True - ) - atom, first = _share_atoms(share) - atom_sources = sparse.csr_matrix( - (np.ones(len(atom)), (atom, local_codes.ravel())), - shape=(len(first), int(local_codes.max()) + 1), - ) - atom_sources.sum_duplicates() - atom_sources.data[:] = 1.0 - atom_count = np.diff(atom_sources.indptr) - small = atom_count < floor - if not small.any(): - return None - atom_share = sparse.csr_matrix(share[:, first]) - name = self.names[total] - if total not in self._uncertified: - if _span_covers(atom_share, ~small): - return None - self._uncertified.add(total) - spent = [0] - - def carried(rest: np.ndarray) -> int: - """The rest's distinct source households, or ``floor`` once it has that many.""" - - atoms = np.flatnonzero(rest) - if not len(atoms): - return 0 - if atom_count[atoms].max() >= floor: - return floor - # Callers only compare the count with ``floor``, so a first slice - # of the rest that already reaches it settles the answer. - for chunk in (atoms[: 4 * floor], atoms): - selected = atom_sources[chunk] - spent[0] += selected.nnz + len(chunk) - count = len(np.unique(selected.indices)) - if count >= floor or len(chunk) == len(atoms): - return min(count, floor) - return floor - - def fewest(indices) -> int: - return min( - (int(rows[i]) for i in indices), - key=lambda row: (self.carriers[row], self.names[row]), - ) - - if name not in self.capped: - # The members bar the counts beside an amount first, which the - # search can finish where the counts would multiply its sets; - # then every member, with a fresh budget. - phases = [member & ~counts, member] if (member & counts).any() else [member] - for chosen in phases: - spent[0] = 0 - found = self._search( - atom_share, chosen, carried, floor, rows, small, spent - ) - if found is _CAPPED: - self._cap(name) - break - if found is not None: - return fewest(found) - if name in self.capped: - found = self._greedy(atom_share, member, carried, floor) - if found is not None: - return fewest(found) - if total in self._parts_clean: - return None - # One part on its own, and two parts together: shares at any value. - # A part (or pair) that leaves at least ``floor`` of the total's - # source households untouched leaves a rest of at least ``floor``. - uncovered = self.carriers[total] - self.carriers[rows] - alone = ~member | (name in self.capped) - for i in np.flatnonzero(alone & (uncovered < floor)): - row = atom_share[i].toarray().ravel() - count = carried(_unsettled(row)) - if 0 < count < floor: - return fewest([i]) - bound = ( - self.carriers[total] - - self.carriers[rows][:, None] - - self.carriers[rows][None, :] - + self.shared_sources[np.ix_(rows, rows)] - ) - for i, j in np.argwhere(np.triu(bound < floor, k=1)): - if rows[i] == rows[j]: - continue - pair = (atom_share[i] + atom_share[j]).toarray().ravel() - count = carried(_unsettled(pair)) - if 0 < count < floor: - return fewest([i, j]) - return None - - def _cap(self, name: str) -> None: - self.capped.add(name) - warnings.warn( - f"UK diagnostics: the residual search for {name} passed its cap, " - "so its members are grouped greedily.", - stacklevel=3, - ) - - def _search( - self, - atom_share: sparse.csr_matrix, - member: np.ndarray, - carried: Any, - floor: int, - rows: np.ndarray, - small: np.ndarray, - spent: list[int], - ) -> object: - """A set of members whose total less them is thin: branch and bound. - - Members join largest first while their shares, summed, stay within one - on every atom. Every set is tested, since a smaller set can leave a - thin rest that a larger one covers. A branch stops when its rest is - nothing, when every atom its rest could keep rests on at least - ``floor`` source households (a thin rest is a union of smaller - atoms), or when even every member it could still take leaves an atom - of that size uncovered. Returns the set's member indices, ``None``, or - ``_CAPPED`` past the work or node cap or the dense limit. - """ - - order = sorted( - np.flatnonzero(member).tolist(), - key=lambda i: (-int(self.size[rows[i]]), self.names[rows[i]]), - ) - if not order: - return None - atoms = atom_share.shape[1] - limit = 1 + _RECOVERY_ROUNDING - below = 1 - _RECOVERY_ROUNDING - # The bound errs toward searching on: reach comes from sums that can - # drift by a few ulps, so an atom counts as stranded only clearly so. - stranded_below = below - 1e-9 - big = ~small - # The root's bound, from sparse sums, before any dense block is made. - everything = np.asarray(atom_share[order].sum(axis=0)).ravel() - stranded = everything < stranded_below - if (stranded & big).any() or carried(stranded) >= floor: - return None - if len(order) * atoms > _RESIDUAL_DENSE_LIMIT: - return _CAPPED - dense = np.asarray(atom_share[order].todense()) - nodes = 0 - # Depth-first, one frame per chosen set: (chosen, summed, candidate - # positions into ``order``, next candidate to try, reach). ``reach`` - # is the summed shares with every candidate from the next one on, so - # the atoms it leaves under one stay uncovered whatever else joins. - stack: list[tuple[list[int], np.ndarray, list[int], int, np.ndarray]] = [ - ([], np.zeros(atoms), list(range(len(order))), 0, everything) - ] - while stack: - chosen, summed, candidates, k, reach = stack.pop() - if k == 0: - nodes += 1 - spent[0] += (len(candidates) + 1) * atoms - if nodes > _RESIDUAL_SEARCH_NODES or spent[0] > _RESIDUAL_SEARCH_WORK: - return _CAPPED - uncovered = summed < below - if not uncovered.any(): - continue - if not (uncovered & small).any(): - continue # every rest below here keeps an atom of floor size - count = carried(uncovered) - if chosen and 0 < count < floor: - return [order[i] for i in chosen] - if k >= len(candidates): - continue - stranded = reach < stranded_below - if (stranded & big).any() or carried(stranded) >= floor: - continue - head = candidates[k] - stack.append((chosen, summed, candidates, k + 1, reach - dense[head])) - joined = summed + dense[head] - if (joined > limit).any(): - continue - tail = candidates[k + 1 :] - if tail: - spent[0] += len(tail) * atoms - over = (joined + dense[tail] > limit).any(axis=1) - tail = [c for c, bad in zip(tail, over, strict=True) if not bad] - reach_after = joined + dense[tail].sum(axis=0) if tail else joined.copy() - stack.append(([*chosen, head], joined, tail, 0, reach_after)) - return None - - def _greedy( - self, - atom_share: sparse.csr_matrix, - member: np.ndarray, - carried: Any, - floor: int, - ) -> list[int] | None: - """A greedy group of members whose total less them is thin, or ``None``. - - For a total the exact search cannot finish. Each member seeds two - groups, which take the others that clash with none already in them, - once largest first and once those clashing with fewest others first. - A group's rest is wherever its shares do not sum to one, so a group - that passes one somewhere is still measured. - """ - - members = np.flatnonzero(member) - if not len(members): - return None - share = sparse.csr_matrix(atom_share[members]) - support = share.copy() - support.data = np.ones_like(support.data) - clash = (support @ support.T).toarray() > 0 - high = share.copy() - high.data = (high.data > 0.5 + _RECOVERY_ROUNDING).astype(float) - high.eliminate_zeros() - sure = (high @ high.T).toarray() > 0 - np.fill_diagonal(clash, False) - csc = share.tocsc() - for a in range(len(members)): - doubt = np.flatnonzero(clash[a] & ~sure[a]) - doubt = doubt[doubt > a] - if not len(doubt): - continue - # Two members clash where both hold a share and the two pass one. - columns = share.indices[share.indptr[a] : share.indptr[a + 1]] - values = share.data[share.indptr[a] : share.indptr[a + 1]] - block = sparse.csr_matrix(csc[:, columns][doubt]) - hit = block.data + values[block.indices] > 1 + _RECOVERY_ROUNDING - row_of = np.repeat(np.arange(len(doubt)), np.diff(block.indptr)) - over = np.zeros(len(doubt), dtype=bool) - over[np.unique(row_of[hit])] = True - clash[a, doubt] = clash[doubt, a] = over - size = np.diff(share.indptr) - orders = ( - sorted(range(len(members)), key=lambda i: (-size[i], i)), - sorted( - range(len(members)), - key=lambda i: (int(clash[i].sum()), -size[i], i), - ), - ) - tried: set[frozenset[int]] = set() - for order in orders: - for seed in order: - chosen = [seed] - blocked = clash[seed].copy() - for other in order: - if other != seed and not blocked[other]: - chosen.append(other) - blocked |= clash[other] - key = frozenset(chosen) - if key in tried: - continue - tried.add(key) - group = sorted(chosen) - summed = np.asarray(share[group].sum(axis=0)).ravel() - count = carried(_unsettled(summed)) - if 0 < count < floor: - return members[group].tolist() - return None - - -#: How far a small atom's share column may lie from the span of the big -#: atoms' columns, both as a unit column and summed over its entries as -#: stored (where the total's share is one), for the span test to clear its -#: total. A tenth of the rounding share, fixed: it does not grow with atoms -#: or parts. -_SPAN_DISTANCE = 0.1 * _RECOVERY_ROUNDING -#: Big-atom directions weaker than this share of the strongest singular value -#: are left out of the span, as the search counts a big atom held within the -#: rounding share of one as covered. Leaving directions out only shrinks the -#: span. -_SPAN_WEAK = 10 * _RECOVERY_ROUNDING - - -def _span_covers(atom_share: sparse.csr_matrix, big: np.ndarray) -> bool: - """Whether the big atoms' share columns, with the total's, span every atom's. - - Each atom's column is the total's share (one) over the parts' shares. A - combination of the total and its parts that vanishes on every big atom - vanishes on every atom when the big columns span them all. Measured - directly, not through ranks: with the span taken from the big atoms' unit - columns by their singular vectors, every small atom's column must lie - within ``_SPAN_DISTANCE`` of it, as a unit column (on the shares as they - are, and with each row scaled to its largest share, so a part of tiny - shares beside one of large shares is not lost) and summed over its stored - entries (so a combination with weights between minus one and one, as - every searched one has, that vanishes on the big atoms is within that - distance of the total's entry on every small atom, whatever the atom's - largest share or the number of parts). Only all three together clear it. - """ - - if not big.any(): - return False - count = atom_share.shape[1] - rows = sparse.vstack( - [sparse.csr_matrix(np.ones((1, count))), sparse.csr_matrix(atom_share)] - ).tocsr() - peak = np.maximum.reduceat(np.abs(rows.data), rows.indptr[:-1]) - scaled = sparse.csr_matrix(sparse.diags(1.0 / peak) @ rows) - return _within_span(rows, big, stored=True) and _within_span(scaled, big) - - -def _within_span( - rows: sparse.csr_matrix, big: np.ndarray, *, stored: bool = False -) -> bool: - """Whether every small atom's column lies within ``_SPAN_DISTANCE`` of the - big atoms' span: as a unit column, and with ``stored`` also summed over its - entries as they are in ``rows``.""" - - if rows.shape[0] * int(big.sum()) > _RESIDUAL_DENSE_LIMIT: - return False # too large to factor here; the search decides instead - norms = np.sqrt(np.asarray(rows.multiply(rows).sum(axis=0)).ravel()) - unit = sparse.csr_matrix(rows @ sparse.diags(1.0 / norms)).tocsc() - block = unit[:, np.flatnonzero(big)].toarray() - # Singular values reveal a weak direction that pivoted QR's diagonal can - # miss on a graded block. - vectors, strength, _ = scipy_linalg.svd(block, full_matrices=False) - if not len(strength) or strength[0] <= 0: - return False - basis = vectors[:, strength > _SPAN_WEAK * strength[0]] - small = np.flatnonzero(~big) - for start in range(0, len(small), 4096): - chunk = small[start : start + 4096] - columns = unit[:, chunk].toarray() - rest = columns - basis @ (basis.T @ columns) - if (np.linalg.norm(rest, axis=0) > _SPAN_DISTANCE).any(): - return False - if stored and (np.abs(rest).sum(axis=0) * norms[chunk] > _SPAN_DISTANCE).any(): - return False - return True - - -def _whole_entries(rows: sparse.csr_matrix) -> np.ndarray: - """Whether each row's entries are all whole numbers (a count).""" - - rows = sparse.csr_matrix(rows) - if not rows.shape[0]: - return np.zeros(0, dtype=bool) - whole = np.abs(rows.data - np.round(rows.data)) <= _RECOVERY_ROUNDING - off = ( - np.add.reduceat((~whole).astype(int), rows.indptr[:-1]) if len(rows.data) else 0 - ) - filled = np.diff(rows.indptr) > 0 - return filled & (np.asarray(off) == 0) - - -def _unsettled(summed: np.ndarray) -> np.ndarray: - """Where a total less parts summing to ``summed`` is not nothing. - - One rule for every check, the search's own: a share within the rounding - share of one, either side, counts as covered. A convention, at the exact - tie: there a rest can lose a household. - """ - - return (summed < 1 - _RECOVERY_ROUNDING) | (summed > 1 + _RECOVERY_ROUNDING) - - -#: What :meth:`_ResidualCheck._search` returns past its caps. -_CAPPED = object() - - -def _share_atoms(share: sparse.csr_matrix) -> tuple[np.ndarray, np.ndarray]: - """Group a total's households by the shares its parts hold in them. - - Returns each household's atom and, per atom, one household standing for - it. Each household's column of shares is hashed exactly: every (part, - share) entry, with the share's lowest twelve mantissa bits dropped so - float noise does not split a column, goes through two 64-bit mixers, and - a column's keys are their wrapping sums with its entry count. Two - households share an atom only when their columns agree entry for entry - to within the dropped bits (about 1e-12 of each share), barring a - collision of both 64-bit sums; a share on the edge of the dropped bits - can split an atom, which only costs time. - """ - - count = share.shape[1] - if not count: - return np.zeros(0, dtype=np.int64), np.zeros(0, dtype=np.int64) - csc = sparse.csc_matrix(share) - csc.sort_indices() - filled = np.diff(csc.indptr) - column = np.repeat(np.arange(count), filled) - bits = np.ascontiguousarray(csc.data, dtype=np.float64).view(np.uint64) - bits = bits & ~np.uint64(0xFFF) - part = csc.indices.astype(np.uint64) - keys = [] - with np.errstate(over="ignore"): - for salt in (np.uint64(0x9E3779B97F4A7C15), np.uint64(0xD1B54A32D192ED03)): - entry = _mix64(_mix64(part * salt + np.uint64(1)) ^ bits) - total = np.zeros(count, dtype=np.uint64) - np.add.at(total, column, entry) - keys.append(total) - table = np.column_stack([filled.astype(np.uint64), *keys]) - _, first, atom = np.unique(table, axis=0, return_index=True, return_inverse=True) - return atom.ravel(), first - - -def _mix64(values: np.ndarray) -> np.ndarray: - """SplitMix64's finaliser, elementwise on unsigned 64-bit integers.""" - - with np.errstate(over="ignore"): - values = values + np.uint64(0x9E3779B97F4A7C15) - values = (values ^ (values >> np.uint64(30))) * np.uint64(0xBF58476D1CE4E5B9) - values = (values ^ (values >> np.uint64(27))) * np.uint64(0x94D049BB133111EB) - return values ^ (values >> np.uint64(31)) - - -def _small_recovery( - unit: sparse.csr_matrix, - gram: np.ndarray, - sources: np.ndarray, - held: list[int], - published: list[int], - floors: np.ndarray, -) -> tuple[np.ndarray, np.ndarray] | None: - """How the published rows give back a too-small combination of held rows. - - ``unit`` holds the unit-normed rows and ``gram`` their inner products. A - combination of the held rows is given back when what is left of it off - the published rows' span is a negligible share of it (its squared norm - under ``_RECOVERY_TOLERANCE`` of the combination's own). Each held row is - tried alone first (a total less its published bands gives one back); then - the combinations, from the generalized eigenvectors of that remainder - against the combination's own size, so that two proportional held rows, - whose difference is nothing, give nothing back. The first combination - that rests on fewer distinct source households than the highest floor - among its rows returns the minimum-norm published coefficients that give - it back, and each published row's leverage (1 when no other published row - can stand in for it); ``None`` when there is none. - """ - - epsilon = np.finfo(float).eps - values, vectors = np.linalg.eigh(gram[np.ix_(published, published)]) - keep = values > values.max() * len(values) * epsilon - values, vectors = values[keep], vectors[:, keep] - cross = gram[np.ix_(published, held)] - reach = (vectors.T @ cross) / np.sqrt(values)[:, None] - own = gram[np.ix_(held, held)] - remainder = own - reach.T @ reach - - def rests_below_floor(alpha: np.ndarray) -> bool: - rows = np.flatnonzero(alpha) - combination = np.asarray(unit[[held[i] for i in rows]].T @ alpha[rows]).ravel() - size = np.abs(combination) - if not size.any(): - return False - support = size > _RECOVERY_ROUNDING * size.max() - floor = max(int(floors[held[i]]) for i in rows) - return len(pd.unique(sources[support])) < floor - - def found(alpha: np.ndarray) -> tuple[np.ndarray, np.ndarray]: - coefficients = vectors @ ((vectors.T @ (cross @ alpha)) / values) - return coefficients, np.sum(vectors**2, axis=1) - - for row in np.flatnonzero(np.diag(remainder) < _RECOVERY_TOLERANCE): - alpha = np.zeros(len(held)) - alpha[row] = 1.0 - if rests_below_floor(alpha): - return found(alpha) - own_values, own_vectors = np.linalg.eigh(own) - nonzero = own_values > own_values.max() * len(own_values) * epsilon - lift = own_vectors[:, nonzero] / np.sqrt(own_values[nonzero]) - share = lift.T @ remainder @ lift - share_values, share_vectors = np.linalg.eigh((share + share.T) / 2) - given_back = lift @ share_vectors[:, share_values < _RECOVERY_TOLERANCE] - for alpha in _reduced_basis(given_back): - if rests_below_floor(alpha): - return found(alpha) - return None - - -def _reduced_basis(basis: np.ndarray) -> list[np.ndarray]: - """The reduced row echelon basis of a span given by its columns. - - A vector in the span is fixed by its entries on the pivots, so separate - relations come out as separate vectors. Each column is scaled to a largest - entry of one first, so the rounding share means the same for all. - """ - - reduced = basis.T.copy() - largest = np.abs(reduced).max(axis=1, initial=0.0) - reduced = reduced[largest > 0] / largest[largest > 0, None] - pivot = 0 - for column in range(reduced.shape[1]): - if pivot == reduced.shape[0]: - break - best = pivot + int(np.argmax(np.abs(reduced[pivot:, column]))) - if abs(reduced[best, column]) < _RECOVERY_ROUNDING: - continue - reduced[[pivot, best]] = reduced[[best, pivot]] - reduced[pivot] /= reduced[pivot, column] - for other in range(reduced.shape[0]): - if other != pivot: - reduced[other] -= reduced[other, column] * reduced[pivot] - pivot += 1 - reduced[np.abs(reduced) < _RECOVERY_ROUNDING] = 0.0 - return [vector for vector in reduced[:pivot] if vector.any()] - - -def uk_withheld_rows( - problem: Any, - weights: Sequence[float] | np.ndarray, - frame: Frame, - target_rows: Sequence[Mapping[str, object]], - geography_levels: Mapping[str, object] | None = None, -) -> set[str]: - """Every row whose model figures stay in the build: :func:`uk_withheld_row_sets`.""" - - thin, complementary = uk_withheld_row_sets( - problem, weights, frame, target_rows, geography_levels - ) - return thin | complementary - - -def uk_withheld_brma_rows( - problem: Any, - weights: Sequence[float] | np.ndarray, - frame: Frame, - target_rows: Sequence[Mapping[str, object]], - geography_levels: Mapping[str, str], -) -> set[str]: - """The BRMA rows among :func:`uk_thin_rows` (their ``carrier_floor_met`` flag).""" - - brma = [ - row for row in target_rows if geography_levels.get(str(row["name"])) == "brma" - ] - return ( - uk_thin_rows(problem, weights, frame, brma, geography_levels) if brma else set() - ) - - -def uk_withheld_flag(value: object) -> bool: - """Whether a row's ``model_figures_withheld`` flag is set (a true bool).""" - - return isinstance(value, (bool, np.bool_)) and bool(value) - - -def uk_withheld_gate_keys(rows: object) -> frozenset[str]: - """The local gate keys (``family/area_code/metric``) of withheld rows.""" - - records = rows.to_dict(orient="records") if hasattr(rows, "to_dict") else rows - return frozenset( - f"{str(row.get('family', '')).strip()}/" - f"{str(row.get('area_code', '')).strip()}/" - f"{str(row.get('metric', '')).strip()}" - for row in records or () - if isinstance(row, Mapping) - and uk_withheld_flag(row.get("model_figures_withheld")) - ) - - -def uk_withheld_gate_areas(rows: object) -> frozenset[str]: - """The bare area codes of withheld BRMA rows, for the report guard. - - One family binds per BRMA, so a BRMA's area code names its row. A - constituency or local authority binds many families, so its code names - published rows too, and its withheld rows are matched by their keys alone - (María's ruling of 2026-10-23 on the local line). - """ - - records = rows.to_dict(orient="records") if hasattr(rows, "to_dict") else rows - return frozenset( - str(row.get("area_code", "")).strip() - for row in records or () - if isinstance(row, Mapping) - and uk_withheld_flag(row.get("model_figures_withheld")) - and _GEOGRAPHY_LEVEL_ALIASES.get( - str(row.get("geography_level", "")).strip().lower(), - str(row.get("geography_level", "")).strip().lower(), - ) - == "brma" - and str(row.get("area_code", "")).strip() - ) - - -def uk_withhold_brma_figures( - rows: Sequence[Mapping[str, object]], - withheld: frozenset[str], - *, - fields: Sequence[str] = ("estimate", "relative_error", "abs_relative_error"), -) -> list[dict[str, object]]: - """Copies of written target rows with a withheld row's model figures blank. - - While any row is withheld every row carries ``model_figures_withheld``, a - bool, so a reader of the written table tells a withheld row from a - missing figure. - """ - - out = [] - for row in rows: - copy = dict(row) - hidden = str(copy.get("name")) in withheld - if hidden: - for field in fields: - if field in copy: - copy[field] = None - if withheld: - copy["model_figures_withheld"] = hidden - else: - copy.pop("model_figures_withheld", None) - out.append(copy) - return out - - -#: The guard's one message (the fourth review of #1305). A failed receipt -#: keeps an exception's message and the emitter sends it on, so it names no -#: place: a report path can carry the withheld row's key, and beside the -#: public register, its status. -UK_WITHHELD_ROW_NAMED_MESSAGE = ( - "The gate report names a withheld row; the build's local stderr says where." -) - - -class UKWithheldRowNamedError(ValueError): - """A written gate report names a withheld row (microcosm#1262).""" - - def __init__(self) -> None: - super().__init__(UK_WITHHELD_ROW_NAMED_MESSAGE) - - -def uk_refuse_named_withheld_rows( - payload: object, - *, - names: frozenset[str], - keys: frozenset[str], - areas: frozenset[str] = frozenset(), -) -> None: - """Fail closed if a written gate report names a withheld row at all. - - María's ruling of 2026-10-19 on the third review of #1305: the fit gates - decide on the published rows and count the withheld ones, so no gate has - a reason to name one, and a name beside a figure or a verdict would give - the row back. A withheld row's name, gate key or area code, in any case, - in any key or string of the report, stops the build before the report - leaves it. The error's message is constant; the place goes to this - machine's stderr only. - - It matches literal text: each withheld row's name and gate key, and the - bare area codes in ``areas``, which are those of withheld BRMA rows only - (:func:`uk_withheld_gate_areas`). One family is bound per BRMA, so its - code names its row; a constituency or local authority binds many, so a - withheld local row is matched by its key and a published row of the same - area may be named (María's ruling of 2026-10-23 on the local line). - """ - - labels = {label.casefold() for label in (*names, *keys, *areas) if label} - if not labels: - return - - def check(text: str, path: str) -> None: - folded = text.casefold() - if any(label in folded for label in labels): - print(f"error: {path} names a withheld row.", file=sys.stderr) - raise UKWithheldRowNamedError - - def walk(value: object, path: str) -> None: - if isinstance(value, Mapping): - for key, item in value.items(): - check(str(key), f"{path}.{key}") - walk(item, f"{path}.{key}") - elif isinstance(value, (list, tuple)): - for position, item in enumerate(value): - walk(item, f"{path}[{position}]") - elif isinstance(value, str): - check(value, path) - - walk(payload, "report") - - -_WITHHELD_TOTALS_NOTE = ( - "A target row resting on fewer than ten distinct source households keeps " - "its place without its model figures, and so does a row that, with the " - "published rows, would give such a row back. initial_loss, final_loss, " - "fraction_within_10pct and past_cap_census are restated over the published " - "rows, on the solve's own loss weights, scales and cap (initial_loss at the " - "input weights, the rows' initial estimates); loss_trajectory, the solve's " - "path over every row, is empty, and options keep their settings only." -) - - -def _restate_totals_over_published_rows( - payload: dict[str, object], - result: CalibrationResult, - withheld: frozenset[str], -) -> dict[str, object]: - """Restate the payload's totals over the published rows (microcosm#1262). - - María's ruling of 2026-10-18 on the #1305 re-review: a total over every - row would give a withheld row back by difference against the published - rows' contributions. The final loss becomes the published rows' summed - contributions (each a share of the solve's whole loss weight, as the rows - record them), the initial loss the same at the input weights, and the - fraction within 10% and the past-cap census count the published rows - only. The loss trajectory cannot be restated and is emptied. Returns the - ``uk_diagnostics`` block that labels the basis. - """ - - rows = list(result.diagnostics) - kept = [index for index, row in enumerate(rows) if str(row.name) not in withheld] - - def published_loss(estimates: Sequence[float]) -> float | None: - try: - weights = np.asarray(result.target_loss_weights, dtype=float) - scales = np.asarray(result.target_loss_scales, dtype=float) - cap = float(result.target_loss_cap) - except (AttributeError, TypeError, ValueError): - return None - if ( - weights.shape != (len(rows),) - or scales.shape != (len(rows),) - or not np.isfinite(weights).all() - or not np.isfinite(scales).all() - or (scales <= 0).any() - or not weights.sum() > 0 - or not math.isfinite(cap) - ): - return None - shares = weights / weights.sum() - terms = [] - for index in kept: - target, estimate = float(rows[index].target), float(estimates[index]) - if not (math.isfinite(target) and math.isfinite(estimate)): - return None - terms.append( - float(shares[index]) - * min(abs(estimate - target) / float(scales[index]), cap) - ) - return math.fsum(terms) - - payload["initial_loss"] = published_loss([row.initial_estimate for row in rows]) - payload["final_loss"] = published_loss([row.final_estimate for row in rows]) - payload["fraction_within_10pct"] = ( - sum(abs(float(rows[index].relative_error)) <= 0.10 for index in kept) - / len(kept) - if kept - else None - ) - payload["loss_trajectory"] = [] - payload["options"] = uk_published_options(dict(payload.get("options") or {})) - payload["past_cap_census"] = past_cap_census( - SimpleNamespace( - options=getattr(result, "options", None), - diagnostics=[rows[index] for index in kept], - ) - ) - return { - "targets": len(withheld), - "min_source_households": UK_DIAGNOSTIC_MIN_SOURCE_HOUSEHOLDS, - "totals_basis": "published_rows", - "note": _WITHHELD_TOTALS_NOTE, - } - - -def uk_published_row_losses( - result: CalibrationResult, withheld: frozenset[str] -) -> tuple[float | None, float | None]: - """The initial and final loss over the published rows (microcosm#1262). - - For a manifest that would otherwise carry the solve's loss over every row, - which against the published rows' contributions gives a withheld row back - (María's ruling of 2026-10-18); ``None`` where the result cannot restate. - """ - - totals: dict[str, object] = {} - _restate_totals_over_published_rows(totals, result, frozenset(withheld)) - return totals["initial_loss"], totals["final_loss"] - - -def uk_published_options(options: Mapping[str, object]) -> dict[str, object]: - """A payload's solve options while any row is withheld (microcosm#1262). - - The third review of #1305: the solve keeps its best iterate's loss over - every row in ``iterate_selection_receipt``, and that loss less the - restated final loss gives the withheld rows' contribution back. Settings - on the allow-list stay; every other option, and the receipt's two - iterate losses, read null. - """ - - published: dict[str, object] = {} - for key, value in options.items(): - if key in UK_WITHHELD_PUBLISHED_OPTIONS: - published[key] = value - elif key == "iterate_selection_receipt" and isinstance(value, Mapping): - published[key] = { - field: (item if field in UK_WITHHELD_PUBLISHED_ITERATE_FIELDS else None) - for field, item in value.items() - } - else: - published[key] = None - return published - - def _target_pass_rates( target_rows: list[dict[str, object]], skipped_names: Sequence[str], geography_levels: Mapping[str, str], - withheld: frozenset[str] = frozenset(), ) -> list[dict[str, object]]: counts = { level: { @@ -2660,11 +1083,6 @@ def _target_pass_rates( for row in target_rows: name = str(row["name"]) level = geography_levels[name] - if name in withheld: - # Scored, never counted as passing: its outcome stays unknowable. - counts[level]["n_targets"] += 1 - counts[level]["n_scored"] += 1 - continue raw_error = row.get("relative_error") if not isinstance(raw_error, (int, float)) or isinstance(raw_error, bool): raise ValueError( @@ -2711,7 +1129,6 @@ def uk_calibration_diagnostics_payload( build: dict[str, Any] | None = None, local_area_support: pd.DataFrame | None = None, rotated_holdout: Mapping[str, object] | None = None, - withheld: Collection[str] | None = None, ) -> dict[str, object]: """Render shared diagnostics plus the versioned UK release evidence. @@ -2719,9 +1136,9 @@ def uk_calibration_diagnostics_payload( names are never parsed to guess their geography, and a missing, stale, or unknown mapping aborts instead of silently shrinking a scoreboard level. - ``withheld`` names the rows whose model figures stay in the build - (:func:`uk_withheld_rows`); the gate kernel passes the set its gate - evidence carries, and by default it is counted here on the same rule. + Every row carries its model figures, however few source households carry + it: the diagnostics ship only to the licensed private repository (María's + ruling of 2026-10-26, which dropped the withholding of microcosm#1262). """ registry = _require_uk_target_registry(target_registry) @@ -2751,47 +1168,7 @@ def uk_calibration_diagnostics_payload( declared, _, skipped = _declared_target_partition(result, target_rows, registry) geography = _geography_mapping(declared, target_geography_levels) weights = uk_weight_summary(result_weights) - if withheld is None: - thin, complementary = uk_withheld_row_sets( - result.problem, result.weights, frame, target_rows, geography - ) - withheld = frozenset(thin | complementary) - else: - withheld = frozenset(withheld) - # The floor's own verdict, so a row the caller withholds beside a - # thin one is told apart from the thin row itself. - thin = ( - uk_thin_rows(result.problem, result.weights, frame, target_rows, geography) - if withheld - else set() - ) - for row in target_rows: - name = str(row["name"]) - if geography.get(name) == "brma": - # Every BRMA row states its ten-household verdict, so the release - # contract can see one that skipped the floor (María's ruling of - # 2026-10-19 on the fourth review of #1305: it warns). - row["metadata"] = { - **dict(row.get("metadata") or {}), - "carrier_floor_met": name not in thin, - } - if name in withheld: - for field in _MODEL_FIGURE_FIELDS: - if field in row: - row[field] = None - row["metadata"] = { - **dict(row.get("metadata") or {}), - "model_figures_withheld": ( - _WITHHELD_NOTE if name in thin else _COMPLEMENT_NOTE - ), - **({} if name in thin else {"complementary_withholding": True}), - } - pass_rates = _target_pass_rates(target_rows, skipped, geography, withheld) - withheld_block = ( - _restate_totals_over_published_rows(payload, result, withheld) - if withheld - else None - ) + pass_rates = _target_pass_rates(target_rows, skipped, geography) strata = uk_zero_weight_strata( household, result_weights, @@ -2810,13 +1187,9 @@ def uk_calibration_diagnostics_payload( }, } if local_area_support is not None: - # A withheld row stays out of every rollup, so that no family or area - # total can be differenced against the published rows to recover it, - # and no rollup reads a figure the row no longer carries. - published = [row for row in target_rows if str(row["name"]) not in withheld] - uk_diagnostics["weakest_families"] = uk_weakest_families(published) + uk_diagnostics["weakest_families"] = uk_weakest_families(target_rows) uk_diagnostics["weakest_areas_by_fit"] = uk_weakest_areas_by_fit( - published, + target_rows, local_area_support, ) if rotated_holdout is not None: @@ -2828,8 +1201,6 @@ def uk_calibration_diagnostics_payload( *(payload.get("diagnostic_warnings") or []), *uk_consumption_drift_warnings(drift), ] - if withheld_block is not None: - uk_diagnostics["model_figures_withheld"] = withheld_block payload["uk_diagnostics"] = uk_diagnostics return CalibrationDiagnosticsV8.model_validate(payload).model_dump( mode="python", @@ -2848,13 +1219,8 @@ def write_uk_calibration_diagnostics( build: dict[str, Any] | None = None, local_area_support: pd.DataFrame | None = None, rotated_holdout: Mapping[str, object] | None = None, - withheld: Collection[str] | None = None, ) -> DiagnosticsWriteOutcome: - """Validate and write shared-plus-UK diagnostics through the canonical writer. - - ``withheld`` is the payload's: the rows whose model figures stay in the - build, counted on the payload's rule when not given. - """ + """Validate and write shared-plus-UK diagnostics through the canonical writer.""" output = Path(path) try: @@ -2867,7 +1233,6 @@ def write_uk_calibration_diagnostics( build=build, local_area_support=local_area_support, rotated_holdout=rotated_holdout, - withheld=withheld, ) diagnostics = CalibrationDiagnosticsV8.model_validate(payload) except ValidationError as error: diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/frs_annual_income.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/frs_annual_income.py index 36ac2202bf..203b00ae48 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/frs_annual_income.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/frs_annual_income.py @@ -796,13 +796,22 @@ def pay_concept_ratio( dv = _numeric(jobs, "ugrspay") support = distinct_carriers(jobs["household_id"].to_numpy(), job_weights) denominator = float(np.nansum(job_weights * usual)) - if support < 10 or denominator <= 0: + # Fewer than ten reporting households only flags: the receipt prints the + # ratio "<10" and the gate reads it unmeasured, since a small-cell rule + # never stops a build (María's ruling of 2026-10-26). + if support == 0 or denominator <= 0: raise ValueError( f"{FRS_ANNUAL_INCOME_STAGE_NAME} cannot measure the usual-to-DV pay " - "ratio: fewer than ten households report both." + "ratio: no household reports both." ) ratio = float(np.nansum(job_weights * dv)) / denominator lower, upper = PAY_CONCEPT_RATIO_BOUNDS + if support < 10: + # The bounds are a plausibility check on the two pay concepts. On one + # to nine households a ratio past them is noise, so it is held to + # them rather than stopping the build, and it stays flagged as above + # (Vahid's second review of #1396). + return min(max(ratio, lower), upper), support if not lower <= ratio <= upper: raise ValueError( f"{FRS_ANNUAL_INCOME_STAGE_NAME}: the DV-to-usual pay ratio {ratio:.4f} " @@ -924,7 +933,7 @@ def weighted(values: np.ndarray, mask: np.ndarray) -> float | str: return { "window_months": WINDOW_MONTHS, "weights": "household weights at the stage, carried by each person", - "pay_concept_ratio": ratio, + "pay_concept_ratio": ratio if ratio_support >= 10 else "<10", "pay_concept_ratio_support": support_band(ratio_support), "earnings_growth": float(earnings_growth), "spell_sources": sources, diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/frs_take_up.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/frs_take_up.py index 1b639f3ff1..4e44634e33 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/frs_take_up.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/frs_take_up.py @@ -616,8 +616,16 @@ def uk_take_up_signal_gate( *, contract: UKTakeUpContract | None = None, maximum_share_deviation: float = 0.05, + under_two_usage_maximum_share_deviation: float | None = None, ) -> GateResult: - """Require non-constant UK stochastic flags near contract target shares.""" + """Require non-constant UK stochastic flags near contract target shares. + + The under-2 usage share takes ``under_two_usage_maximum_share_deviation`` + when it is given, every other flag ``maximum_share_deviation``: the DfE + 9-to-11-month row binds a thin cell of that draw's children, so the + calibrated weights move the share further from its rates than they move + any other flag's. + """ resolved = contract if contract is not None else load_uk_take_up_contract() failures: list[str] = [] @@ -659,10 +667,17 @@ def uk_take_up_signal_gate( ) else: target = _target_share(table, key, resolved, weights) + bound = ( + under_two_usage_maximum_share_deviation + if key == UK_UNDER_TWO_USAGE_SIGNAL_KEY + and under_two_usage_maximum_share_deviation is not None + else maximum_share_deviation + ) details[f"{entity}.{output}"] = { "weighted_share": share, "target": target, "absolute_deviation": abs(share - target), + "maximum_share_deviation": bound, "unique_count": unique_count, "population_units": int(population.sum()), } @@ -690,11 +705,10 @@ def uk_take_up_signal_gate( f"{entity}.{output}: constant column; stochastic take-up " "assignment must not collapse to a universal default." ) - if abs(share - target) > maximum_share_deviation: + if abs(share - target) > bound: failures.append( f"{entity}.{output}: weighted share {share:.3f} differs from " - f"contract target {target:.3f} by more than " - f"{maximum_share_deviation:.3f}." + f"contract target {target:.3f} by more than {bound:.3f}." ) return GateResult( name="take_up_signal", diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/full_build_cli.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/full_build_cli.py index 3652c63cb2..834d4ded51 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/full_build_cli.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/full_build_cli.py @@ -856,13 +856,22 @@ def parse_args(argv: list[str] | None = None) -> argparse.Namespace: "--publish-orrery", dest="publish_orrery", action="store_true", - help="Publish the saved graph, including when dataset staging is local-only.", + help=( + "Publish the saved graph to the public Orrery, including when " + "dataset staging is local-only. Off by default. Its summaries " + "carry the targets and each gate's verdict and count of failure " + "lines, but no target row's model figures and no failure line; " + "the export stops if a summary carries either." + ), ) graph_publication.add_argument( "--no-publish-orrery", dest="publish_orrery", action="store_false", - help="Export graph files locally without submitting a publication job.", + help=( + "Export graph files locally without submitting a publication job " + "(the default)." + ), ) parser.set_defaults(publish_orrery=None) args = parser.parse_args(argv) @@ -1135,48 +1144,23 @@ def _stderr_progress(line: str) -> None: print(line, file=sys.stderr, flush=True) -def _may_withhold_rows(args: argparse.Namespace) -> bool: - """Whether the request can bind a row whose model figures stay in the build. - - Every request can: María's rule of 2026-10-21 binds a national row however - few source households carry it (the UC payment and benefit-cap bands), as - the dense role's area BRMAs have been bound since microcosm#1262, and a - thin row's figures stay in the build either way. So no role's staged - epochs keep their loss (the fourth review of #1305 kept it for the - national role while that role bound no thin row). - """ - - del args - return True - - def _solve_observer(args: argparse.Namespace, telemetry): """Readable stderr lines plus the thinned staging rows of every solve. The dense solve, the informed size search and the refit share this one observer; the size events carry the ``phase`` the stderr line names and - the staging row records. An epoch's loss covers every row, so a request - that can bind a thin row forwards its epochs without it: the staging rows - and the emitter carry null, and only the local stderr line keeps it - (the third review of #1305). + the staging row records. """ from .solve_progress import uk_solve_progress_callback - withhold_loss = _may_withhold_rows(args) sinks = [uk_solve_progress_callback(_stderr_progress)] sinks.append( - thinned_epochs( - emit_calibration_progress, - every=staging_epoch_every(args), - withhold_loss=withhold_loss, - ) + thinned_epochs(emit_calibration_progress, every=staging_epoch_every(args)) ) if telemetry is not None: sinks.append( thinned_epochs( - telemetry.calibration_progress, - every=staging_epoch_every(args), - withhold_loss=withhold_loss, + telemetry.calibration_progress, every=staging_epoch_every(args) ) ) @@ -3157,14 +3141,6 @@ def _execute_national_build( "score_vs_enhanced_frs": None, } stage(telemetry, "diagnostics", "started") - # The national gates flagged the rows whose model figures stay in the - # build; the diagnostics take that set rather than count it again, so it - # is computed once per build (Vahid's third review of #1383, item 32). - withheld = frozenset( - str(row["name"]) - for row in evidence["diagnostics"] - if row.get("model_figures_withheld") is True - ) diagnostics_outcome = write_uk_calibration_diagnostics( result, paths["calibration_diagnostics"], @@ -3172,7 +3148,6 @@ def _execute_national_build( target_geography_levels=evidence["target_geography_levels"], target_registry=solved_registry, build=build_block, - withheld=withheld, ) if isinstance(diagnostics_outcome, DiagnosticsWriteFailure): raise RuntimeError( diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/full_gates.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/full_gates.py index 09e69253bc..f9c9d7b183 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/full_gates.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/full_gates.py @@ -23,7 +23,6 @@ uk_cgt_projection_artifact, ) from microcosm.build.uk_runtime.cgt_projection import UK_CGT_PROJECTION_ARTIFACT_KEY -from microcosm.build.uk_runtime.diagnostics import uk_withheld_rows from microcosm.build.uk_runtime.graph_evidence import uk_spine_gate_artifacts from microcosm.build.uk_runtime.national_frame import uk_release_export_frame from microcosm.build.uk_runtime.parity_reference import load_efrs_parity_reference @@ -236,33 +235,6 @@ def build_full_gate_context( local_rows.append(row) else: national_errors[target.row_name] = float(solved_rows[index].relative_error) - # A row's model figures leave the build only when ten distinct source - # households carry them: María's ruling of 2026-10-17 for BRMA rows - # (microcosm#1262), extended to national and regional rows by her rule of - # 2026-10-21, which binds a thin row rather than leave it out (local rows - # keep the area-support rule). The fit gates decide on the published rows - # and count the withheld ones (her ruling of 2026-10-19); the flag tells - # the bindings and the writers which rows those are. - # The withholding ties a local family to its parents by contract target - # (Vahid's review of #1383, item 1). - withheld = uk_withheld_rows( - problem, - solution.weights, - frame, - [ - { - **row, - "metadata": {"contract_target_id": metadata.get("contract_target_id")}, - } - for row, metadata in zip( - diagnostics, ordered_problem.target_metadata, strict=True - ) - ], - {str(row["name"]): str(row["geography_level"]) for row in diagnostics}, - ) - for row in diagnostics: - if row["name"] in withheld: - row["model_figures_withheld"] = True reference_registry = supporting_evidence.get("reference_registry") if not isinstance(reference_registry, TargetRegistry): raise ValueError( @@ -320,11 +292,9 @@ def build_full_gate_context( candidate_targets=set(national_errors), reference_targets=national_reference, target_relative_errors=national_errors, - withheld_targets=frozenset(withheld), ), "local_target_diagnostics": local_rows, "target_diagnostics": diagnostics, - "model_figures_withheld": tuple(sorted(withheld)), "aggregate_admin": admin_totals, "aggregate_admin_measurement": admin_receipt, "full_gate_scope": uk_full_gate_scope_receipt(selection_receipt), diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/gambling_participation.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/gambling_participation.py index 83ff26cb4b..3ca491273e 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/gambling_participation.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/gambling_participation.py @@ -81,9 +81,12 @@ "l2_regularization", "validation_fraction", ) -#: The fewest distinct source households a receipt cell may rest on, and the -#: fewest donor households a key's fits may learn from (CD171 section 5.2.1). +#: The fewest distinct source households a receipt cell may rest on (CD171 +#: section 5.2.1). SMALL_CELL = 10 +#: The fewest donor households on each side of a key the propensity fit +#: needs: its held-out validation split is stratified by the key. +_FIT_MINIMUM = 2 @dataclass(frozen=True) @@ -663,11 +666,15 @@ def top_up_gambling_participation( drawn = np.asarray(keys[key], dtype=float) donor_stakes = np.asarray(donor_keys[key], dtype=float) played = donor_stakes > 0 - if not SMALL_CELL <= int(played.sum()) <= len(played) - SMALL_CELL: + # Fewer than ten donor households on a side only flags: the receipt + # bands the fits' donor support and withholds what rests on them, and + # a small-cell rule never stops a build (María's ruling of 2026-10-26). + # The fit itself needs two on each side. + if not _FIT_MINIMUM <= int(played.sum()) <= len(played) - _FIT_MINIMUM: raise ValueError( f"{TOP_UP_GAMBLING_PARTICIPATION_KIND}: the donor must record {key} " - f"stakes on {SMALL_CELL} or more households and leave {SMALL_CELL} " - "or more without, to fit and report its share." + f"stakes on {_FIT_MINIMUM} or more households and leave " + f"{_FIT_MINIMUM} or more without, to fit its share." ) chance = { window: household_participation( diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/graph_national.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/graph_national.py index c3e093c2b8..94e8f55483 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/graph_national.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/graph_national.py @@ -101,12 +101,7 @@ ) from .cgt_projection import UK_CGT_PROJECTION_ARTIFACT_KEY from .content_identity import uk_frame_content_identity -from .diagnostics import ( - uk_published_row_losses, - uk_refuse_named_withheld_rows, - uk_target_geography_levels, - uk_withheld_rows, -) +from .diagnostics import uk_target_geography_levels from .full_targets import CHRONICLE_SOURCE_CODEC, load_uk_national_target_inputs from .graph_build import SPINE_PROVENANCE_TYPE from .graph_calibration import ( @@ -1040,41 +1035,12 @@ def run(self, context: KernelContext) -> KernelResult: manifest_block = national_calibration_manifest( result, frame, problem=problem, doctrine=doctrine ) - # María's rule of 2026-10-21 binds a row however few source households - # carry it. Under ten, its model figures stay in the build, as a BRMA - # row's do (her rulings of 2026-10-17 to 2026-10-19): blank in the - # evidence rows, outside the fit gate's verdict, and the manifest's - # losses restated over the published rows. - withheld = frozenset( - uk_withheld_rows( - result.problem, - result.weights, - frame, - [{"name": row.name} for row in result.diagnostics], - ) - ) - if withheld: - initial_loss, final_loss = uk_published_row_losses(result, withheld) - manifest_block = { - **manifest_block, - "loss": final_loss, - "solve": { - **dict(manifest_block["solve"]), - "initial_loss": initial_loss, - "final_loss": final_loss, - }, - "totals_basis": "published_rows", - "model_figures_withheld": len(withheld), - } diagnostics_rows = [ { "name": row.name, - "estimate": None if row.name in withheld else row.final_estimate, + "estimate": row.final_estimate, "target": row.target, - "relative_error": None if row.name in withheld else row.relative_error, - **( - {"model_figures_withheld": row.name in withheld} if withheld else {} - ), + "relative_error": row.relative_error, } for row in result.diagnostics ] @@ -1088,9 +1054,7 @@ def run(self, context: KernelContext) -> KernelResult: target_relative_errors={ str(row["name"]): float(row["relative_error"]) for row in diagnostics_rows - if str(row["name"]) not in withheld }, - withheld_targets=withheld, ), "aggregate_admin": admin_totals, UK_CGT_PROJECTION_ARTIFACT_KEY: projection, @@ -1107,9 +1071,6 @@ def run(self, context: KernelContext) -> KernelResult: ) blocking = report.blocking_outcomes(release_candidate=False) report_payload = gate_phase_report_payload(report, gates=gates) - # The gates decide on the published rows and count the withheld ones; - # a report that names one stops the build before it leaves. - uk_refuse_named_withheld_rows(report_payload, names=withheld, keys=frozenset()) payload = { "schema_version": 1, "kind": "uk_national_gate_report", diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/graph_terminal.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/graph_terminal.py index fe6afb008b..25fe8c8bbb 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/graph_terminal.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/graph_terminal.py @@ -849,9 +849,6 @@ def run(self, context: KernelContext) -> KernelResult: diagnostics = [] support = [] output_artifacts = {} - # BRMA rows whose model figures leave the build only with ten source - # households behind them (María's ruling of 2026-10-17). - withheld: frozenset[str] = frozenset() upstream_reports = { name: json.loads(context.artifacts[name].payload) for name in ("spine_assembled", "spine_transferred") @@ -946,14 +943,7 @@ def run(self, context: KernelContext) -> KernelResult: ) diagnostics = evidence.artifacts["target_diagnostics"] support = support_frame.to_dict(orient="records") - from .diagnostics import ( - uk_calibration_diagnostics_payload, - uk_withhold_brma_figures, - ) - - # The evidence flags the BRMA rows whose model figures stay in the - # build (María's ruling of 2026-10-17, microcosm#1262). - withheld = frozenset(evidence.artifacts["model_figures_withheld"]) + from .diagnostics import uk_calibration_diagnostics_payload from .graph_targets import registry_from_payload selected_registry = registry_from_payload( @@ -993,16 +983,13 @@ def run(self, context: KernelContext) -> KernelResult: "build_kind": "uk_full_build", "target_scope": selection["selector"], }, - withheld=withheld, ) output_artifacts.update( { "calibration_diagnostics": encode_stage_evidence( _json_safe(complete_diagnostics) ), - "target_diagnostics_csv": pd.DataFrame( - uk_withhold_brma_figures(diagnostics, withheld) - ) + "target_diagnostics_csv": pd.DataFrame(diagnostics) .to_csv(index=False) .encode(), "area_support_csv": support_frame.to_csv(index=False).encode(), @@ -1016,23 +1003,6 @@ def run(self, context: KernelContext) -> KernelResult: report = evaluate_phase( gates, phase=phase, context=evidence, registry=UK_GATE_REGISTRY ) - from .diagnostics import ( - uk_refuse_named_withheld_rows, - uk_withheld_gate_areas, - uk_withheld_gate_keys, - uk_withhold_brma_figures, - ) - - report_payload = gate_phase_report_payload(report, gates=gates) - # The gates decide on the published rows and count the withheld ones - # (María's ruling of 2026-10-19); a report that names one fails the - # build rather than leaving it. - uk_refuse_named_withheld_rows( - report_payload, - names=withheld, - keys=uk_withheld_gate_keys(diagnostics), - areas=uk_withheld_gate_areas(diagnostics), - ) payload = { "schema_version": 1, "kind": "uk_full_gate_report", @@ -1040,11 +1010,9 @@ def run(self, context: KernelContext) -> KernelResult: "sample_fraction": float(context.params["sample_fraction"]), "release_candidate": bool(context.params["release_candidate"]), "scope": uk_full_gate_scope_receipt(selection), - "report": report_payload, + "report": gate_phase_report_payload(report, gates=gates), "upstream_phase_reports": upstream_reports, - "target_diagnostics": _json_safe( - uk_withhold_brma_figures(diagnostics, withheld) - ), + "target_diagnostics": _json_safe(diagnostics), "area_support": _json_safe(support), "artifacts": {name: value.key for name, value in context.artifacts.items()}, } @@ -1606,74 +1574,6 @@ def _reviewed_exclusions_stood_on(gate_rows: Mapping[str, Mapping]) -> dict: return record -#: The size receipt's fields a manifest publishes while any row is withheld: -#: counts, settings, the draw and its search bracket. Every other field reads -#: null, the losses over every row, the search's probes and the refit's -#: distances among them (microcosm#1262, the third review of #1305). -_SIZE_RECEIPT_PUBLISHED_WHILE_WITHHELD = frozenset( - { - "baseline_floored_rows", - "baseline_mass_share_certainties", - "baseline_pi_floor", - "boundary_draws", - "certainty_share", - "certification", - "household_ids", - "households", - "inclusion_probabilities", - "method", - "pi_hi", - "pool_households", - "pool_row_indices", - "problem_sha256", - "protected", - "protected_carriers", - "realized_households", - "refit_baseline", - "refit_epochs", - "refit_iterate_selection", - "requested_households", - "seed", - "selection_budget_basis", - "selection_epochs", - "selection_l0_lambda", - "selection_pi_hi", - "selection_receipt", - "selection_reused", - "selection_search_bracket", - "selection_search_pi_hi", - "stretch_reference", - "support", - "zero_target_rows", - } -) - - -def _published_size_receipt( - size_receipt: Mapping[str, object] | None, *, withheld: int -) -> dict[str, object] | None: - """The size receipt as a manifest publishes it. - - While any row's model figures are withheld, only the fields on the - allow-list keep their values and a note says why; the stored receipt - keeps them all. - """ - - if size_receipt is None: - return None - if not withheld: - return dict(size_receipt) - published = { - key: (value if key in _SIZE_RECEIPT_PUBLISHED_WHILE_WITHHELD else None) - for key, value in size_receipt.items() - } - published["withheld_totals_note"] = ( - "Only counts, settings and the draw are published: " - f"{withheld} row(s) have their model figures withheld (microcosm#1262)." - ) - return published - - def _fit_rows(target_rows: pd.DataFrame, materialization: Mapping[str, str]): """Split the terminal target diagnostics into local and national rows.""" kinds = target_rows["name"].map(materialization) @@ -1839,19 +1739,10 @@ def rowwise_candidate_manifest_from_graph( 1 for kind in materialization.values() if kind == _NATIONAL_MATERIALIZATION ) local_rows = len(materialization) - ladder_rows - national_rows - # A row whose model figures stay in the build reads blank (microcosm#1262): - # every fit figure below is over the published rows, and the solve block - # counts the rest. - withheld_rows = ( - target_rows["model_figures_withheld"].fillna(False).astype(bool) - if "model_figures_withheld" in target_rows - else pd.Series(False, index=target_rows.index) - ) - published_rows = target_rows.loc[~withheld_rows].reset_index(drop=True) - local_fit, national_fit = _fit_rows(published_rows, materialization) - abs_errors = published_rows["abs_relative_error"].to_numpy(dtype=np.float64) + local_fit, national_fit = _fit_rows(target_rows, materialization) + abs_errors = target_rows["abs_relative_error"].to_numpy(dtype=np.float64) if not np.isfinite(abs_errors).all(): - raise ValueError("A published target row has a non-finite relative error.") + raise ValueError("A target row has a non-finite relative error.") support_by_grain = { ("la" if grain == "local_authority" else str(grain)): rows.reset_index( drop=True @@ -2025,19 +1916,7 @@ def rowwise_candidate_manifest_from_graph( }, "n_households": int(frame.n("household")), "pool_households": int(len(problem.entity_ids)), - "dataset_size": _published_size_receipt( - size_receipt, withheld=int(withheld_rows.sum()) - ), - **( - { - "model_figures_withheld": { - "targets": int(withheld_rows.sum()), - "totals_basis": "published_rows", - } - } - if withheld_rows.any() - else {} - ), + "dataset_size": None if size_receipt is None else dict(size_receipt), "initial_loss": diagnostics["initial_loss"], "final_loss": diagnostics["final_loss"], "max_abs_relative_error": float(abs_errors.max()) @@ -2095,16 +1974,26 @@ def rowwise_candidate_manifest_from_graph( ), "rotated_holdout": diagnostics["uk_diagnostics"].get("rotated_holdout"), }, - # Area counts only: the manifest ships in a release, and a level's - # minima would be one area's support figures (microcosm#1301). The - # figures stay in the area-support table. + # The counts and the minima: María's ruling of 2026-10-26 dropped the + # withholding of per-area support figures (microcosm#1301). "support": { "areas_checked": int(len(support)), "areas_below_floor": int(support["support_below_floor"].sum()), + "min_assigned_households": int(support["assigned_households"].min()), + "min_nonzero_households": int(support["nonzero_households"].min()), + "min_effective_sample_size": float(support["effective_sample_size"].min()), "by_geography_level": { str(level): { "areas_checked": int(len(rows)), "areas_below_floor": int(rows["support_below_floor"].sum()), + "min_assigned_households": int(rows["assigned_households"].min()), + "min_nonzero_households": int(rows["nonzero_households"].min()), + "min_effective_sample_size": float( + rows["effective_sample_size"].min() + ), + "min_nonzero_source_households": int( + rows["nonzero_source_households"].min() + ), } for level, rows in support.groupby("geography_level", sort=True) }, diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/national_role.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/national_role.py index 91206d19e1..5ffc89ce7b 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/national_role.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/national_role.py @@ -195,10 +195,6 @@ def national_dry_run( _national_dry_run = national_dry_run -def _optional_float(value: object) -> float | None: - return None if value is None else float(value) - - def national_fit_by_family( diagnostics: Mapping[str, Any], registry: TargetRegistry ) -> list[dict[str, object]]: @@ -323,10 +319,8 @@ def output(role: str) -> dict[str, Any]: }, "n_households": int(solve["n_households"]), "pool_households": int(solve["n_households"]), - # Restated over the published rows when a row is withheld, and - # null where the solve cannot restate (microcosm#1262). - "initial_loss": _optional_float(solve["initial_loss"]), - "final_loss": _optional_float(solve["final_loss"]), + "initial_loss": float(solve["initial_loss"]), + "final_loss": float(solve["final_loss"]), "n_nonzero": int(solve["n_nonzero"]), "max_abs_relative_error": ( float(abs_errors.max()) if abs_errors.size else None diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/orrery_contract.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/orrery_contract.py index ace70019f9..d23691034b 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/orrery_contract.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/orrery_contract.py @@ -28,14 +28,17 @@ from .graph_calibration import SIZE_DRAW_TYPE, SIZE_RECEIPT_TYPE, SIZE_SEARCH_TYPE from .graph_evidence import SPINE_GATE_REPORT_TYPE from .graph_national import ( - NATIONAL_EVIDENCE_TYPE, NATIONAL_GATE_REPORT_TYPE, NATIONAL_TARGET_TYPE, ) from .graph_targets import TARGET_SELECTION_TYPE, registry_from_payload -from .graph_terminal import FULL_DIAGNOSTICS_TYPE, FULL_GATE_REPORT_TYPE +from .graph_terminal import FULL_GATE_REPORT_TYPE -#: A summary row's fields that the result's weights produce. +#: A target row's fields that the result's weights produce. The summaries are +#: the projection a build may publish to the Orrery, and since María's ruling +#: of 2026-10-26 the build no longer marks the rows resting on fewer than ten +#: source households, so the summaries carry no row's figures (Vahid's review +#: of #1396, M1). The build's private diagnostics keep every row's. _SUMMARY_MODEL_FIELDS = ( "initial", "achieved", @@ -43,135 +46,21 @@ "relative_error", "within_tolerance", ) - - -#: The outputs in which a gate on a result records the rows it withheld: the -#: national gates flag each row of their calibration evidence, and the full -#: build's terminal gate notes each withheld row in its diagnostics' metadata. -_RECORDED_WITHHELD = { - "calibration_evidence": ( - NATIONAL_EVIDENCE_TYPE, - "diagnostics", - lambda row: row.get("model_figures_withheld") is True, - ), - "calibration_diagnostics": ( - FULL_DIAGNOSTICS_TYPE, - "targets", - lambda row: bool((row.get("metadata") or {}).get("model_figures_withheld")), - ), -} - - -def _recorded_withheld( - context: ArtifactSummaryContext, -) -> tuple[frozenset[str], frozenset[str]] | None: - """The rows a gate on this result saw, and those it recorded as withheld. - - Only a gate that reads this result directly counts. The summary takes its - set rather than count it again, so a build computes the withholding once - (Vahid's third review of #1383, item 32). None when no such gate has run. - """ - - found: set[tuple[frozenset[str], frozenset[str]]] = set() - for node_id, predecessors in context.run.compiled.predecessors.items(): - if context.node_id not in predecessors: - continue - receipt = context.run.manifest.nodes.get(node_id) - if receipt is None: - continue - for name, descriptor in receipt.typed_artifacts.get("outputs", {}).items(): - reader = _RECORDED_WITHHELD.get(name) - if reader is None or name not in receipt.opaque_artifacts: - continue - type_, table, flagged = reader - if descriptor["type"] != { - "name": type_.name, - "schema_version": type_.schema_version, - }: - continue - rows = json.loads(context.store.load_bytes(descriptor["key"]))[table] - found.add( - ( - frozenset(str(row["name"]) for row in rows), - frozenset(str(row["name"]) for row in rows if flagged(row)), - ) - ) - if len(found) > 1: - raise ValueError("Gates on one result recorded different withheld rows.") - return next(iter(found), None) - - -def _withhold_summary_rows( - data: dict, - result, - ordered, - recorded: tuple[frozenset[str], frozenset[str]] | None = None, -) -> None: - """Keep a thin row's figures out of the published summary (#1262). - - María's ruling of 2026-10-17: a BRMA row's model figures leave a build - only when ten distinct source households carry them, here counted on this - result's own weights; her rule of 2026-10-21 extends it to national and - regional rows (local rows keep the area-support rule). A withheld row - keeps its target and its place, and the final loss covers the published - rows (her ruling of 2026-10-18). ``recorded`` is a gate's - (:func:`_recorded_withheld`): taken as it is when that gate saw every - summary row, and counted here otherwise. - """ - - from .diagnostics import _restate_totals_over_published_rows, uk_withheld_rows - - rows = data["tables"]["targets"] - metadata_by_row = { - target.row_name: metadata - for target, metadata in zip( - ordered.problem.targets, ordered.target_metadata, strict=True - ) - } - if recorded is not None and {row["name"] for row in rows} <= recorded[0]: - withheld = set(recorded[1]) - else: - # The withholding ties a local family to its parents by contract - # target (Vahid's review of #1383, item 1). - withheld = uk_withheld_rows( - ordered.problem, - result.weights, - result.frame, - [ - { - **row, - "metadata": { - key: metadata_by_row.get(row["name"], {}).get(key) - for key in ("contract_target_id", "geography_id") - }, - } - for row in rows - ], - { - name: metadata.get("geography_level", "") - for name, metadata in metadata_by_row.items() - }, - ) - if not withheld: - return - for row in rows: - if row["name"] in withheld: - for field in _SUMMARY_MODEL_FIELDS: - row[field] = None - row["model_figures_withheld"] = True - totals: dict = {} - _restate_totals_over_published_rows(totals, result, frozenset(withheld)) - data["overview"]["final_loss"] = totals["final_loss"] - data["overview"]["model_figures_withheld"] = { - "targets": len(withheld), - "totals_basis": "published_rows", - } +#: Size receipt fields left out of the summary: one target row's figure. +_SIZE_ROW_FIELDS = ("max_target_scaled_change",) +_RECORD_SCOPE = ( + "Targets and the weight distribution; no entity IDs, record values or " + "target row's model figures." +) def _uk_result_summary(context: ArtifactSummaryContext) -> dict: result, ordered = summary_result(context) data = result_summary_data(result, ordered) - _withhold_summary_rows(data, result, ordered, _recorded_withheld(context)) + for row in data["tables"]["targets"]: + for field in _SUMMARY_MODEL_FIELDS: + del row[field] + data["overview"]["record_scope"] = _RECORD_SCOPE ancestors, pending = set(), [context.node_id] while pending: current = pending.pop() @@ -226,7 +115,8 @@ def _uk_result_summary(context: ArtifactSummaryContext) -> dict: def _size_summary(context: ArtifactSummaryContext) -> dict: - """Project the maintained size artifact, excluding IDs, masks and draws.""" + """Project the maintained size artifact, excluding IDs, masks, draws and + any one target row's figure; the losses are totals over every row.""" value = json.loads(context.payload) problem = decode_problem(context.input_payload("problem")) if value.get("problem_sha256") != problem.sha256: @@ -264,18 +154,10 @@ def _size_summary(context: ArtifactSummaryContext) -> dict: "baseline_mass_share_certainties", "dense_loss", "compact_loss", - "max_target_scaled_change", "certification", "pi_hi", ) summary = {key: value[key] for key in fields if key in value} - # Totals over every row: with a row withheld they would give it back by - # difference (microcosm#1262). Without the weights behind them this - # summary cannot tell which rows are thin, and since María's rule of - # 2026-10-21 any problem may bind one, so it publishes none. - for key in ("dense_loss", "compact_loss", "max_target_scaled_change"): - if key in summary: - summary[key] = None summary["problem_sha256"] = problem.sha256 for key in ("support", "protected", "household_ids", "pool_row_indices"): if key in value: @@ -329,7 +211,9 @@ def _gate_rows(report: object) -> tuple[list[dict], dict]: isinstance(line, str) for line in failures ): raise ValueError("Gate failures must be text lines.") - row["failures"] = failures + # A line can state a row's model figures or an area's support, which + # the build no longer withholds; the gate report keeps the lines. + row["failure_count"] = len(failures) row["evidence_sha256"] = outcome.get("evidence_sha256") counts[row["status"]] += 1 rows.append(row) @@ -347,7 +231,8 @@ def _gate_report_summary(context: ArtifactSummaryContext) -> dict: The spine artifact is a bare phase report; the full and national artifacts wrap one in a document with enforcement or blocking verdicts. Gate detail - payloads and target or area tables are not projected. + payloads, target or area tables and failure lines are not projected; each + gate states how many failure lines it has. """ document = json.loads(context.payload) if not isinstance(document, dict): @@ -409,6 +294,37 @@ def _gate_report_summary(context: ArtifactSummaryContext) -> dict: } +def public_summary_findings(summaries: list[dict]) -> list[str]: + """Recorded summaries that carry a target row's figures or failure lines. + + The providers above project neither. The publication runs this on the + summaries it is about to export, so a provider that regresses stops the + export rather than reaching the Orrery. + """ + + findings = [] + for summary in summaries: + data = summary.get("data") + if not isinstance(data, dict): + continue + where = f"{summary.get('node')}/{summary.get('artifact')}" + tables = data.get("tables") or {} + fields = { + field + for row in tables.get("targets", []) + for field in _SUMMARY_MODEL_FIELDS + if field in row + } + fields.update( + field for field in _SIZE_ROW_FIELDS if field in data.get("overview", {}) + ) + if fields: + findings.append(f"{where} carries {', '.join(sorted(fields))}") + if any("failures" in row for row in tables.get("gates", [])): + findings.append(f"{where} carries gate failure lines") + return findings + + def checkpoint_references(sidecar_path: Path | None) -> tuple[list[dict], str | None]: """Use only recorded checkpoint lineage, never today's reconstructed spine.""" if sidecar_path is None or not sidecar_path.is_file(): diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/orrery_publication.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/orrery_publication.py index d3666f8537..67518dc5ec 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/orrery_publication.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/orrery_publication.py @@ -29,6 +29,8 @@ from microcosm.graph.execution_overlay import execution_overlay_bytes from microcosm.graph.orrery import orrery_json_from_schema +from .orrery_contract import public_summary_findings + RECEIPT_NAME = "orrery.publication.json" INVENTORY_NAME = "orrery.upload.json" EVIDENCE_MANIFEST_NAME = "orrery.evidence-manifest.json" @@ -56,14 +58,14 @@ class GraphFinalization: def publication_enabled(args: Namespace) -> bool: - explicit = getattr(args, "publish_orrery", None) - if explicit is not None: - return explicit - return not ( - getattr(args, "no_staging", False) - or getattr(args, "staging_local_only", False) - or getattr(args, "no_staged_dataset", False) - ) + """Whether the saved graph goes to the public Orrery: only on request. + + A UK build keeps its graph evidence local unless ``--publish-orrery`` asks + for the submission (María's ruling of 2026-10-26), whatever its staging; + staging to the private repositories does not depend on it. + """ + + return getattr(args, "publish_orrery", None) is True def _urls(value: object) -> Iterator[str]: @@ -130,6 +132,11 @@ def finalize_graph( store = ContentStore(args.graph_store, create=False) runs = load_run_evidence(index_path, store=store, reference_base=output) execution = collect_execution_evidence(schema, runs=runs, store=store) + # Checked before anything is preserved: without the inventory + # neither the build nor the emitter's retry can submit them. + if public_summary_findings(execution["summaries"]): + receipt.update(status="failed", error_code="unpublishable_summary") + raise RuntimeError("Graph summaries carry unpublishable fields.") roles[index_path.name] = "index" index = json.loads(index_path.read_bytes()) for run in index["runs"]: diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/release_certification.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/release_certification.py index aa75456f8d..9785ca34e8 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/release_certification.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/release_certification.py @@ -238,7 +238,6 @@ def uk_release_parity_evidence( """ target_relative_errors: dict[str, float] = {} - withheld: set[str] = set() for row in diagnostics_targets: name = str(row["name"]) if "@" not in name: @@ -249,11 +248,13 @@ def uk_release_parity_evidence( ) metadata = row.get("metadata") if isinstance(metadata, Mapping) and metadata.get("model_figures_withheld"): - # Fewer than ten source households carry it (María's rule of - # 2026-10-21): bound, published without its figures, and outside - # the fit gate's verdict. - withheld.add(name) - continue + # A build from before María's ruling of 2026-10-26, which dropped + # the withholding, left this row's figures blank; the fit gate + # judges every row, so the run cannot be certified here. + raise UKReleaseCertificationError( + f"diagnostics target {name!r} withholds its model figures; " + "rebuild the run to certify it." + ) target_relative_errors[name] = float(row["relative_error"]) return SimpleNamespace( candidate_columns=uk_export_candidate_columns(frame), @@ -261,12 +262,11 @@ def uk_release_parity_evidence( f"{entity}.{name}" for name, entity in parity_reference.input_entities.items() }, - candidate_targets=set(target_relative_errors) | withheld, + candidate_targets=set(target_relative_errors), reference_targets={ f"{spec.name}@{spec.period}" for spec in reference_registry.specs }, target_relative_errors=target_relative_errors, - withheld_targets=frozenset(withheld), ) @@ -380,16 +380,6 @@ def run_uk_release_cut_battery( battery.run_phase( "terminal", EvidenceContext(frame=frame, artifacts=terminal_artifacts) ) - from microcosm.build.uk_runtime.diagnostics import uk_refuse_named_withheld_rows - - # The gates decide on the published rows and count the withheld ones - # (María's rule of 2026-10-21 binds a thin national row); a report that - # names one stops before the certification uses it. - uk_refuse_named_withheld_rows( - battery.report_payload(), - names=frozenset(parity_evidence.withheld_targets), - keys=frozenset(), - ) battery.enforce("terminal", mode=BlockingMode.BLOCKS_ARTIFACT) payload = battery.report_payload() finalize_uk_scoped_gate_report( diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/rowwise_staging.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/rowwise_staging.py index 8ff62fe8dc..a27fc79681 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/rowwise_staging.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/rowwise_staging.py @@ -365,7 +365,6 @@ def thinned_epochs( sink: Callable[[Mapping[str, Any]], None], *, every: int = CALIBRATION_EPOCH_EVERY, - withhold_loss: bool = False, ) -> Callable[[dict[str, object]], None]: """Forward the shared rule's calibration epochs to ``sink``. @@ -378,10 +377,6 @@ def thinned_epochs( (the national command never runs a budget search and never met this). A contract or content refusal from the telemetry is reported once and stops the forwarding: the solve must never abort on its own progress report. - - ``withhold_loss`` forwards each epoch with a null ``loss``: an epoch's loss - covers every row, so for a problem that may withhold a row's model figures - it would give them back against the published ones (microcosm#1262). """ disabled = False @@ -391,8 +386,6 @@ def callback(event: dict[str, object]) -> None: if disabled or not forwards_calibration_epoch(event, every=every): return forwarded = dict(event) - if withhold_loss: - forwarded["loss"] = None budget_search = forwarded.get("budget_search") if isinstance(budget_search, bool): forwarded["budget_search"] = 1 if budget_search else None diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/stage_health.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/stage_health.py index 2a9de2c019..328c32e080 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/stage_health.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/stage_health.py @@ -1106,8 +1106,10 @@ def _frs_annual_income_spells_gate( current employee earners: the survey's spells can add part-year earners but cannot remove a current one. Where the receipt measures it, at least the declared share of the pay outside the current job is observed rather - than drawn from a donor; a share carried by fewer than ten households is - reported unmeasured. + than drawn from a donor. A ratio or share carried by fewer than ten + households, which the receipt prints "<10", is flagged unmeasured, never + failed: a small-cell rule never stops a build (María's ruling of + 2026-10-26). """ check = "frs_annual_income_spells" @@ -1128,7 +1130,9 @@ def _frs_annual_income_spells_gate( upper = _finite_number(bounds[1], label=f"{stage}.{bounds_key}[1]") value = evidence.get(key) details[key] = value - if isinstance(value, bool) or not isinstance(value, int | float): + if value == "<10": + details[f"{key}_measured"] = False + elif isinstance(value, bool) or not isinstance(value, int | float): failures.append(f"{stage}: {key} is {value!r}, not a measured ratio.") elif not lower <= float(value) <= upper: failures.append( @@ -1303,7 +1307,10 @@ def _uc_take_up_gate( type's pools whose target the draw can reach, the realized Great Britain caseload is within ``maximum_caseload_deviation`` of DWP's count, and the family type's whole caseload is no further from DWP's than before the - redraw, give or take that share of DWP's count. + redraw, give or take that share of DWP's count. A family type whose + caseload rests on fewer than ten sources, which the receipt prints "<10", + is flagged unchecked, never failed: a small-cell rule never stops a build + (María's ruling of 2026-10-26). """ check = "uc_take_up" @@ -1322,6 +1329,7 @@ def _uc_take_up_gate( if not isinstance(families, Mapping) or not families: failures.append(f"{stage}: the receipt carries no family types.") families = {} + unchecked: list[str] = [] for name, family in families.items(): family = _mapping(family, label=f"{stage}.families.{name}") values = { @@ -1335,11 +1343,11 @@ def _uc_take_up_gate( ) } details[str(name)] = values + if any(value == "<10" for value in values.values()): + unchecked.append(str(name)) + continue if any(not isinstance(value, int | float) for value in values.values()): - failures.append( - f"{stage}: family type {name} carries a caseload resting on fewer " - "than ten sources, or none." - ) + failures.append(f"{stage}: family type {name} carries no caseload.") continue dwp = _finite_number(values["dwp_caseload"], label=f"{stage}.{name}.dwp") before = _finite_number(values["caseload_before"], label=f"{stage}.{name}") @@ -1361,6 +1369,7 @@ def _uc_take_up_gate( f"{stage}: family type {name} moves from {before:,.0f} to " f"{after:,.0f}, further from DWP's {dwp:,.0f}." ) + details["family_types_unchecked_small_cells"] = unchecked return ( _fail(stage, check, failures, details) if failures @@ -3507,8 +3516,9 @@ def _excise_quantities_gate( spending comes from must have stayed in [0, 1] on the frame, each must rest on ``required_support_band`` donors, and the donor share whose published total sits beside its diary lines must be at most - ``maximum_parent_residual_share`` (a share withheld for resting on under - ten donors is under it). + ``maximum_parent_residual_share``. A share the receipt withholds for + resting on under ten donors is flagged unchecked, never failed (María's + ruling of 2026-10-26). """ from microcosm.build.country_spec import load_country_spec @@ -3637,6 +3647,7 @@ def _close(observed: object, value: float) -> bool: f"{stage}: the excise_shares receipt names {sorted(shares)}, not " f"{sorted(UK_LCFS_EXCISE_SHARES)}." ) + unchecked_residuals: list[str] = [] for name in UK_LCFS_EXCISE_SHARES: entry = shares.get(name) if not isinstance(entry, Mapping): @@ -3651,7 +3662,9 @@ def _close(observed: object, value: float) -> bool: f"not {required_support!r}." ) residual = donor.get("total_beside_lines") - if isinstance(residual, int | float) and residual > maximum_residual: + if residual == "<10": + unchecked_residuals.append(name) + elif isinstance(residual, int | float) and residual > maximum_residual: failures.append( f"{stage}: a weighted {residual} of donors carry a published total " f"beside {name}'s lines, above {maximum_residual}." @@ -3660,6 +3673,7 @@ def _close(observed: object, value: float) -> bool: "maximum_relative_deviation": tolerance, "levels": {column: level.annual for column, level in levels.items()}, "alcohol_volume_weights": dict(volume.receipt), + "residuals_unchecked_small_cells": unchecked_residuals, } return ( _fail(stage, check, failures, details) @@ -3692,8 +3706,9 @@ def _gambling_participation_gate( ``required_support_band`` donors; and the excise levelling must have shared the bases by the topped-up keys, so each key is positive on the twelve-month share. The receipt withholds a stratum with a cell under ten - source households, which the gate counts; a key it withholds nationally - fails, since nothing of it could be checked. + source households, which the gate counts, and a key with such a cell + nationally, which the gate names as unchecked: a small-cell rule flags and + never stops a build (María's ruling of 2026-10-26). """ from microcosm.build.country_spec import load_country_spec @@ -3821,6 +3836,7 @@ def _stratum(key: str, label: str, entry: Mapping[str, object]) -> list[str]: keys = _mapping(receipt.get("keys"), label=f"{stage}.gambling_participation.keys") levelled = _mapping(excise.get("keys"), label=f"{stage}.excise_quantities.keys") withheld_strata = 0 + withheld_keys: list[str] = [] national: dict[str, object] = {} for key in UK_GAMBLING_PARTICIPATION_KEYS: entry = keys.get(key) @@ -3852,10 +3868,7 @@ def _stratum(key: str, label: str, entry: Mapping[str, object]) -> list[str]: else: failures.append(f"{stage}: {key} stratum {label} is not an object.") if entry.get("withheld") is True: - failures.append( - f"{stage}: the receipt withholds {key}'s national shares, so the gate " - "can check none of them." - ) + withheld_keys.append(key) continue for target, after in ( ("regular_target", "after_regular"), @@ -3914,6 +3927,7 @@ def _stratum(key: str, label: str, entry: Mapping[str, object]) -> list[str]: "maximum_relative_deviation": tolerance, "maximum_stratum_shortfall": shortfall, "strata_withheld": withheld_strata, + "keys_unchecked_small_cells": withheld_keys, "national": national, } return ( @@ -4245,7 +4259,9 @@ def _property_purchases_gate( not exact); its value is HMRC's less the recorded shortfall, which the stage refuses past one fifth, so the gate refuses past the declared share; and the individuals' shares that carry the all-buyers totals onto - households are proper shares. + households are proper shares. A kind whose buyers rest on fewer than ten + sources, which the receipt prints "<10", is flagged unchecked, never + failed (María's ruling of 2026-10-26). """ check = "property_purchases" @@ -4269,8 +4285,19 @@ def _property_purchases_gate( ) if drawn != expected: failures.append(f"{stage}: the receipt draws kinds {drawn}, not {expected}.") + unchecked: list[str] = [] for kind in kinds: name = str(kind.get("property_type")) + if any( + kind.get(field) == "<10" + for field in ( + "fitted_transactions", + "value_shortfall_share", + "fitted_value", + ) + ): + unchecked.append(name) + continue target = _finite_number( kind.get("target_transactions"), label=f"{stage}.{name}.target_transactions" ) @@ -4320,6 +4347,7 @@ def _property_purchases_gate( share = _finite_number(value, label=f"{stage}.derivation.{key}") if not 0.0 < share <= 1.0: failures.append(f"{stage}: derivation {key} is {share}, not a share.") + details["kinds_unchecked_small_cells"] = unchecked if failures: return _fail(stage, check, failures, details) return _pass(stage, check, details) @@ -4335,7 +4363,9 @@ def _regional_home_values_gate( Every declared region has rewritten rows and no more than the stage's rows; no source sits at the value cap beyond the declared count; the knots are the declared basis year and the ranking the declared basis; and the - weighted value stays positive on both sides of the stage. + weighted value stays positive on both sides of the stage. A count the + receipt bands for resting on fewer than ten records is flagged rather + than failed where the band cannot tell (María's ruling of 2026-10-26). """ check = "regional_home_values" @@ -4348,16 +4378,37 @@ def _regional_home_values_gate( failures.append( f"{stage}: the receipt rewrites regions {sorted(rewritten)}, not {regions}." ) - counts = {str(region): int(count) for region, count in rewritten.items()} + # A region the receipt prints "<10" rewrote one to nine rows: it is not + # empty, and it is flagged (a small-cell rule never fails a build, María's + # ruling of 2026-10-26). The sum check takes it at its lower bound. + banded = sorted( + str(region) for region, count in rewritten.items() if count == "<10" + ) + counts = { + str(region): 1 if count == "<10" else int(count) + for region, count in rewritten.items() + } empty = sorted(region for region, count in counts.items() if count <= 0) if empty: failures.append(f"{stage}: no row is rewritten in {empty}.") - rows = int(evidence.get("rows", 0)) - if sum(counts.values()) > rows: + rows = evidence.get("rows", 0) + if rows != "<10" and sum(counts.values()) > int(rows): failures.append(f"{stage}: more rows are rewritten than the stage carries.") - at_cap = int(evidence.get("sources_at_cap", -1)) + at_cap = evidence.get("sources_at_cap", -1) maximum_at_cap = int(parameters["maximum_sources_at_cap"]) - if not 0 <= at_cap <= maximum_at_cap: + cap_unchecked = False + if at_cap in _SUPPORT_BAND_BOUNDS: + # The receipt bands the count: it fails only when the whole band is + # past the limit, and a band straddling the limit is flagged. + lowest, highest = _SUPPORT_BAND_BOUNDS[at_cap] + if lowest > maximum_at_cap: + failures.append( + f"{stage}: {at_cap} sources sit at the value cap " + f"(limit {maximum_at_cap})." + ) + elif highest > maximum_at_cap: + cap_unchecked = True + elif not 0 <= int(at_cap) <= maximum_at_cap: failures.append( f"{stage}: {at_cap} sources sit at the value cap (limit {maximum_at_cap})." ) @@ -4376,7 +4427,12 @@ def _regional_home_values_gate( value = _finite_number(evidence.get(side), label=f"{stage}.{side}") if value <= 0.0: failures.append(f"{stage}: {side} is not positive.") - details = {"regions": regions, "sources_at_cap": at_cap} + details = { + "regions": regions, + "sources_at_cap": at_cap, + "regions_rewritten_under_ten": banded, + "sources_at_cap_unchecked": cap_unchecked, + } if failures: return _fail(stage, check, failures, details) return _pass(stage, check, details) @@ -4384,6 +4440,8 @@ def _regional_home_values_gate( #: The support bands the take-up receipts print (receipt_counts). _SUPPORT_BANDS = frozenset({"<10", "10-29", "30+"}) +#: The counts each band stands for, lowest and highest. +_SUPPORT_BAND_BOUNDS = {"<10": (1, 9), "10-29": (10, 29), "30+": (30, math.inf)} def _legacy_closure_take_up_gate( @@ -4412,6 +4470,7 @@ def _legacy_closure_take_up_gate( if not isinstance(combinations, Mapping) or not combinations: failures.append(f"{stage}: the receipt carries no combinations.") combinations = {} + withheld_flags = 0 for name, combination in combinations.items(): combination = _mapping(combination, label=f"{stage}.combinations.{name}") rate = _finite_number(combination.get("rate"), label=f"{stage}.{name}.rate") @@ -4425,7 +4484,9 @@ def _legacy_closure_take_up_gate( if combination.get("support") not in _SUPPORT_BANDS: failures.append(f"{stage}: {name} prints no support band.") flag = combination.get("rate_unreachable") - if not (flag is None or isinstance(flag, bool) or flag == "<10"): + if flag == "<10": + withheld_flags += 1 + elif not (flag is None or isinstance(flag, bool)): failures.append(f"{stage}: {name} flags {flag!r} as unreachable.") # A drawn cohort on fewer than ten sources prints the share withheld. printed = evidence.get("great_britain_weighted_share_claiming_at_closure") @@ -4435,7 +4496,11 @@ def _legacy_closure_take_up_gate( ) if not 0.0 <= share <= 1.0: failures.append(f"{stage}: the share claiming at closure is {share}.") - details = {"combinations": len(combinations)} + details = { + "combinations": len(combinations), + "unreachable_flags_withheld": withheld_flags, + "share_claiming_at_closure_withheld": printed == "<10", + } if failures: return _fail(stage, check, failures, details) return _pass(stage, check, details) diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/support_floor.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/support_floor.py index c4b802a781..87270e3f0d 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/support_floor.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/support_floor.py @@ -5,11 +5,9 @@ row that some households carry stays bound however few they are: a cell that rests on fewer than ten records is no reason to leave a row out, and only a measured distortion of the calibration is (María's rule of 2026-10-21, which -replaced the floor of ten she signed on 2026-10-16). What the licence asks of -such a row is that its model figures stay in the build: the diagnostics, the -gate evidence and every written surface withhold the figures of a row that -fewer than ten distinct source households carry -(:func:`microcosm.build.uk_runtime.diagnostics.uk_withheld_rows`). +replaced the floor of ten she signed on 2026-10-16). Such a row's model +figures ship with every other row's: the outputs go only to the licensed +private repository (her ruling of 2026-10-26). The floor is declared once, in the ``support_floor`` block of ``uk/calibration_measure_exclusions.json`` (schema 4), and signed there; its @@ -182,7 +180,7 @@ def uk_support_floor_from_payload(block: Mapping[str, Any]) -> UKSupportFloor: raise ValueError( f"UK support floor must be {UK_SUPPORT_FLOOR_VALUE}: a row that any source " "household carries stays bound however few they are (María's rule of " - "2026-10-21), and the figures of a thin row are withheld, not the row." + "2026-10-21)." ) scopes = _scopes_from_payload(block["scopes"]) for field in _TEXT_FIELDS: diff --git a/packages/microcosm-build/tests/engine_free/shared/test_gates.py b/packages/microcosm-build/tests/engine_free/shared/test_gates.py index c1cae70459..de7ad611d6 100644 --- a/packages/microcosm-build/tests/engine_free/shared/test_gates.py +++ b/packages/microcosm-build/tests/engine_free/shared/test_gates.py @@ -56,7 +56,7 @@ def _area_support(rows=2, ess=2.0, sources=2): ) -def test_area_support_reviewed_exclusion_records_the_floors_missed() -> None: +def test_area_support_reviewed_exclusion_records_measured_shortfalls() -> None: record = {"approved_by": "reviewer", "adjudication": "uk-data#123"} result = area_support_gate( _area_support(), @@ -70,17 +70,18 @@ def test_area_support_reviewed_exclusion_records_the_floors_missed() -> None: assert result.passed assert result.details["excluded_area_count"] == 1 excluded = result.details["reviewed_exclusions"]["constituency/C1"] - # The floors the area misses and the signed record; never the area's - # rows, ESS or sources, which a release withholds (microcosm#1301). + # The area's measured support beside the floors it misses (María's ruling + # of 2026-10-26 dropped the withholding of microcosm#1301). assert excluded == { - "shortfalls": ["rows < 50", "ESS < 50", "distinct sources < 50"], + "shortfalls": ["rows 2 < 50", "ESS 2 < 50", "distinct sources 2 < 50"], + "rows": 2, + "ess": 2.0, + "sources": 2, "record": record, } -def test_area_support_details_and_failures_carry_no_area_figures() -> None: - from microcosm.data.contract import _uk_dense_disclosure_findings - +def test_area_support_details_and_failures_state_the_area_figures() -> None: support = pd.concat( [ _area_support(rows=30, ess=25.5, sources=20), @@ -99,15 +100,17 @@ def test_area_support_details_and_failures_carry_no_area_figures() -> None: ) assert result.failures == ( - "constituency/C2: rows < 50, ESS < 50, distinct sources < 50", + "constituency/C2: rows 40 < 50, ESS 35 < 50, distinct sources 45 < 50", ) assert result.details["by_geography_level"] == { - "constituency": {"areas_checked": 2, "areas_below_floor": 2} + "constituency": { + "areas_checked": 2, + "areas_below_floor": 2, + "minimum_rows": 30, + "minimum_effective_sample_size": 25.5, + "minimum_distinct_sources": 20, + } } - shipped = {"details": result.details, "failures": list(result.failures)} - assert _uk_dense_disclosure_findings("uk_local_gates.json", shipped) == [] - for figure in ("30", "25.5", "20", "40", "35", "45"): - assert all(figure not in failure for failure in result.failures) def test_area_support_stale_and_unknown_exclusions_fail() -> None: @@ -721,6 +724,9 @@ def test_passes_both_declared_grains(self) -> None: assert result.details["by_geography_level"]["constituency"] == { "areas_checked": 1, "areas_below_floor": 0, + "minimum_rows": 60, + "minimum_effective_sample_size": 52.0, + "minimum_distinct_sources": 55, } def test_names_every_floor_breach(self) -> None: @@ -739,7 +745,7 @@ def test_names_every_floor_breach(self) -> None: assert not result.passed assert result.failures == ( - "constituency/C1: rows < 50, ESS < 50, distinct sources < 50", + "constituency/C1: rows 49 < 50, ESS 47.5 < 50, distinct sources 48 < 50", ) def test_roster_omission_refuses_instead_of_shrinking_the_surface(self) -> None: diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_battery_bindings.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_battery_bindings.py index a830d53361..ca7f71d062 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_battery_bindings.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_battery_bindings.py @@ -228,7 +228,6 @@ def _parity(**overrides) -> SimpleNamespace: "candidate_targets": {"ons/population"}, "reference_targets": {"ons/population"}, "target_relative_errors": {"ons/population": 0.01}, - "withheld_targets": frozenset(), } fields.update(overrides) return SimpleNamespace(**fields) @@ -264,7 +263,7 @@ def _fixture_coverage_registry(): evaluator=lambda context, parameters: GateResult( name="take_up_signal", passed=True ), - parameter_keys=frozenset({"maximum_share_deviation"}), + parameter_keys=UK_GATE_REGISTRY["take_up_signal"].parameter_keys, ), "enum_domain": UKGateBinding( name="enum_domain", @@ -1147,36 +1146,21 @@ def test_seeded_defects_fail_the_expected_gates(self) -> None: "uk_target_fit", } <= failed - def test_the_fit_gate_decides_on_the_published_national_rows(self) -> None: - """María's rule of 2026-10-21: a thin national row is bound, its figures kept. - - The fit gate neither checks nor names a withheld row, and counts it; a - published row's breach still fails the gate. - """ + def test_the_fit_gate_judges_a_thin_national_row(self) -> None: + """María's ruling of 2026-10-26: no row's figures are withheld, so the + fit gate judges a row however few source households carry it.""" thin = "dwp.uc.payment_distribution_single_thin@2025" - withheld = _parity( + parity = _parity( candidate_targets={"ons/population", thin}, reference_targets={"ons/population", thin}, target_relative_errors={"ons/population": 0.01, thin: -0.60}, - withheld_targets=frozenset({thin}), - ) - battery = _run_battery(_tables(), parity=withheld) - fit = {o.entry.id: o for o in battery.outcomes}["uk_target_fit"] - assert fit.status is GateStatus.PASSED, fit.result.failures - assert fit.result.details["withheld_targets"] == 1 - assert thin not in str(fit.result.details) - breached = _parity( - candidate_targets={"ons/population", thin}, - reference_targets={"ons/population", thin}, - target_relative_errors={"ons/population": -0.40, thin: -0.60}, - withheld_targets=frozenset({thin}), ) - battery = _run_battery(_tables(), parity=breached) + battery = _run_battery(_tables(), parity=parity) fit = {o.entry.id: o for o in battery.outcomes}["uk_target_fit"] assert fit.status is GateStatus.FAILED - assert fit.result.failures - assert all(thin not in failure for failure in fit.result.failures) + assert fit.result.details["failing_targets"] == {thin: -0.60} + assert "withheld_targets" not in fit.result.details class TestUnevidencedArms: @@ -2624,18 +2608,18 @@ def test_the_national_register_is_refused_on_the_local_surface( self._evaluate(monkeypatch, uk_gates, {}, -0.30, parameters=parameters) -class TestWithheldBrmaRows: - """The production local fit bindings on a withheld BRMA row (microcosm#1262). +class TestThinRowsAreJudged: + """The production local fit bindings on a thin BRMA row. - María's rulings of 2026-10-17 and 2026-10-19: a BRMA row resting on fewer - than ten source households keeps its place without its figures, and both - fit gates decide on the published rows and count the withheld ones. + María's ruling of 2026-10-26 dropped the withholding of microcosm#1262: a + row resting on fewer than ten source households keeps its figures, and + both fit gates judge it with every other row. """ - WITHHELD = "private_rent/S33999999/rent/private_rent_brma" + THIN = "private_rent/S33999999/rent/private_rent_brma" @staticmethod - def _rows(flag: bool = True) -> list[dict]: + def _rows() -> list[dict]: rows = [ { "family": "private_rent", @@ -2651,7 +2635,6 @@ def _rows(flag: bool = True) -> list[dict]: "area_code": "S33999999", "metric": "rent/private_rent_brma", "relative_error": -0.4, - "model_figures_withheld": flag, }, { "family": "private_rent", @@ -2682,109 +2665,41 @@ def _evaluate(self, monkeypatch, uk_gates, gate_id, rows, register=None): entry.parameters, ) - def _guard(self, result: GateResult) -> None: - from microcosm.build.uk_runtime.diagnostics import ( - uk_refuse_named_withheld_rows, - ) - - uk_refuse_named_withheld_rows( - {"failures": list(result.failures), "details": result.details}, - names=frozenset(), - keys=frozenset({self.WITHHELD}), - ) - - def test_the_target_fit_decides_on_the_published_rows( - self, monkeypatch, uk_gates - ) -> None: - """María's ruling of 2026-10-19: a withheld row is neither checked nor named. - - The withheld row misses its target by 40%, so a check over every row - would fail on it; the gate fails on the published row beyond the - bound alone, and counts the withheld one. - """ + def test_the_target_fit_judges_the_thin_row(self, monkeypatch, uk_gates) -> None: + """The thin row misses its target by 40% and fails beside the + published row beyond the bound; nothing is counted as withheld.""" result = self._evaluate( monkeypatch, uk_gates, "uk_local_target_fit", self._rows() ) assert result.passed is False published = "private_rent/E06000004/rent/private_rent" - assert result.details["failing_targets"] == {published: 0.30} - assert result.details["targets_checked"] == 7 - assert result.details["withheld_targets"] == 1 - assert "withheld_failing_targets" not in result.details - self._guard(result) - - def test_a_withheld_row_inside_the_bound_reads_the_same( - self, monkeypatch, uk_gates - ) -> None: - """Inside or beyond the bound, the gate's output does not move.""" - - rows = self._rows() - rows[6]["relative_error"] = 0.01 - inside = self._evaluate(monkeypatch, uk_gates, "uk_local_target_fit", rows) - beyond = self._evaluate( - monkeypatch, uk_gates, "uk_local_target_fit", self._rows() - ) - assert inside == beyond + assert result.details["failing_targets"] == {published: 0.30, self.THIN: -0.4} + assert result.details["targets_checked"] == 8 + assert "withheld_targets" not in result.details - def test_a_withheld_rows_register_entry_is_set_aside( + def test_the_thin_rows_register_entry_excuses_it( self, monkeypatch, uk_gates ) -> None: - """An entry for a withheld row neither excuses, rots nor names it.""" - - result = self._evaluate( - monkeypatch, - uk_gates, - "uk_local_target_fit", - self._rows(), - register={self.WITHHELD: _receipt()}, - ) - assert self.WITHHELD not in result.details["reviewed_exclusions"] - assert self.WITHHELD not in result.details["dormant_exclusions"] - assert self.WITHHELD not in result.details["stale_exclusions"] - self._guard(result) - - def test_a_withheld_rows_entry_for_another_line_is_set_aside( - self, monkeypatch, uk_gates - ) -> None: - """The fourth review of #1305: an out-of-line entry named the row. - - An entry scoped to the national line is listed as set aside on the - local one; for a withheld row it is left out of that list too. - """ - result = self._evaluate( monkeypatch, uk_gates, "uk_local_target_fit", self._rows(), - register={self.WITHHELD: _receipt(release_lines=("national",))}, + register={self.THIN: _receipt()}, ) - assert "out_of_line_exclusions" not in result.details - self._guard(result) + assert self.THIN in result.details["reviewed_exclusions"] + assert self.THIN not in result.details["failing_targets"] - def test_family_fit_rests_on_the_published_rows( - self, monkeypatch, uk_gates - ) -> None: + def test_family_fit_counts_every_row(self, monkeypatch, uk_gates) -> None: result = self._evaluate( monkeypatch, uk_gates, "uk_local_per_family_fit", self._rows() ) - assert result.details["family_sizes"] == {"private_rent": 7} + assert result.details["family_sizes"] == {"private_rent": 8} assert result.details["family_within_shares"]["private_rent"] == pytest.approx( - 6 / 7 - ) - assert result.details["withheld_targets"] == {"private_rent": 1} - self._guard(result) - - def test_an_unflagged_row_is_checked_and_named(self, monkeypatch, uk_gates) -> None: - """The guard bites: without the flag the row is named, and refused.""" - - result = self._evaluate( - monkeypatch, uk_gates, "uk_local_target_fit", self._rows(flag=False) + 6 / 8 ) - assert result.details["failing_targets"][self.WITHHELD] == -0.4 - with pytest.raises(ValueError, match="names a withheld row"): - self._guard(result) + assert "withheld_targets" not in result.details class TestGateOnlyAreaSupport: diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_dense_release_assembler.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_dense_release_assembler.py index b4f65127d2..ac9c482a5a 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_dense_release_assembler.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_dense_release_assembler.py @@ -672,13 +672,12 @@ def test_assembler_stages_a_contract_valid_dense_release( assert preflight.main(["--release-dir", str(release_dir)]) == 0 -def test_assembler_warns_on_a_shipped_support_figure_and_still_assembles( +def test_assembler_ships_a_per_area_support_figure_without_a_warning( tmp_path: Path, monkeypatch, capsys ) -> None: - """A per-area support figure in a file the assembler ships byte for byte - is a warning, not a refusal: the directory is assembled, and the warning - is printed and listed in the summary by file and path, never by value - (review of microcosm#1307).""" + """María's ruling of 2026-10-26: a release ships per-area support figures + (microcosm#1301), so one in a file the assembler ships byte for byte + draws no warning.""" monkeypatch.setenv("MICROCOSM_UK_TERMINAL_GATE_SIGNING_KEY", KEY) assembler = _load("assemble_uk_dense_release_dir") candidate, spine, _ = _candidate_dir(tmp_path) @@ -697,16 +696,9 @@ def test_assembler_warns_on_a_shipped_support_figure_and_still_assembles( assert assembler.main(_assemble_args(candidate, spine, None, out)) == 0 captured = capsys.readouterr() - (warning,) = json.loads(captured.out)["warnings"] - assert warning.startswith( - "rowwise_candidate_manifest.json carries 2 per-area support figure(s)" - ) - assert "fit.weakest_areas[0].nonzero_households" in warning - assert f"warning: {warning}" in captured.err - for figure in ("37", "23.75"): - assert figure not in warning - release_dir = out / UK_DENSE_RELEASE_ID - assert dc.validate_release_dir(release_dir) == [warning] + assert json.loads(captured.out)["warnings"] == [] + assert "warning:" not in captured.err + assert dc.validate_release_dir(out / UK_DENSE_RELEASE_ID) == [] def test_assembler_override_assembles_a_pre_lane_run_with_a_recorded_opt_out( @@ -1351,33 +1343,40 @@ def test_assembler_stages_a_graph_built_dense_candidate( assert coverage["holdout"] == {"run": False, "claim": "none"} assert coverage["incumbent"] == {"compared": False} assert {"no_out_of_sample_claim", "no_incumbent_comparison"} <= set(limitations) - # Disclosure (microcosm#1301): every area is below the floors, yet no - # shipped document carries an area's rows, ESS or sources, so the - # contract has nothing to warn about. The signed report names the floors - # each excused area misses; the manifest counts areas; the release - # manifest names the areas by code. + # Every area is below the floors, and the release ships each area's + # support figures (María's ruling of 2026-10-26 dropped their withholding, + # microcosm#1301): the signed report states each excused area's rows, ESS + # and sources, and the manifest the minima; the contract warns on none. assert dc.validate_release_dir(release_dir) == [] assert summary["warnings"] == [] - for path in sorted(release_dir.glob("*.json")): - payload = json.loads(path.read_text()) - assert dc._uk_dense_disclosure_findings(path.name, payload) == [], path.name signed = json.loads((release_dir / "uk_local_gates.json").read_text()) shipped_exclusions = signed["gates"]["uk_local_area_support"]["details"][ "reviewed_exclusions" ] assert set(shipped_exclusions) == set(excused) assert all( - set(entry) == {"shortfalls", "record"} for entry in shipped_exclusions.values() + set(entry) == {"shortfalls", "rows", "ess", "sources", "record"} + for entry in shipped_exclusions.values() ) shipped_manifest = json.loads( (release_dir / "rowwise_candidate_manifest.json").read_text() ) + level_support = { + "areas_checked": 2, + "areas_below_floor": 2, + "min_assigned_households": 1, + "min_nonzero_households": 1, + "min_effective_sample_size": 1.0, + "min_nonzero_source_households": 1, + } assert shipped_manifest["support"] == { "areas_checked": 4, "areas_below_floor": 4, + "min_assigned_households": 1, + "min_nonzero_households": 1, + "min_effective_sample_size": 1.0, "by_geography_level": { - level: {"areas_checked": 2, "areas_below_floor": 2} - for level in ("constituency", "local_authority") + level: level_support for level in ("constituency", "local_authority") }, } release_manifest = json.loads((release_dir / "release_manifest.json").read_text()) diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_dense_signoff_draft.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_dense_signoff_draft.py index d451c48f8c..8d29d47c1b 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_dense_signoff_draft.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_dense_signoff_draft.py @@ -335,15 +335,16 @@ def _support_frame(support) -> pd.DataFrame: def _target_rows(national, local, withheld=frozenset()) -> list[dict]: - """The embedded rows; a ``withheld`` local key reads blank (microcosm#1262).""" + """The embedded rows; a ``withheld`` national name or local key reads + blank (microcosm#1262, María's rule of 2026-10-21).""" rows = [ { "name": name, "target_name": name, "target": 100.0, - "estimate": 100.0 * (1.0 + error), - "relative_error": error, - "abs_relative_error": abs(error), + "estimate": None if name in withheld else 100.0 * (1.0 + error), + "relative_error": None if name in withheld else error, + "abs_relative_error": None if name in withheld else abs(error), "family": "synthetic_national", "geography_level": "country", "area_type": "country", @@ -380,7 +381,7 @@ def _target_rows(national, local, withheld=frozenset()) -> list[dict]: if withheld: for row in rows: key = f"{row['family']}/{row['area_code']}/{row['metric']}" - row["model_figures_withheld"] = key in withheld + row["model_figures_withheld"] = key in withheld or row["name"] in withheld return rows @@ -482,14 +483,16 @@ def write_run( targets = _target_rows(national, local, withheld) support_frame = _support_frame(support) results = { + # The national binding counts the surface's whole withheld set, as + # its parity evidence carries it; the local one its own cells. "uk_target_fit": _fit( - national, registers["uk_target_fit"]["exclusions"], clock + national, registers["uk_target_fit"]["exclusions"], clock, withheld ), "uk_local_target_fit": _fit( {f"{f}/{a}/{m}": e for f, a, m, e in local}, registers["uk_local_target_fit"]["exclusions"], clock, - withheld, + frozenset(withheld) - set(national), ), "uk_local_area_support": _area( support_frame, registers["uk_local_area_support"], clock @@ -2045,9 +2048,10 @@ def test_verify_fails_a_build_2_that_did_not_stand_on_the_sign_off( assert any(message in line for line in result["failures"]), result["failures"] -def test_verify_warns_on_a_support_figure_in_the_signed_report(build_1, repo, tmp_path): - """The signed local report gets the release's disclosure walk, which - warns rather than fails, as the release contract does (microcosm#1301).""" +def test_verify_no_longer_walks_the_signed_report(build_1, repo, tmp_path): + """María's ruling of 2026-10-26: a release ships per-area support figures, + so a figure in the signed local report draws no warning; the drafted + entries, which go into a public PR, keep their own walk.""" registers = _signed_off(build_1, repo, tmp_path) build_registers = json.loads(json.dumps(registers)) _figure_in_reason(build_registers) @@ -2060,10 +2064,9 @@ def test_verify_warns_on_a_support_figure_in_the_signed_report(build_1, repo, tm ) status, result = verify(build_2, repo, tmp_path) assert status == 0, result["failures"] - assert any( - line.startswith("contract: ") and "measured support" in line - for line in result["warnings"] - ), result["warnings"] + assert not any("measured support" in line for line in result["warnings"]), result[ + "warnings" + ] def test_verify_surfaces_a_tampered_local_report(build_1, repo, tmp_path): @@ -2513,3 +2516,27 @@ def test_the_tool_drafts_only_gate_only_resources_when_they_are_declared(): solve_scope = pytest.importorskip("microcosm.build.uk_runtime.solve_scope") declared = set(solve_scope.UK_GATE_ONLY_RESOURCES) assert {spec.resource for spec in TOOL.REGISTERS} <= declared + + +def test_a_withheld_national_row_is_counted_and_never_signed(repo, tmp_path): + """A thin national row is withheld too (María's rule of 2026-10-21): the + national fit gate counts the surface's whole withheld set and decides on + the published rows, so the draft signs nothing for it.""" + + national = {**NATIONAL, "synthetic.national_thin@2025": -0.4567} + build = write_run( + tmp_path / "build-1", + registers=build_1_registers(), + national=national, + withheld=frozenset({"synthetic.national_thin@2025", BRMA_CELL}), + local=(*LOCAL, ("private_rent", "S33999999", "rent/private_rent_brma", 0.0)), + ) + out = tmp_path / "draft" + assert draft(build, repo, out) == 0 + receipt = json.loads((out / "signoff_draft.json").read_text()) + assert receipt["signable"] is True + assert ( + "synthetic.national_thin@2025" + not in receipt["registers"]["uk_target_fit"]["add"] + ) + assert "4567" not in (out / "signoff.patch").read_text() diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_desnz_constituency_energy.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_desnz_constituency_energy.py index 8b8b12815d..ba46ee1567 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_desnz_constituency_energy.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_desnz_constituency_energy.py @@ -763,24 +763,6 @@ def test_the_committed_surface_binds_every_great_britain_seat() -> None: } -def test_the_withholding_families_of_the_energy_rows() -> None: - # The kWh rows have no higher-grain parent, so they are checked in their - # regions' blocks, where seats and authorities meet; the gas-connected - # rows join the census household family and its nation controls. - from microcosm.build.uk_runtime.diagnostics import uk_local_family_parents - - families = { - member: (members, parents) - for members, parents in uk_local_family_parents() - for member in members - } - for target_id in ("desnz.subnational.electricity_kwh", "desnz.subnational.gas_kwh"): - assert families[target_id] == (frozenset({target_id}), frozenset()) - members, parents = families["desnz.subnational.gas_connected_households"] - assert "ons.census.households" in members - assert parents - - def test_the_no_gas_cells_reconcile_at_a_declared_zero() -> None: # Orkney and Shetland, councils and seat, have no mains gas: both gas # families count them at zero in reconciliation and bind none of them diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_diagnostics.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_diagnostics.py index 280a9e6b06..21989c5fa2 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_diagnostics.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_diagnostics.py @@ -162,6 +162,9 @@ def test_local_weakest_rollups_pin_family_area_and_country_shapes() -> None: "worst_target", "worst_abs_relative_error", "loss_contribution", + "nonzero_households", + "nonzero_source_households", + "effective_sample_size", } assert [row["country"] for row in areas["countries"]] == [ "England", @@ -179,8 +182,14 @@ def test_local_weakest_rollups_pin_family_area_and_country_shapes() -> None: assert trimmed["n_areas_scored"] == 2 assert [row["area_code"] for row in trimmed["bottom_by_fit"]] == ["W07000041"] - # The rows ship in a release, so they carry the area's floor flag, never - # its rows, ESS or sources (microcosm#1301). + # Each row carries its area's rows, ESS and sources, and the floor flag + # beside them when the table has it (María's ruling of 2026-10-26). + wales_row = areas["bottom_by_fit"][0] + assert ( + wales_row["nonzero_households"], + wales_row["nonzero_source_households"], + wales_row["effective_sample_size"], + ) == (80, 70, 65.0) flagged = uk_weakest_areas_by_fit( rows, support.assign(support_below_floor=[True, False]) ) @@ -190,17 +199,9 @@ def test_local_weakest_rollups_pin_family_area_and_country_shapes() -> None: assert all( type(row["support_below_floor"]) is bool for row in flagged["bottom_by_fit"] ) - for row in flagged["bottom_by_fit"]: - assert not { - "nonzero_households", - "nonzero_source_households", - "effective_sample_size", - } & set(row) - # Only the codes are required of the support table. - codes_only = uk_weakest_areas_by_fit( - rows, support.loc[:, ["geography_level", "area_code"]] - ) - assert codes_only["bottom_by_fit"] == areas["bottom_by_fit"] + # The support figures are required of the support table. + with pytest.raises(ValueError, match="missing rollup column"): + uk_weakest_areas_by_fit(rows, support.loc[:, ["geography_level", "area_code"]]) def test_local_fit_diagnostics_filter_national_rows_and_pin_support_shape() -> None: @@ -241,15 +242,27 @@ def test_local_fit_diagnostics_filter_national_rows_and_pin_support_shape() -> N "share_failing_cells_in_bottom_ess_decile": 1.0, "spearman_worst_abs_relative_error_vs_ess": -1.0, "worst_areas": [ - {"area_code": "E14000001", "worst_abs_relative_error": 0.3}, - {"area_code": "E14000002", "worst_abs_relative_error": 0.05}, + { + "area_code": "E14000001", + "worst_abs_relative_error": 0.3, + "rows": 2, + "ess": 1.0, + "sources": 1, + }, + { + "area_code": "E14000002", + "worst_abs_relative_error": 0.05, + "rows": 20, + "ess": 20.0, + "sources": 20, + }, ], } assert result["la"]["n_failing_cells"] == 1 assert result["la"]["spearman_worst_abs_relative_error_vs_ess"] is None - # With the floor flag in the support table, each worst area carries it in - # place of its rows, ESS and sources (microcosm#1301). + # With the floor flag in the support table, each worst area carries it + # beside its rows, ESS and sources (María's ruling of 2026-10-26). flagged = uk_support_limited_misses( diagnostics, { @@ -258,18 +271,10 @@ def test_local_fit_diagnostics_filter_national_rows_and_pin_support_shape() -> N }, max_abs_relative_error=0.25, ) - assert flagged["constituency"]["worst_areas"] == [ - { - "area_code": "E14000001", - "worst_abs_relative_error": 0.3, - "support_below_floor": True, - }, - { - "area_code": "E14000002", - "worst_abs_relative_error": 0.05, - "support_below_floor": True, - }, - ] + assert [ + (area["area_code"], area["rows"], area["support_below_floor"]) + for area in flagged["constituency"]["worst_areas"] + ] == [("E14000001", 2, True), ("E14000002", 20, True)] rows = [ _local_target_row( @@ -317,12 +322,7 @@ def _consumption_columns(n: int) -> dict[str, np.ndarray]: def _diagnostics_case(*, with_skipped: bool = False, with_consumption: bool = False): - """One row per geography level, each carried by one household. - - Every row rests on fewer than ten source households, so a test that is not - about withholding passes an empty withheld set; the withheld path has its - own tests (María's rule of 2026-10-21 withholds a thin row's figures). - """ + """One row per geography level, each carried by one household.""" levels_and_weights = ( ("national", 11.0), @@ -566,7 +566,6 @@ def test_payload_preserves_common_schema_and_adds_versioned_uk_evidence() -> Non frame, target_geography_levels=geography, target_registry=registry, - withheld=frozenset(), build={"release_id": "fixture"}, ) @@ -776,7 +775,6 @@ def test_drift_flags_reach_the_payload_as_warnings() -> None: frame, target_geography_levels=geography, target_registry=registry, - withheld=frozenset(), ) flagged = [ warning @@ -876,7 +874,6 @@ def test_payload_carries_the_consumption_drift_when_the_frame_has_it() -> None: frame, target_geography_levels=geography, target_registry=registry, - withheld=frozenset(), ) drift = payload["uk_diagnostics"]["consumption_drift"] @@ -906,7 +903,6 @@ def test_uk_payload_shared_layer_matches_shared_diagnostics_format() -> None: frame, target_geography_levels=geography, target_registry=registry, - withheld=frozenset(), build=build, ) @@ -963,7 +959,6 @@ def test_skipped_target_counts_as_a_geography_non_pass() -> None: frame, target_geography_levels=geography, target_registry=registry, - withheld=frozenset(), ) assert len(payload["skipped"]) == 1 @@ -991,7 +986,6 @@ def test_skipped_target_counts_as_a_geography_non_pass() -> None: frame, target_geography_levels=missing_skipped, target_registry=registry, - withheld=frozenset(), ) @@ -1064,7 +1058,6 @@ def test_writer_round_trips_strict_json(tmp_path: Path) -> None: frame, target_geography_levels=geography, target_registry=registry, - withheld=frozenset(), ) assert isinstance(outcome, DiagnosticsWriteSuccess) @@ -1075,7 +1068,6 @@ def test_writer_round_trips_strict_json(tmp_path: Path) -> None: frame, target_geography_levels=geography, target_registry=registry, - withheld=frozenset(), ) ) invalid = write_uk_calibration_diagnostics( @@ -1084,7 +1076,6 @@ def test_writer_round_trips_strict_json(tmp_path: Path) -> None: frame, target_geography_levels=geography, target_registry=registry, - withheld=frozenset(), build={"not_json": object()}, ) assert isinstance(invalid, DiagnosticsWriteFailure) @@ -1118,7 +1109,6 @@ def test_written_uk_diagnostics_match_the_published_json_schema( target_geography_levels=geography, target_registry=registry, build={"release_id": "fixture"}, - withheld=frozenset(), ) assert isinstance(outcome, DiagnosticsWriteSuccess) @@ -1144,7 +1134,6 @@ def test_writer_rejects_nested_non_finite_build_provenance( frame, target_geography_levels=geography, target_registry=registry, - withheld=frozenset(), build={"nested": [{"value": value}]}, ) @@ -1173,7 +1162,6 @@ def fail_replace(_temporary, _output): frame, target_geography_levels=geography, target_registry=registry, - withheld=frozenset(), ) assert isinstance(outcome, DiagnosticsWriteFailure) @@ -1214,7 +1202,6 @@ def canonical_writer( frame, target_geography_levels=geography, target_registry=registry, - withheld=frozenset(), ) assert isinstance(outcome, DiagnosticsWriteSuccess) @@ -1339,13 +1326,13 @@ def test_copies_without_the_lineage_key_refuse(self) -> None: uk_support_family_weights(household) -def test_a_thin_brma_row_keeps_its_place_but_not_its_model_figures() -> None: - """María's ruling of 2026-10-17 (#1305 review): ten source households per BRMA row. +def test_a_thin_row_keeps_its_model_figures() -> None: + """María's ruling of 2026-10-26 dropped the withholding of microcosm#1262. - One BRMA row rests on three source households, the other on eleven. The - thin row stays in the payload with its model figures null and a note; - it counts as scored but never as passing, and stays out of the family - rollup, so nothing published can be differenced to recover it. + One BRMA row rests on three source households, the other on eleven. Both + keep their model figures and carry no withholding note or carrier + verdict; both count in the pass rates and the family rollup, and the + totals are the solve's own. """ n = 14 @@ -1412,10 +1399,13 @@ def test_a_thin_brma_row_keeps_its_place_but_not_its_model_figures() -> None: ) rows = {row["target_name"]: row for row in payload["targets"]} thin, wide = rows["thin_brma_target"], rows["wide_brma_target"] - assert thin["final_estimate"] is None and thin["relative_error"] is None - assert thin["within_tolerance"] is None - assert "model_figures_withheld" in thin["metadata"] + assert thin["final_estimate"] == pytest.approx(6.0) + assert thin["relative_error"] == pytest.approx(-0.4) assert wide["final_estimate"] == pytest.approx(14.0) + for row in (thin, wide): + metadata = row.get("metadata") or {} + assert "model_figures_withheld" not in metadata + assert "carrier_floor_met" not in metadata (brma,) = [ row for row in payload["uk_diagnostics"]["target_pass_rates_by_geography_level"] @@ -1423,1561 +1413,8 @@ def test_a_thin_brma_row_keeps_its_place_but_not_its_model_figures() -> None: ] assert (brma["n_targets"], brma["n_scored"], brma["n_within_10pct"]) == (2, 2, 0) (family,) = payload["uk_diagnostics"]["weakest_families"] - assert family["n_targets"] == 1 and family["worst_target"] == wide["name"] - - -def test_a_thin_national_row_keeps_its_place_but_not_its_model_figures() -> None: - """María's rule of 2026-10-21: a national row is bound however thin it is. - - The BRMA rule now covers national rows. One national row rests on three source - households and stays bound, its model figures null and noted; the other, - on eleven, publishes. The withheld block restates the totals over the - published row, and no row is told it met a BRMA floor. - """ - - n = 14 - sources = [0, 0, 1, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10] - household = pd.DataFrame( - { - "household_id": np.arange(n, dtype=np.int64), - "source_household_id": np.asarray(sources, dtype=np.int64), - _SPI_COLUMN: [False] * n, - _CG_COLUMN: [False] * n, - "thin_measure": [1.0] * 6 + [0.0] * 8, - "wide_measure": [1.0] * n, - } - ) - specs = [ - TargetSpec( - name=name, - entity="household", - value=10.0, - measure=measure, - period=2023, - source="Synthetic UK diagnostics fixture", - family="dwp_universal_credit", - hierarchy=_fixture_hierarchy(name, "national"), - ) - for name, measure in ( - ("thin_payment_band", "thin_measure"), - ("wide_payment_band", "wide_measure"), - ) - ] - geography = {f"{spec.name}@2023": "national" for spec in specs} - weights = np.ones(n) - frame = Frame( - { - "person": pd.DataFrame( - { - "person_id": np.arange(n, dtype=np.int64), - "person_household_id": np.arange(n, dtype=np.int64), - } - ), - "household": household, - }, - EntitySchema(group_entities=("household",)), - {"household": Weights(weights, WeightKind.DESIGN)}, - ) - registry = TargetRegistry(specs, country="uk") - result = score_targets(frame, registry.to_target_set(), weights=weights) - payload = uk_calibration_diagnostics_payload( - result, - frame, - target_geography_levels=geography, - target_registry=registry, - ) - rows = {row["target_name"]: row for row in payload["targets"]} - thin, wide = rows["thin_payment_band"], rows["wide_payment_band"] - assert thin["final_estimate"] is None and thin["relative_error"] is None - assert "model_figures_withheld" in thin["metadata"] - assert "carrier_floor_met" not in (thin.get("metadata") or {}) - assert wide["final_estimate"] == pytest.approx(14.0) - (national,) = [ - row - for row in payload["uk_diagnostics"]["target_pass_rates_by_geography_level"] - if row["geography_level"] == "national" - ] - assert (national["n_targets"], national["n_scored"]) == (2, 2) - block = payload["uk_diagnostics"]["model_figures_withheld"] - assert block["targets"] == 1 and block["totals_basis"] == "published_rows" - assert payload["loss_trajectory"] == [] - - -def test_a_thin_row_is_withheld_at_every_level() -> None: - """María's rule of 2026-10-21, and her ruling of 2026-10-23 on the local line. - - A row resting on fewer than ten source households keeps its place without - its figures at every level; the area-support rule still decides which - constituency and authority rows bind. - """ - - from types import SimpleNamespace - - from scipy import sparse - - from microcosm.build.uk_runtime.diagnostics import uk_withheld_rows - - n = 12 - matrix = sparse.csr_array( - (np.ones(3), (np.zeros(3, dtype=int), np.arange(3))), shape=(1, n) - ) - problem = SimpleNamespace(matrix=matrix, names=["thin_row@E14000001@2025"]) - frame = Frame( - { - "person": pd.DataFrame( - { - "person_id": np.arange(n, dtype=np.int64), - "person_household_id": np.arange(n, dtype=np.int64), - } - ), - "household": pd.DataFrame( - { - "household_id": np.arange(n, dtype=np.int64), - "source_household_id": np.arange(n, dtype=np.int64), - "region": ["LONDON"] * n, - } - ), - }, - EntitySchema(group_entities=("household",)), - {"household": Weights(np.ones(n), WeightKind.DESIGN)}, - ) - # A local row names its contract target (Vahid's third review of #1383, - # item 33); this one ties to no family. - rows = [ - { - "name": "thin_row@E14000001@2025", - "metadata": {"contract_target_id": "fixture.thin_row"}, - } - ] - for level, withheld in ( - ("national", True), - ("region", True), - ("brma", True), - ("statistical_scope", True), - ("constituency", True), - ("local_authority", True), - ("la", True), - ): - found = uk_withheld_rows( - problem, np.ones(n), frame, rows, {"thin_row@E14000001@2025": level} - ) - assert (found == {"thin_row@E14000001@2025"}) is withheld, level - - -def _withheld_sets( - rows: dict[str, list[int]], - n: int, - values: dict[str, float | list[float]] | None = None, - sources: list[float] | None = None, - levels: dict[str, str] | None = None, - regions: list[str] | None = None, - targets: dict[str, str] | None = None, - tie_targets: bool = True, -) -> tuple[set[str], set[str]]: - """``uk_withheld_row_sets`` over rows given by the households that carry them. - - Every household is its own source household (or ``sources``) and carries - weight one. A row's entries are one, or its ``values`` (one for all its - households, or one each). ``regions`` gives each household's region, and - ``targets`` a row's contract target. Any other row gets a contract target - no family holds, as a local row must name one; ``tie_targets=False`` - leaves the other rows without one. - """ - - from types import SimpleNamespace - - from scipy import sparse - - from microcosm.build.uk_runtime.diagnostics import uk_withheld_row_sets - - names = list(rows) - dense = np.zeros((len(names), n)) - for position, name in enumerate(names): - dense[position, rows[name]] = (values or {}).get(name, 1.0) - problem = SimpleNamespace(matrix=sparse.csr_array(dense), names=names) - frame = Frame( - { - "person": pd.DataFrame( - { - "person_id": np.arange(n, dtype=np.int64), - "person_household_id": np.arange(n, dtype=np.int64), - } - ), - "household": pd.DataFrame( - { - "household_id": np.arange(n, dtype=np.int64), - "source_household_id": ( - np.arange(n, dtype=np.int64) - if sources is None - else np.asarray(sources) - ), - **({} if regions is None else {"region": regions}), - } - ), - }, - EntitySchema(group_entities=("household",)), - {"household": Weights(np.ones(n), WeightKind.DESIGN)}, - ) - tied = { - name: (targets or {}).get(name) - or (f"test:{name.split('@')[0]}" if tie_targets else None) - for name in names - } - target_rows = [ - {"name": name} - if tied[name] is None - else {"name": name, "metadata": {"contract_target_id": tied[name]}} - for name in names - ] - return uk_withheld_row_sets(problem, np.ones(n), frame, target_rows, levels) - - -def test_a_band_its_total_gives_back_withholds_the_next_smallest_band() -> None: - """Vahid's second review of #1333, item 10, and María's hard rule. - - The total less the published bands gives the thin band back, so the - next-smallest band is withheld beside it, not the total. The two together - rest on fifteen source households, which the published rows may give back. - """ - - thin, beside = _withheld_sets( - { - "total": list(range(30)), - "band_a": [0, 1, 2], - "band_b": list(range(3, 15)), - "band_c": list(range(15, 30)), - }, - 30, - ) - assert (thin, beside) == ({"band_a"}, {"band_b"}) - - -def test_a_thin_top_band_no_row_carries_withholds_the_next_smallest_band() -> None: - """Vahid's second review of #1344, item 17: a thin top band, no thin bound band. - - The top band (above GBP 2,500 a month) is no row, so no row is thin and - no withheld row is given back, but the total less the bound bands gives - the top band's three households back. The smaller bound band is withheld, - so what the published rows give back rests on fifteen households. - """ - - thin, beside = _withheld_sets( - { - "total": list(range(30)), - "band_a": list(range(0, 15)), - "band_b": list(range(15, 27)), - }, - 30, - ) - assert (thin, beside) == (set(), {"band_b"}) - - -def test_a_top_band_resting_on_no_household_withholds_nothing() -> None: - thin, beside = _withheld_sets( - { - "total": list(range(30)), - "band_a": list(range(0, 15)), - "band_b": list(range(15, 30)), - }, - 30, - ) - assert (thin, beside) == (set(), set()) - - -def test_a_household_in_two_bands_still_leaves_the_bands_one_partition() -> None: - """Two benefit units of one household in two bands: half its total each. - - The bands still partition the total, so its thin rest (the top band's - three households) is found and the smaller band withheld. - """ - - thin, beside = _withheld_sets( - { - "total": list(range(30)), - "band_a": list(range(0, 15)), - "band_b": [0, *range(15, 27)], - }, - 30, - values={"total": [2.0, *[1.0] * 29]}, - ) - assert (thin, beside) == (set(), {"band_b"}) - - -def test_bands_beside_regions_of_the_same_total_are_still_checked() -> None: - """The regions partition the total exactly; the bands leave a thin top band. - - Each band crosses both regions, so a band and a region never stand in one - partition, and the bands' rest is measured on its own. - """ - - thin, beside = _withheld_sets( - { - "total": list(range(30)), - "region_1": list(range(0, 15)), - "region_2": list(range(15, 30)), - "band_a": [*range(0, 10), *range(15, 20)], - "band_b": [*range(10, 15), *range(20, 27)], - }, - 30, - ) - assert (thin, beside) == (set(), {"band_b"}) - - -def test_a_constant_multiple_of_a_part_is_withheld_with_it() -> None: - """A count of people beside the count of their households is that part again. - - The people row is four times the units row on the same households, so - once the units row is withheld, the total less a quarter of the people row - would give the three households back. Both are withheld (the adversarial - review of #1344's item 17 fix, 22 October). - """ - - thin, beside = _withheld_sets( - {"total": list(range(30)), "units": list(range(27)), "people": list(range(27))}, - 30, - values={"people": 4.0}, - ) - assert (thin, beside) == (set(), {"people", "units"}) - - -def test_bands_in_another_unit_than_their_total_are_scaled() -> None: - """Monthly bands under a yearly total: a twelfth of the total on each household.""" - - thin, beside = _withheld_sets( - { - "total": list(range(30)), - "band_a": list(range(15)), - "band_b": list(range(15, 27)), - }, - 30, - values={"total": 1200.0, "band_a": 100.0, "band_b": 100.0}, - ) - assert (thin, beside) == (set(), {"band_b"}) - - -def test_a_band_of_two_unit_households_only_still_partitions_its_total() -> None: - """Every household of band_b holds a second unit in band_a: half the total each.""" - - thin, beside = _withheld_sets( - { - "total": list(range(30)), - "band_a": list(range(27)), - "band_b": list(range(15, 27)), - }, - 30, - values={"total": [1.0] * 15 + [2.0] * 12 + [1.0] * 3}, - ) - assert (thin, beside) == (set(), {"band_b"}) - - -def test_income_components_less_their_total_band_are_checked() -> None: - """A total-income band less its published components gives back other income. - - The components hold a different share of the total on each household, and - a count of the band's payers sits inside it too; the count is no member. - """ - - employment = [100.5 + h for h in range(40)] - pension = [20.25 + h / 2 for h in range(10, 40)] - total = [ - employment[h] + (pension[h - 10] if h >= 10 else 0.0) + (3.25 if h < 5 else 0.0) - for h in range(40) - ] - thin, beside = _withheld_sets( - { - "total": list(range(40)), - "employment": list(range(40)), - "pension": list(range(10, 40)), - "payers": list(range(40)), - }, - 40, - values={"total": total, "employment": employment, "pension": pension}, - ) - assert (thin, beside) == (set(), {"pension"}) - - -def test_two_overlapping_parts_less_their_total_give_back_the_overlap() -> None: - """Claimants of either benefit less the claimants of each: five on both.""" - - thin, beside = _withheld_sets( - { - "total": list(range(40)), - "contrib": list(range(25)), - "income": list(range(20, 40)), - }, - 40, - ) - assert (thin, beside) == (set(), {"income"}) - - -def test_a_set_smaller_than_the_largest_group_is_checked() -> None: - """Bands a and b and a third part fit pairwise but pass one together. - - The total less bands a and b alone gives back the nine-household top band - and household 0, which the larger set covers. - """ - - thin, beside = _withheld_sets( - { - "total": list(range(40)), - "band_a": list(range(15)), - "band_b": [0, *range(15, 31)], - "c_other": [0, *range(31, 40)], - }, - 40, - values={"total": [2.0] + [1.0] * 39}, - ) - assert (thin, beside) == (set(), {"band_a"}) - - -def test_bands_crossing_larger_regions_are_still_grouped() -> None: - """Each band misses a region larger than it, which a greedy group takes first.""" - - cells = iter(range(39)) - b0r0, b0r1, b1r1, b1r2, b2r0, b2r2 = ( - [next(cells) for _ in range(6)] for _ in range(6) - ) - top = [next(cells) for _ in range(3)] - thin, beside = _withheld_sets( - { - "total": list(range(39)), - "band_0": b0r0 + b0r1, - "band_1": b1r1 + b1r2, - "band_2": b2r0 + b2r2, - "region_0": b0r0 + b2r0 + top[:1], - "region_1": b0r1 + b1r1 + top[1:2], - "region_2": b1r2 + b2r2 + top[2:], - }, - 39, - ) - assert (thin, beside) == (set(), {"band_0"}) - - -def test_a_total_past_the_search_cap_is_grouped_greedily(monkeypatch) -> None: - """With no work allowed, every total is grouped greedily and named in a warning.""" - - from microcosm.build.uk_runtime import diagnostics - - monkeypatch.setattr(diagnostics, "_RESIDUAL_SEARCH_WORK", 0) - with pytest.warns(UserWarning, match="passed its cap"): - thin, beside = _withheld_sets( - { - "total": list(range(120)), - "region_1": list(range(41)), - "region_2": list(range(41, 82)), - "region_3": list(range(82, 120)), - "band_a": [*range(3, 22), *range(41, 53)], - "band_b": [*range(22, 41), *range(82, 94)], - "band_c": list(range(53, 82)), - "band_d": list(range(94, 120)), - }, - 120, - ) - assert (thin, beside) == (set(), {"band_d"}) - - -def test_households_whose_shares_differ_slightly_stay_in_different_atoms() -> None: - """A large share elsewhere must not round band B's last five households away. - - Band B holds 99.999 of the total's 100 on five households, so the total - less bands A and B rests on those five; a part with a share of a million - on another household beside them changes nothing. - """ - - total = [1.0] + [100.0] * 39 - thin, beside = _withheld_sets( - { - "total": list(range(40)), - "band_a": list(range(20)), - "band_b": list(range(20, 40)), - "big": list(range(10)), - }, - 40, - values={ - "total": total, - "band_a": total[:20], - "band_b": [100.0] * 15 + [99.999] * 5, - "big": [1e6] + [100.0] * 9, - }, - ) - assert (thin, beside) == (set(), {"band_a"}) - - -def test_a_component_in_whole_pounds_is_still_searched() -> None: - """An amount component of whole pounds is no count: three components less - their total give back other income on five households.""" - - whole = [100.0 + h for h in range(40)] - first = [10.25 + h for h in range(20)] - second = [20.5 + h for h in range(20)] - other = {3: 7.31, 8: 7.31, 25: 7.31, 30: 7.31, 33: 7.31} - total = [ - whole[h] + (first[h] if h < 20 else second[h - 20]) + other.get(h, 0.0) - for h in range(40) - ] - thin, beside = _withheld_sets( - { - "total": list(range(40)), - "whole": list(range(40)), - "first": list(range(20)), - "second": list(range(20, 40)), - }, - 40, - values={"total": total, "whole": whole, "first": first, "second": second}, - ) - assert (thin, beside) == (set(), {"first"}) - - -def test_a_part_of_constant_negative_share_is_scaled() -> None: - """The total plus twice a part of share minus a half gives back three households.""" - - thin, beside = _withheld_sets( - {"total": list(range(30)), "loss": list(range(27))}, - 30, - values={"total": 100.0, "loss": -50.0}, - ) - assert (thin, beside) == (set(), {"loss"}) - - -def test_three_components_with_no_thin_pair_are_searched_together() -> None: - """Every component sits on every household, so no pair less the total is - thin; all three less it give back other income on five households.""" - - employment = [100.5 + h for h in range(40)] - pension = [20.25 + h / 4 for h in range(40)] - savings = [3.5 + h / 8 for h in range(40)] - total = [ - employment[h] + pension[h] + savings[h] + (2.75 if h < 5 else 0.0) - for h in range(40) - ] - thin, beside = _withheld_sets( - { - "total": list(range(40)), - "employment": list(range(40)), - "pension": list(range(40)), - "savings": list(range(40)), - }, - 40, - values={ - "total": total, - "employment": employment, - "pension": pension, - "savings": savings, - }, - ) - assert (thin, beside) == (set(), {"employment"}) - - -def test_a_part_above_its_total_on_one_household_is_checked_alone() -> None: - """Twice the total's entry on household 0, so no member; the total less it - still rests on four households.""" - - thin, beside = _withheld_sets( - {"total": list(range(30)), "part": list(range(27))}, - 30, - values={"part": [2.0] + [1.0] * 26}, - ) - assert (thin, beside) == (set(), {"part"}) - - -def test_a_missing_source_id_counts_as_a_source_of_its_own() -> None: - sources = [float(h) for h in range(29)] + [float("nan")] - thin, beside = _withheld_sets( - { - "total": list(range(30)), - "band_a": list(range(15)), - "band_b": list(range(15, 27)), - }, - 30, - sources=sources, - ) - assert (thin, beside) == (set(), {"band_b"}) - - -def test_cells_of_ten_households_clear_a_total_without_a_search(monkeypatch) -> None: - """Twelve regions, each split in two cells of ten: every atom rests on ten - households, so no combination at any weights can be thin.""" - - from microcosm.build.uk_runtime import diagnostics - - def refuse(*_args, **_kwargs): - raise AssertionError("the search ran") - - monkeypatch.setattr(diagnostics._ResidualCheck, "_search", refuse) - rows = {"total": list(range(240))} - for g in range(12): - rows[f"region_{g:02d}"] = list(range(20 * g, 20 * g + 20)) - rows[f"region_{g:02d}_a"] = list(range(20 * g, 20 * g + 10)) - rows[f"region_{g:02d}_b"] = list(range(20 * g + 10, 20 * g + 20)) - assert _withheld_sets(rows, 240) == (set(), set()) - - -def test_a_small_atom_in_the_span_of_large_ones_clears_its_total(monkeypatch) -> None: - """Household 20 holds two units, one in each band: its column is the mean of - the two bands' columns, so nothing can isolate it, and no search runs.""" - - from microcosm.build.uk_runtime import diagnostics - - def refuse(*_args, **_kwargs): - raise AssertionError("the search ran") - - monkeypatch.setattr(diagnostics._ResidualCheck, "_search", refuse) - thin, beside = _withheld_sets( - { - "total": list(range(21)), - "band_a": [*range(10), 20], - "band_b": [*range(10, 20), 20], - }, - 21, - values={"total": [1.0] * 20 + [2.0]}, - ) - assert (thin, beside) == (set(), set()) - - -def test_an_outlier_household_does_not_hide_a_gap_from_the_span_test() -> None: - """Employment less a huge offsetting loss on one household of total one. - - The outlier squashes every other share once a row is scaled to its - largest; two households where the parts fall short of the total by a - hundredth still rest on two source households, and the total less both - parts gives them back (the third adversarial review of item 17). - """ - - total, x, y = {}, {}, {} - for h in range(12): - total[h] = x[h] = 30000.0 + 101.0 * h - for h in range(12, 24): - total[h] = y[h] = 30000.0 + 97.0 * h - for h in range(24, 44): - total[h] = 25000.0 + 89.0 * h - x[h], y[h] = 0.4 * total[h], 0.6 * total[h] - total[44], x[44], y[44] = 1.0, 1e6, 1.0 - 1e6 - for h in (45, 46): - total[h] = 40000.0 + h - x[h], y[h] = 0.4 * total[h], 0.59 * total[h] - thin, beside = _withheld_sets( - {"total": sorted(total), "x": sorted(x), "y": sorted(y)}, - 47, - values={ - "total": [total[h] for h in sorted(total)], - "x": [x[h] for h in sorted(x)], - "y": [y[h] for h in sorted(y)], - }, - ) - assert (thin, beside) == (set(), {"x"}) - - -def test_a_large_atom_short_of_one_by_less_than_the_rounding_is_covered() -> None: - """Twelve households hold 0.6 and 0.4 less five ten-millionths: the search - counts that as covered, so the span test must not count it as a direction - that hides the two-household atom.""" - - delta = 5e-7 - shares = ( - [(0.6, 0.4 - delta)] * 12 - + [(0.3, 0.7)] * 12 - + [(1.0, 0.0)] * 12 - + [(0.2, 0.3)] * 2 - ) - first = [h for h, (a, _) in enumerate(shares) if a] - second = [h for h, (_, b) in enumerate(shares) if b] - thin, beside = _withheld_sets( - {"total": list(range(38)), "p1": first, "p2": second}, - 38, - values={ - "total": 1000.0, - "p1": [1000 * shares[h][0] for h in first], - "p2": [1000 * shares[h][1] for h in second], - }, - ) - assert (thin, beside) == (set(), {"p2"}) - - -def test_a_share_exactly_one_rounding_short_of_one_counts_as_covered_everywhere() -> ( - None -): - """A part holding one less a millionth on ten households and a half on one: - the total less it rests on three, whether or not a copy of the total sits - beside it.""" - - almost = 1 - 1e-6 - for rows in ( - {"total": list(range(13)), "copy": list(range(13)), "part": list(range(11))}, - {"total": list(range(13)), "part": list(range(11))}, - ): - thin, beside = _withheld_sets(rows, 13, values={"part": [almost] * 10 + [0.5]}) - assert (thin, beside) == (set(), {"part"}) - - -def test_an_outlier_on_the_gap_household_itself_is_measured_as_stored() -> None: - """Two households where employment is a thousand times the total and a - matching loss falls short of it by a ten-thousandth: as unit columns the - gap looks tiny, but the total less both parts rests on those two.""" - - total, x, y = {}, {}, {} - for h in range(12): - total[h] = x[h] = 30000.0 + 101.0 * h - for h in range(12, 24): - total[h] = y[h] = 30000.0 + 97.0 * h - for h in range(24, 44): - total[h] = 25000.0 + 89.0 * h - x[h], y[h] = 0.4 * total[h], 0.6 * total[h] - for h in (44, 45): - total[h] = 40000.0 + h - x[h], y[h] = 1000.0 * total[h], (1 - 1000.0 - 1e-4) * total[h] - thin, beside = _withheld_sets( - {"total": sorted(total), "x": sorted(x), "y": sorted(y)}, - 46, - values={ - "total": [total[h] for h in sorted(total)], - "x": [x[h] for h in sorted(x)], - "y": [y[h] for h in sorted(y)], - }, - ) - assert (thin, beside) == (set(), {"x"}) - - -def test_a_small_shortfall_beside_many_bands_is_not_cleared() -> None: - """Three hundred bands of ten; two more households in band 1 hold one less - 2.4 millionths of the total, above the rounding share, so the total less - every band rests on those two.""" - - rows = {"total": list(range(3002))} - for k in range(300): - rows[f"band_{k:03d}"] = list(range(10 * k, 10 * k + 10)) + ( - [3000, 3001] if k == 1 else [] - ) - thin, beside = _withheld_sets( - rows, 3002, values={"band_001": [1.0] * 10 + [1 - 2.4e-6] * 2} - ) - assert (thin, beside) == (set(), {"band_000"}) - - -def test_a_row_given_back_two_ways_loses_a_giver_from_each() -> None: - """Two relations give the thin band back, so one giver of each is withheld. - - While both stand, every giver has a stand-in and the smallest goes first - (the other total's rest); then the first total's bands are the only way - back, and the next-smallest of them goes. - """ - - thin, beside = _withheld_sets( - { - "total": list(range(30)), - "band_a": [0, 1, 2], - "band_b": list(range(3, 15)), - "band_c": list(range(15, 30)), - "other_total": [0, 1, 2, *range(30, 40)], - "other_rest": list(range(30, 40)), - }, - 40, - ) - assert (thin, beside) == ({"band_a"}, {"other_rest", "band_b"}) - - -def test_proportional_thin_rows_are_no_recovery() -> None: - """A thin count and an amount on the same households differ by nothing. - - The amount is twice the count everywhere, so their difference is zero and - no published row gives anything back by it; the total's relation alone - asks for one more band. - """ - - thin, beside = _withheld_sets( - { - "total": list(range(30)), - "band_a_count": [0, 1, 2], - "band_a_amount": [0, 1, 2], - "band_b": list(range(3, 15)), - "band_c": list(range(15, 30)), - }, - 30, - values={"band_a_amount": 2.0}, - ) - assert (thin, beside) == ({"band_a_count", "band_a_amount"}, {"band_b"}) - - -def test_a_thin_row_no_published_row_gives_back_withholds_nothing_more() -> None: - thin, beside = _withheld_sets( - {"band_a": [0, 1, 2], "band_b": list(range(3, 15))}, 15 - ) - assert (thin, beside) == ({"band_a"}, set()) - - -def test_a_row_withheld_beside_a_thin_one_says_so_and_meets_the_schema( - tmp_path: Path, -) -> None: - """The written diagnostics tell a row withheld beside a thin one from it. - - (A row can also be withheld where no row is thin, when a total less its - parts would give back a cell that is no row; it carries the same flag.) - - BRMA rows: the thin band fails the ten-household floor; the band withheld - beside it meets the floor and is flagged ``complementary_withholding``, as - the release contract reads it. The payload, with its null figures, its - notes and its restated totals, is valid against the published schema. - """ - - n = 30 - members = { - "total": range(30), - "band_a": range(3), - "band_b": range(3, 15), - "band_c": range(15, 30), - } - household = pd.DataFrame( - { - "household_id": np.arange(n, dtype=np.int64), - "source_household_id": np.arange(n, dtype=np.int64), - _SPI_COLUMN: [False] * n, - _CG_COLUMN: [False] * n, - } - ) - for name, carriers in members.items(): - household[f"{name}_measure"] = 0.0 - household.loc[list(carriers), f"{name}_measure"] = 1.0 - specs = [ - TargetSpec( - name=name, - entity="household", - value=float(len(carriers)), - measure=f"{name}_measure", - period=2023, - source="Synthetic UK diagnostics fixture", - family="fixture", - hierarchy=_fixture_hierarchy(name, "brma"), - ) - for name, carriers in members.items() - ] - geography = {f"{spec.name}@2023": "brma" for spec in specs} - weights = np.ones(n) - frame = Frame( - { - "person": pd.DataFrame( - { - "person_id": np.arange(n, dtype=np.int64), - "person_household_id": np.arange(n, dtype=np.int64), - } - ), - "household": household, - }, - EntitySchema(group_entities=("household",)), - {"household": Weights(weights, WeightKind.DESIGN)}, - ) - registry = TargetRegistry(specs, country="uk") - result = score_targets(frame, registry.to_target_set(), weights=weights) - path = tmp_path / "calibration_diagnostics.json" - - outcome = write_uk_calibration_diagnostics( - result, - path, - frame, - target_geography_levels=geography, - target_registry=registry, - ) - - assert isinstance(outcome, DiagnosticsWriteSuccess) - document = load_strict_json(path.read_bytes()) - assert published_json_schema_errors(document) == [] - rows = {row["target_name"]: row for row in document["targets"]} - thin, beside = rows["band_a"]["metadata"], rows["band_b"]["metadata"] - assert thin["carrier_floor_met"] is False - assert "complementary_withholding" not in thin - assert beside["carrier_floor_met"] is True - assert beside["complementary_withholding"] is True - assert beside["model_figures_withheld"].startswith( - "model figures withheld: with the published rows" - ) - assert "a row or a cell" in beside["model_figures_withheld"] - assert rows["band_b"]["final_estimate"] is None - assert rows["total"]["final_estimate"] == pytest.approx(30.0) - assert document["uk_diagnostics"]["model_figures_withheld"]["targets"] == 2 - - -def _thin_and_wide_brma_payload( - thin_values=(1.0,) * 6 + (0.0,) * 8, extra_options=None, thin_target=10.0 -): - """The thin/wide BRMA fixture's diagnostics payload and its result. - - ``extra_options`` joins the result's options, as a solve records them. - """ - - n = 14 - sources = [0, 0, 1, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10] - household = pd.DataFrame( - { - "household_id": np.arange(n, dtype=np.int64), - "source_household_id": np.asarray(sources, dtype=np.int64), - _SPI_COLUMN: [False] * n, - _CG_COLUMN: [False] * n, - "thin_measure": list(thin_values), - "wide_measure": [1.0] * n, - "other_measure": [0.5] * n, - } - ) - specs = [ - TargetSpec( - name=name, - entity="household", - value=value, - measure=measure, - period=2023, - source="Synthetic UK diagnostics fixture", - family="private_rent", - hierarchy=_fixture_hierarchy(name, "brma"), - ) - for name, measure, value in ( - ("thin_brma_target", "thin_measure", thin_target), - ("wide_brma_target", "wide_measure", 10.0), - ("other_brma_target", "other_measure", 7.5), - ) - ] - geography = {f"{spec.name}@2023": "brma" for spec in specs} - weights = np.ones(n) - frame = Frame( - { - "person": pd.DataFrame( - { - "person_id": np.arange(n, dtype=np.int64), - "person_household_id": np.arange(n, dtype=np.int64), - } - ), - "household": household, - }, - EntitySchema(group_entities=("household",)), - {"household": Weights(weights, WeightKind.DESIGN)}, - ) - registry = TargetRegistry(specs, country="uk") - result = score_targets(frame, registry.to_target_set(), weights=weights) - if extra_options: - from dataclasses import replace - - result = replace(result, options={**result.options, **extra_options}) - support = pd.DataFrame( - columns=[ - "geography_level", - "area_code", - "nonzero_households", - "nonzero_source_households", - "effective_sample_size", - ] - ) - payload = uk_calibration_diagnostics_payload( - result, - frame, - target_geography_levels=geography, - target_registry=registry, - local_area_support=support, - ) - return payload, result - - -def test_no_published_total_gives_a_withheld_row_back() -> None: - """María's ruling of 2026-10-18: the totals cover the published rows only. - - Try to recover the withheld row from what the payload publishes: the - final and initial losses less the published rows' contributions leave - nothing, the fraction within 10% is the published rows' own, and the - trajectory, which no published row can be set against, is empty. - """ - - import math - - payload, result = _thin_and_wide_brma_payload() - rows = {row["target_name"]: row for row in payload["targets"]} - thin = rows.pop("thin_brma_target") - assert thin["final_estimate"] is None - assert thin.get("final_loss_contribution") is None - published = list(rows.values()) - assert payload["final_loss"] == math.fsum( - row["final_loss_contribution"] for row in published - ) - # The initial loss is the published rows' too, from their own fields. - assert payload["initial_loss"] == pytest.approx( - math.fsum( - row["target_loss_weight_share"] - * min( - abs(row["initial_estimate"] - row["target"]) / row["target_loss_scale"], - payload["target_loss_basis"]["cap"], - ) - for row in published - ), - rel=1e-12, - ) - # Either total over every row would have left the thin row's share. - assert payload["final_loss"] < result.final_loss - assert payload["fraction_within_10pct"] == pytest.approx( - sum(abs(row["relative_error"]) <= 0.10 for row in published) / len(published) - ) - assert payload["loss_trajectory"] == [] - assert payload["past_cap_census"]["n_targets"] == len(published) - block = payload["uk_diagnostics"]["model_figures_withheld"] - assert block["targets"] == 1 and block["totals_basis"] == "published_rows" - # A build with nothing withheld keeps the solve's own totals. - payload, result = _thin_and_wide_brma_payload(thin_values=(1.0,) * 14) - assert payload["final_loss"] == pytest.approx(result.final_loss, rel=1e-12) - assert payload["loss_trajectory"] == pytest.approx(list(result.loss_trajectory)) + assert family["n_targets"] == 2 assert "model_figures_withheld" not in payload["uk_diagnostics"] - - -def _numbers(value): - if isinstance(value, bool): - return - if isinstance(value, (int, float)): - yield float(value) - elif isinstance(value, dict): - for item in value.values(): - yield from _numbers(item) - elif isinstance(value, list): - for item in value: - yield from _numbers(item) - - -def test_a_withheld_row_inside_ten_percent_counts_nowhere() -> None: - """The third review of #1305: no test had a withheld row inside 10%. - - The thin row now misses its target by about 3%. Of the published rows - one is inside 10% and one is not, so the fraction is a half; counting the - numerator over every row would make it one. - """ - - payload, _ = _thin_and_wide_brma_payload(thin_target=6.2) - rows = {row["target_name"]: row for row in payload["targets"]} - assert rows["thin_brma_target"]["final_estimate"] is None - assert payload["fraction_within_10pct"] == 0.5 - (brma,) = [ - row - for row in payload["uk_diagnostics"]["target_pass_rates_by_geography_level"] - if row["geography_level"] == "brma" - ] - assert brma["n_within_10pct"] == 1 - - -def test_every_brma_row_states_its_ten_household_verdict() -> None: - """María's ruling of 2026-10-19 on the fourth review of #1305. - - Every BRMA row carries ``carrier_floor_met``, false exactly where its model - figures are withheld, so the release contract can warn about a thin row - the build never flagged. - """ - - payload, _ = _thin_and_wide_brma_payload() - verdicts = { - row["target_name"]: row["metadata"]["carrier_floor_met"] - for row in payload["targets"] - } - assert verdicts == { - "thin_brma_target": False, - "wide_brma_target": True, - "other_brma_target": True, - } - - -def test_the_published_options_are_settings_only() -> None: - """The fourth review of #1305: an outcome key added to the allow-list - passed every test. Each key here is a setting the solve was given; a new - one is added here, after checking that it holds no outcome.""" - - from microcosm.diagnostics import ( - UK_WITHHELD_PUBLISHED_ITERATE_FIELDS, - UK_WITHHELD_PUBLISHED_OPTIONS, - ) - - assert UK_WITHHELD_PUBLISHED_OPTIONS == { - "budget_basis", - "epochs", - "feasible_draw_pi_hi", - "gate_initialization_supplied", - "iterate_selection", - "l1_lambda", - "l1_penalty", - "l2_anchor", - "l2_anchor_weights_supplied", - "l2_basis", - "l2_lambda", - "l2_penalty", - "learning_rate", - "mass", - "mass_parametrization", - "mass_reason", - "matrix_format", - "max_weight_ratio", - "method", - "seed", - "target_loss_cap", - "target_loss_scales", - "target_loss_weights", - "target_records", - "warm_start_weights", - } - assert UK_WITHHELD_PUBLISHED_ITERATE_FIELDS == { - "rule", - "selected_epoch", - "epochs_executed", - "epoch_convention", - } - - -def test_no_loss_over_every_row_survives_in_the_payload() -> None: - """The third review of #1305: the solve's options kept its iterate's loss. - - ``iterate_selection_receipt`` held the selected iterate's loss over every - row, which less the restated final loss gave the withheld row back. While - a row is withheld the options keep their settings only, and no number in - the payload equals a loss over every row. - """ - - import math - - receipt = { - "rule": "best_feasible_loss", - "selected_epoch": 3, - "epochs_executed": 5, - "epoch_convention": "completed_optimizer_updates; zero is start", - "selected_loss_float32": 0.2617, - "closing_iterate_loss_float32": 0.2711, - } - extra = { - "iterate_selection_receipt": receipt, - "budget_search": {"probes": [{"loss": 0.3119}]}, - "an_outcome_nobody_listed": 0.2903, - } - payload, result = _thin_and_wide_brma_payload(extra_options=extra) - options = payload["options"] - assert options["iterate_selection_receipt"] == { - **receipt, - "selected_loss_float32": None, - "closing_iterate_loss_float32": None, - } - assert options["budget_search"] is None - assert options["an_outcome_nobody_listed"] is None - assert options["method"] == "score_only" - every_row = (result.final_loss, result.initial_loss, 0.2617, 0.2711, 0.3119) - for number in _numbers(payload): - assert not any(math.isclose(number, loss, rel_tol=1e-9) for loss in every_row) - # With nothing withheld the options stay as the solve wrote them. - payload, _ = _thin_and_wide_brma_payload( - thin_values=(1.0,) * 14, extra_options=extra - ) - assert payload["options"]["iterate_selection_receipt"] == receipt - assert payload["options"]["an_outcome_nobody_listed"] == 0.2903 - - -def test_the_restated_totals_match_the_solve_and_drop_a_pushed_out_row() -> None: - """Over every row the restatement reproduces the solve's own totals. - - A withheld row pushed past the cap leaves the census's listing and count. - """ - - from types import SimpleNamespace - - from microcosm.build.uk_runtime.diagnostics import ( - _restate_totals_over_published_rows, - ) - - def row(name, target, initial, final): - return SimpleNamespace( - name=name, - target=target, - initial_estimate=initial, - final_estimate=final, - relative_error=(final - target) / target, - ) - - rows = [ - row("a@2025", 10.0, 11.0, 10.5), - row("b@2025", 20.0, 19.0, 21.0), - row("thin@2025", 10.0, 12.0, 400.0), - ] - result = SimpleNamespace( - diagnostics=rows, - target_loss_weights=np.array([1.0, 2.0, 1.0]), - target_loss_scales=np.array([10.0, 20.0, 10.0]), - target_loss_cap=10.0, - options={"target_loss_cap": 10.0}, - ) - payload: dict[str, object] = {} - _restate_totals_over_published_rows(payload, result, frozenset()) - shares = np.array([0.25, 0.5, 0.25]) - assert payload["final_loss"] == pytest.approx( - 0.25 * 0.05 + 0.5 * 0.05 + 0.25 * min(39.0, 10.0) - ) - assert payload["initial_loss"] == pytest.approx( - float(shares @ np.array([0.1, 0.05, 0.2])) - ) - assert payload["past_cap_census"]["pushed_out"] == 1 - _restate_totals_over_published_rows(payload, result, frozenset({"thin@2025"})) - assert payload["final_loss"] == pytest.approx(0.25 * 0.05 + 0.5 * 0.05) - assert payload["fraction_within_10pct"] == 1.0 - census = payload["past_cap_census"] - assert census["n_targets"] == 2 - assert census["pushed_out"] == 0 and census["pushed_out_rows"] == [] - - -def test_written_rows_flag_every_row_while_any_is_withheld() -> None: - from microcosm.build.uk_runtime.diagnostics import uk_withhold_brma_figures - - withheld = frozenset({"thin@2025"}) - rows = [ - {"name": "thin@2025", "target": 10.0, "estimate": 6.0, "relative_error": -0.4}, - {"name": "wide@2025", "target": 10.0, "estimate": 14.0, "relative_error": 0.4}, - ] - thin, wide = uk_withhold_brma_figures(rows, withheld) - assert thin["estimate"] is None and thin["relative_error"] is None - assert thin["target"] == 10.0 and thin["model_figures_withheld"] is True - assert wide == {**rows[1], "model_figures_withheld": False} - assert rows[0]["estimate"] == 6.0 - # With nothing withheld the written table keeps its old columns. - flagged = [{**rows[0], "model_figures_withheld": True}] - assert uk_withhold_brma_figures(flagged, frozenset()) == [rows[0]] - - -def test_the_report_guard_refuses_any_mention_of_a_withheld_row(capsys) -> None: - """María's ruling of 2026-10-19: no gate output names a withheld row. - - The third review of #1305 found more than fifteen shapes that slipped - past a guard looking for figures beside a name. The guard now refuses the - name, the gate key and the area code themselves, in any case, anywhere. - The fourth found that its message named the place, and a failed receipt - sends the message on: it is now constant, and the place stays on stderr. - """ - - from microcosm.build.uk_runtime.diagnostics import ( - UK_WITHHELD_ROW_NAMED_MESSAGE, - UKWithheldRowNamedError, - uk_refuse_named_withheld_rows, - ) - - names = frozenset({"ons.rent.private_rent_brma@S33999999@2025"}) - keys = frozenset({"private_rent/S33999999/rent/private_rent_brma"}) - (key,) = keys - - def guard(report): - uk_refuse_named_withheld_rows( - report, names=names, keys=keys, areas=frozenset({"S33999999"}) - ) - - # Counts, published rows and other areas pass. - guard( - { - "outcomes": [ - { - "failures": ["private_rent/E06000001/rent/private_rent +30.0%"], - "details": { - "withheld_targets": 1, - "family_sizes": {"private_rent": 7}, - "failing_targets": { - "private_rent/S33999998/rent/private_rent_brma": 0.3 - }, - }, - } - ] - } - ) - for report in ( - {"failing_targets": {key: -0.4}}, - {"rows": [{"name": key, "relative_error": -0.4}]}, - {"pairs": [[key, -0.4]]}, - {key: "-41.2%"}, - {"names": [key], "errors": [-0.4]}, - {"failures": [f"{key} is 40 per cent out"]}, - {"failures": [f"err=-4.0e-01 for {key.upper()}"]}, - {"failures": ["ons.rent.private_rent_brma@S33999999 failed"]}, - {"failures": ["S33999999 is beyond the bound"]}, - {"dormant_exclusions": [key]}, - ): - with pytest.raises(UKWithheldRowNamedError) as excinfo: - guard(report) - message = str(excinfo.value) - assert message == UK_WITHHELD_ROW_NAMED_MESSAGE - for label in (key, "S33999999", "failing_targets", "failures", "40"): - assert label.casefold() not in message.casefold() - assert "names a withheld row" in capsys.readouterr().err - # Nothing withheld: nothing to guard. - uk_refuse_named_withheld_rows( - {"failing_targets": {key: -0.4}}, names=frozenset(), keys=frozenset() - ) - - -def test_an_explicit_zero_in_a_brma_row_carries_nothing() -> None: - """A stored zero is no entry: the household does not carry the row.""" - - from types import SimpleNamespace - - from scipy import sparse - - from microcosm.build.uk_runtime.diagnostics import uk_withheld_brma_rows - - n = 12 - data = np.array([1.0] * 9 + [0.0] * 3) - matrix = sparse.csr_array((data, (np.zeros(n, dtype=int), np.arange(n))), (1, n)) - assert matrix.nnz == n - problem = SimpleNamespace(matrix=matrix, names=["brma_row@2025"]) - frame = Frame( - { - "person": pd.DataFrame( - { - "person_id": np.arange(n, dtype=np.int64), - "person_household_id": np.arange(n, dtype=np.int64), - } - ), - "household": pd.DataFrame( - { - "household_id": np.arange(n, dtype=np.int64), - "source_household_id": np.arange(n, dtype=np.int64), - } - ), - }, - EntitySchema(group_entities=("household",)), - {"household": Weights(np.ones(n), WeightKind.DESIGN)}, - ) - rows = [{"name": "brma_row@2025"}] - levels = {"brma_row@2025": "brma"} - assert uk_withheld_brma_rows(problem, np.ones(n), frame, rows, levels) == { - "brma_row@2025" - } - data[9] = 1.0 - matrix = sparse.csr_array((data, (np.zeros(n, dtype=int), np.arange(n))), (1, n)) - problem = SimpleNamespace(matrix=matrix, names=["brma_row@2025"]) - assert uk_withheld_brma_rows(problem, np.ones(n), frame, rows, levels) == set() - # A zero weight carries nothing either. - weights = np.ones(n) - weights[0] = 0.0 - assert uk_withheld_brma_rows(problem, weights, frame, rows, levels) == { - "brma_row@2025" - } - - -def test_the_local_line_withholds_thin_local_rows_by_block() -> None: - """María's ruling of 2026-10-23: thin local rows are withheld, by block. - - In one constituency a family total less its published band gives a thin - band back, so the next-smallest band is withheld beside it, as nationally. - A thin row in another area is withheld on its own, and no row of one area - is withheld for a difference with another's that gives nothing back. - """ - - rows = { - "fam.total@E14000001@2025": list(range(30)), - "fam.band_1@E14000001@2025": list(range(25)), - "fam.band_2@E14000001@2025": list(range(25, 30)), - "other.total@E14000002@2025": list(range(30, 35)), - "other.total@E14000003@2025": list(range(35, 60)), - } - levels = {name: "constituency" for name in rows} - thin, beside = _withheld_sets(rows, 60, levels=levels, regions=["LONDON"] * 60) - assert thin == {"fam.band_2@E14000001@2025", "other.total@E14000002@2025"} - assert beside == {"fam.band_1@E14000001@2025"} - # The same rows as one national block would give the same verdict; the - # block split changes only which differences are looked for. - national = _withheld_sets(rows, 60) - assert national == (thin, beside) - - -def test_a_region_row_less_its_published_local_cells_withholds_one_more() -> None: - """Vahid's review of #1383, item 1: the region and its cells are one block. - - The region row binds beside its local-authority cells, so the region less - the published cell gives the thin one back, and the next-smallest giver - is withheld beside it. Per area, nothing was withheld beside it. - """ - - rows = { - "fam.region@E12000007@2025": list(range(30)), - "fam.cell@E09000001@2025": list(range(25, 30)), - "fam.cell@E09000002@2025": list(range(25)), - "fam.region@E12000008@2025": list(range(30, 60)), - } - levels = { - "fam.region@E12000007@2025": "region", - "fam.region@E12000008@2025": "region", - "fam.cell@E09000001@2025": "local_authority", - "fam.cell@E09000002@2025": "local_authority", - } - regions = ["LONDON"] * 30 + ["SOUTH_EAST"] * 30 - thin, beside = _withheld_sets(rows, 60, levels=levels, regions=regions) - assert thin == {"fam.cell@E09000001@2025"} - assert beside == {"fam.cell@E09000002@2025"} - - -def test_a_regions_constituencies_less_its_authorities_withhold_one_more() -> None: - """Both local grains partition a region, so each gives the other back.""" - - rows = { - "fam.cell@E14000001@2025": list(range(20)), - "fam.cell@E14000002@2025": list(range(20, 40)), - "fam.cell@E06000001@2025": list(range(35)), - "fam.cell@E06000002@2025": list(range(35, 40)), - } - levels = { - "fam.cell@E14000001@2025": "constituency", - "fam.cell@E14000002@2025": "constituency", - "fam.cell@E06000001@2025": "local_authority", - "fam.cell@E06000002@2025": "local_authority", - } - thin, beside = _withheld_sets(rows, 40, levels=levels, regions=["WALES"] * 40) - assert thin == {"fam.cell@E06000002@2025"} - # The constituencies less the larger authority give the thin one back; - # the smaller constituency is withheld (ties go by name), and what is left - # (the thin cell with it) rests on 25 households. - assert beside == {"fam.cell@E14000001@2025"} - - -def _uc_family_rows() -> tuple[dict[str, list[int]], dict[str, str], dict[str, str]]: - # The national UC caseload and its constituency cells share one - # measurement, so they are one family with its parent (the contract). - rows = { - "dwp.uc.households@2025": list(range(60)), - "dwp.uc.households_by_area@E14000001@2025": list(range(30)), - "dwp.uc.households_by_area@E14000002@2025": list(range(30, 55)), - "dwp.uc.households_by_area@E14000003@2025": list(range(55, 60)), - } - levels = {name: "constituency" for name in rows} - levels["dwp.uc.households@2025"] = "country" - targets = { - name: "dwp.uc.households" - if name.startswith("dwp.uc.households@") - else ("dwp.uc.households_by_area") - for name in rows - } - return rows, levels, targets - - -def test_a_national_row_less_a_familys_published_cells_withholds_one_more() -> None: - """A national parent less its family's cells across regions gives one back. - - No region row binds, so no region block sees it: the family's own block - with its parent, the contract's national UC caseload, does. - """ - - rows, levels, targets = _uc_family_rows() - regions = ["NORTH_EAST"] * 30 + ["NORTH_WEST"] * 30 - thin, beside = _withheld_sets( - rows, 60, levels=levels, regions=regions, targets=targets - ) - assert thin == {"dwp.uc.households_by_area@E14000003@2025"} - assert beside == {"dwp.uc.households_by_area@E14000002@2025"} - # Without its contract target a local row would join no family block and - # nothing would be withheld beside the thin cell, so it refuses (Vahid's - # third review of #1383, item 33). - with pytest.raises(ValueError, match="name none"): - _withheld_sets(rows, 60, levels=levels, regions=regions, tie_targets=False) - - -def test_no_parentless_local_family_shares_its_measurement_with_a_higher_row() -> None: - """A local family with no parent has no higher-grain row of its measurement. - - The family check ties a family to its parents through the cross-grain - declarations or a nested measurement. A national or regional row of the - same measurement left untied would let a published total less the - family's cells give a thin cell back unchecked (Vahid's third review of - #1383, item 33). Today the parentless families are the two DESNZ kWh - families, the three equivalised income and housing cost families and the - two private rent families; the national energy rows are spend, not kWh. - """ - - from microcosm.build.uk_runtime.cross_grain_declarations import ( - UK_LOCAL_GEOGRAPHY_LEVELS, - ) - from microcosm.build.uk_runtime.diagnostics import uk_local_family_parents - from microcosm.build.uk_runtime.ledger_targets import ( - uk_cross_grain_contract_signatures, - ) - - contract = uk_cross_grain_contract_signatures() - - def concept(target_id: str) -> object: - return (contract[target_id].get("measurement") or {}).get("concept") - - higher: dict[object, set[str]] = {} - for target_id, target in contract.items(): - if set(target.get("geography_levels") or ()) - UK_LOCAL_GEOGRAPHY_LEVELS: - higher.setdefault(concept(target_id), set()).add(target_id) - parentless = [ - members for members, parents in uk_local_family_parents() if not parents - ] - assert parentless - for members in parentless: - for target_id in members: - assert not higher.get(concept(target_id), set()) - members, target_id - - -def test_a_row_one_block_withholds_stays_hidden_in_another() -> None: - """A row withheld beside a thin one is protected in every block holding it. - - The family block withholds the second cell beside the thin third. A row - of the region's own, on exactly that cell's households, would give it - back, and with it the thin cell, so the region block withholds that too. - """ - - rows, levels, targets = _uc_family_rows() - rows["other.cell@E14000002@2025"] = list(range(30, 55)) - levels["other.cell@E14000002@2025"] = "constituency" - regions = ["NORTH_EAST"] * 30 + ["NORTH_WEST"] * 30 - thin, beside = _withheld_sets( - rows, 60, levels=levels, regions=regions, targets=targets - ) - assert thin == {"dwp.uc.households_by_area@E14000003@2025"} - assert beside == { - "dwp.uc.households_by_area@E14000002@2025", - "other.cell@E14000002@2025", - } - - -def test_local_rows_without_household_regions_refuse() -> None: - """A local row is checked against its region's rows, so it needs regions.""" - - rows = {"fam.cell@E14000001@2025": list(range(20))} - with pytest.raises(ValueError, match="household table needs a region column"): - _withheld_sets(rows, 20, levels={"fam.cell@E14000001@2025": "constituency"}) - - -def test_the_report_guard_matches_a_withheld_local_row_by_its_key(capsys) -> None: - """A constituency binds many families, so its bare code names published rows.""" - - from microcosm.build.uk_runtime.diagnostics import ( - UKWithheldRowNamedError, - uk_refuse_named_withheld_rows, - uk_withheld_gate_areas, - uk_withheld_gate_keys, - ) - - rows = [ - { - "family": "fam", - "area_code": "E14000001", - "metric": "band_2", - "geography_level": "constituency", - "model_figures_withheld": True, - }, - { - "family": "private_rent", - "area_code": "S33999999", - "metric": "private_rent_brma", - "geography_level": "statistical_scope", - "model_figures_withheld": True, - }, - { - "family": "other", - "area_code": "E14000001", - "metric": "total", - "geography_level": "constituency", - }, - ] - keys = uk_withheld_gate_keys(rows) - areas = uk_withheld_gate_areas(rows) - assert keys == {"fam/E14000001/band_2", "private_rent/S33999999/private_rent_brma"} - assert areas == {"S33999999"} - - def guard(report): - uk_refuse_named_withheld_rows(report, names=frozenset(), keys=keys, areas=areas) - - # Another family's published row in the same constituency may be named. - guard({"failures": ["other/E14000001/total +30.0%"], "areas": ["E14000001"]}) - for report in ( - {"failures": ["fam/E14000001/band_2 +30.0%"]}, - {"failures": ["S33999999 is beyond the bound"]}, - ): - with pytest.raises(UKWithheldRowNamedError): - guard(report) - assert "names a withheld row" in capsys.readouterr().err + shared = diagnostics_payload(result, target_registry=registry) + for field in ("initial_loss", "final_loss", "loss_trajectory", "options"): + assert payload[field] == shared[field] diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_frs_annual_income.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_frs_annual_income.py index de19f0b946..1a5c4c62a4 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_frs_annual_income.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_frs_annual_income.py @@ -8,6 +8,7 @@ from __future__ import annotations import json +import math from importlib.resources import files import numpy as np @@ -483,7 +484,6 @@ def test_gate_passes_the_stages_own_receipt() -> None: ("pay_concept_ratio", 3.58, "pay_concept_ratio 3.5800 lies outside"), # Spells add part-year earners; they cannot remove a current one. ("annual_over_current_earners", 0.98, "annual_over_current_earners 0.9800"), - ("annual_over_current_earners", "<10", "not a measured ratio"), ("other_spells_pay_observed_share", 0.5, "only 0.5000 of the pay"), ("other_spells_pay_observed_share", None, "observed_share is None"), ], @@ -500,18 +500,60 @@ def test_gate_refuses_another_stages_receipt() -> None: assert "does not match" in gate.failures[0] -def test_pay_concept_ratio_refuses_too_few_reporters() -> None: +def test_pay_concept_ratio_measures_few_reporters_and_refuses_none() -> None: + """Fewer than ten reporting households only flags (María's ruling of + 2026-10-26): the ratio is measured, and the receipt prints it "<10".""" person, adult, job, interview, _ = _population({}) - job = job.iloc[:5] - with pytest.raises(ValueError, match="fewer than ten households"): + ratio, support = fai.pay_concept_ratio( + person["person_id"].to_numpy(), + np.ones(len(person)), + job.iloc[:5], + np.ones(len(person), dtype=bool), + ) + assert 0 < support < 10 and math.isfinite(ratio) + with pytest.raises(ValueError, match="no household reports both"): fai.pay_concept_ratio( person["person_id"].to_numpy(), np.ones(len(person)), - job, + job.iloc[:0], np.ones(len(person), dtype=bool), ) +def _reporting_jobs(households: int, ratio: float) -> tuple: + """One current employee main job a household, at one DV-to-usual ratio.""" + person_ids = np.arange(1, households + 1) + job = pd.DataFrame( + { + "person_id": person_ids, + "household_id": person_ids, + "jobtype": 1, + "etype": fai.ETYPE_EMPLOYEE_CODE, + "ugross": 500.0, + "ugrspay": 500.0 * ratio, + } + ) + return person_ids, np.ones(households), job, np.ones(households, dtype=bool) + + +@pytest.mark.parametrize("measured, used", [(1.5, 1.10), (0.5, 0.95), (1.02, 1.02)]) +def test_a_thin_pay_concept_ratio_is_held_to_its_bounds(measured, used) -> None: + """On fewer than ten households a ratio past the plausibility bounds is + noise: it is held to them, and the build goes on (Vahid's second review + of #1396). On ten or more it still refuses.""" + ratio, support = fai.pay_concept_ratio(*_reporting_jobs(5, measured)) + assert support == 5 and ratio == pytest.approx(used) + with pytest.raises(ValueError, match="lies outside"): + fai.pay_concept_ratio(*_reporting_jobs(10, 1.5)) + + +@pytest.mark.parametrize("key", ["pay_concept_ratio", "annual_over_current_earners"]) +def test_gate_flags_a_ratio_on_fewer_than_ten_households(key: str) -> None: + gate = _gate({**_leaver_evidence(), key: "<10"}) + assert gate.passed, gate.failures + assert gate.details[f"{key}_measured"] is False + + def _stage(**overrides) -> SourceStageSpec: operations = tuple( SourceOperationSpec(kind=kind, parameters=parameters) diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_full_build_cli.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_full_build_cli.py index d9c074bd6d..66ee437d4a 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_full_build_cli.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_full_build_cli.py @@ -621,78 +621,26 @@ def test_a_release_candidate_needs_the_signing_key_and_local_targets( ) -def test_a_withheld_brma_row_projects_over_the_published_rows(tmp_path, monkeypatch): - """microcosm#1305 re-review: a withheld row reads blank, not NaN. - - The terminal table leaves a withheld BRMA row's figures blank. The - manifest's error summaries and family fit cover the published rows, the - solve block counts the withheld one, and the manifest still writes as - strict JSON (it refuses NaN). - """ +def test_a_thin_brma_row_projects_with_its_figures(tmp_path, monkeypatch): + """María's ruling of 2026-10-26: a row resting on fewer than ten source + households carries its figures, so the manifest's error summaries and + family fit cover it, and the solve block counts nothing as withheld.""" pytest.importorskip("tables") - monkeypatch.setattr(support, "WITHHELD_BRMA_ROW", True) + monkeypatch.setattr(support, "THIN_BRMA_ROW", True) args = arguments(tmp_path, "--release-candidate") assert cli.execute_full_build(prepared(tmp_path, release_candidate=True), args) == 0 manifest = json.loads((args.out / "rowwise_candidate_manifest.json").read_text()) solve = manifest["solve"] assert solve["n_targets"] == 2 - assert solve["model_figures_withheld"] == { - "targets": 1, - "totals_basis": "published_rows", - } - assert solve["max_abs_relative_error"] == 0.0 - assert solve["median_abs_relative_error"] == 0.0 - assert [row["family"] for row in manifest["fit"]["local_by_family"]] == [ - "census_households" + assert "model_figures_withheld" not in solve + assert solve["max_abs_relative_error"] == pytest.approx(0.1) + assert solve["median_abs_relative_error"] == pytest.approx(0.05) + assert sorted(row["family"] for row in manifest["fit"]["local_by_family"]) == [ + "census_households", + "private_rent", ] -def test_a_published_size_receipt_keeps_only_its_allow_list_while_rows_are_withheld(): - """The third review of #1305: an allow-list, not a deny-list. - - Every field a reader of the manifest uses stays; the losses, the refit's - distances, the search's probes and any field nobody listed read null. - """ - from microcosm.build.uk_runtime.graph_terminal import _published_size_receipt - - receipt = { - "requested_households": 2, - "realized_households": 2, - "pool_households": 4, - "protected_carriers": 1, - "refit_epochs": 10, - "selection_epochs": 10, - "selection_l0_lambda": 1e-7, - "selection_receipt": {"design": "sampford"}, - "selection_search_bracket": {"lower": 1e-10, "upper": 1e-5}, - "dense_loss": 0.2, - "compact_loss": 0.3, - "max_target_scaled_change": 0.4, - "compact_loss_under_dense_weights": 0.35, - "refit_l2": {"chi_square_distance_to_anchor": 0.01}, - "selection_budget_search": {"probes": [{"loss": 0.5}]}, - "a_field_nobody_listed": 0.6, - } - assert _published_size_receipt(receipt, withheld=0) == receipt - published = _published_size_receipt(receipt, withheld=1) - kept = { - "requested_households", - "realized_households", - "pool_households", - "protected_carriers", - "refit_epochs", - "selection_epochs", - "selection_l0_lambda", - "selection_receipt", - "selection_search_bracket", - } - for key, value in receipt.items(): - assert published[key] == (value if key in kept else None), key - assert "1 row(s)" in published["withheld_totals_note"] - assert receipt["dense_loss"] == 0.2 - assert _published_size_receipt(None, withheld=1) is None - - def test_dense_run_projects_the_rowwise_candidate_manifest(tmp_path): pytest.importorskip("tables") args = arguments(tmp_path, "--release-candidate") @@ -701,6 +649,14 @@ def test_dense_run_projects_the_rowwise_candidate_manifest(tmp_path): manifest = json.loads((out / "rowwise_candidate_manifest.json").read_text()) assert manifest["schema_version"] == 4 assert manifest["build_kind"] == "uk_rowwise_calibrated_candidate" + # The support block counts areas and states the minima (María's ruling + # of 2026-10-26 dropped their withholding, microcosm#1301). + support = manifest["support"] + assert (support["areas_checked"], support["min_nonzero_households"]) == (4, 1) + assert ( + support["by_geography_level"]["constituency"]["min_nonzero_source_households"] + == 1 + ) assert manifest["release_role"] == "dense" assert manifest["release_id"] == UK_DENSE_RELEASE_ID assert manifest["parameters"]["release_role"] == "dense" @@ -1415,16 +1371,11 @@ def walk(value): @pytest.mark.parametrize("extra", [(), ("--target-geographies", "la")]) -def test_every_request_stages_its_epochs_without_loss( +def test_every_request_stages_its_epochs_with_their_loss( tmp_path, monkeypatch, capsys, extra ): - """The third review of #1305: an epoch's loss covers every row. - - Every request can bind a thin row now (María's rule of 2026-10-21 binds - thin national rows as well as BRMA rows), so every request stages its - epochs, and sends them to the emitter, with a null loss; only the local - stderr line keeps it. - """ + """María's ruling of 2026-10-26 dropped the withholding of microcosm#1262, + so the staged epochs and the emitter carry each epoch's loss again.""" pytest.importorskip("tables") emitted: list[dict] = [] monkeypatch.setattr( @@ -1441,65 +1392,19 @@ def test_every_request_stages_its_epochs_without_loss( rows = _staged_epoch_rows(out) assert rows and emitted losses = {row["loss"] for row in rows} | {event["loss"] for event in emitted} - assert losses == {None} - # The local stderr line keeps the last epoch's loss either way. + assert losses == {0.5, 0.25} assert "loss 0.25" in capsys.readouterr().err -def test_the_thinned_epochs_null_the_loss_on_request(): - from microcosm.build.uk_runtime.rowwise_staging import thinned_epochs - - seen: list[dict] = [] - forward = thinned_epochs(seen.append, every=1, withhold_loss=True) - forward({"kind": "calibration_epoch", "epoch": 1, "epochs": 1, "loss": 0.25}) - assert seen == [ - {"kind": "calibration_epoch", "epoch": 1, "epochs": 1, "loss": None} - ] - seen.clear() - thinned_epochs(seen.append, every=1)( - {"kind": "calibration_epoch", "epoch": 1, "epochs": 1, "loss": 0.25} - ) - assert seen[0]["loss"] == 0.25 - - -@pytest.mark.parametrize( - "role,localisation,levels", - [ - ("dense", "area", None), - ("dense", "area", ("la", "brma")), - ("dense", "area", ("la",)), - ("dense", "none", None), - ("national", "area", None), - ], -) -def test_every_request_may_withhold_a_row(role, localisation, levels): - """María's rule of 2026-10-21 binds thin national rows as well as BRMA rows.""" - - from types import SimpleNamespace - - args = SimpleNamespace( - release_role=role, brma_localisation=localisation, target_geographies=levels - ) - assert cli._may_withhold_rows(args) is True - - -def test_a_national_request_stages_its_epochs_without_their_loss(tmp_path, monkeypatch): - """A national run binds thin UC payment and benefit-cap bands now. - - An epoch's loss covers every row, so against the published rows it would - give a withheld row back: the staged epochs carry null, as the dense - role's have since the third review of #1305. - """ - +def test_a_national_request_stages_its_epochs_with_their_loss(tmp_path, monkeypatch): args = cli.parse_args(_national_argv(tmp_path)) - assert cli._may_withhold_rows(args) is True emitted: list[dict] = [] monkeypatch.setattr( cli, "emit_calibration_progress", lambda event: emitted.append(dict(event)) ) observer = cli._solve_observer(args, None) observer({"kind": "calibration_epoch", "epoch": 1, "epochs": 1, "loss": 0.25}) - assert [event["loss"] for event in emitted] == [None] + assert [event["loss"] for event in emitted] == [0.25] def test_telemetry_content_refusal_never_aborts_the_solve( @@ -3371,3 +3276,22 @@ def test_the_brma_and_rent_resource_flags_need_their_modes(tmp_path): {}, {}, ) + + +def test_the_thin_rows_only_switch_is_gone(tmp_path): + """María's ruling of 2026-10-26 dropped the withholding, and with it + --withhold-thin-rows-only; a script that still passes it is refused.""" + + with pytest.raises(SystemExit): + arguments(tmp_path, "--withhold-thin-rows-only") + + +def test_the_orrery_publication_is_off_unless_asked(tmp_path): + """María's ruling of 2026-10-26: no build submits its graph to the public + Orrery by default.""" + + from microcosm.build.uk_runtime.orrery_publication import publication_enabled + + assert not publication_enabled(arguments(tmp_path)) + assert not publication_enabled(arguments(tmp_path, "--no-publish-orrery")) + assert publication_enabled(arguments(tmp_path, "--publish-orrery")) diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_full_calibration_graph.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_full_calibration_graph.py index 500d26c1c2..41db1e1500 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_full_calibration_graph.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_full_calibration_graph.py @@ -47,27 +47,6 @@ from test_support.microcosm_build.uk_local_rowwise import _clone_frame -@pytest.fixture(autouse=True) -def _every_toy_row_published(monkeypatch): - """Publish every row of the three-household toy graph. - - A row's model figures leave a build only when ten distinct source - households carry it (María's rule of 2026-10-21 binds a thin row and - withholds its figures). The toy graph declares its columns exactly and - carries no source lineage to count, so these graph tests publish every - row; the withheld path has its own tests in test_uk_diagnostics.py and - test_uk_orrery_contract.py. - """ - - from microcosm.build.uk_runtime import diagnostics, full_gates - - def none_withheld(*args, **kwargs): - return set() - - monkeypatch.setattr(diagnostics, "uk_withheld_rows", none_withheld) - monkeypatch.setattr(full_gates, "uk_withheld_rows", none_withheld) - - def source_frame(): frame = _clone_frame() tables = {entity: frame.table(entity).copy() for entity in frame.entities} @@ -288,7 +267,10 @@ def binding_solver(): def test_orrery_summary_replays_dense_and_size_artifacts_without_solving( k, tmp_path, monkeypatch ): - from microcosm.build.uk_runtime.orrery_contract import UK_SUMMARY_PROVIDERS + from microcosm.build.uk_runtime.orrery_contract import ( + UK_SUMMARY_PROVIDERS, + public_summary_findings, + ) from microcosm.graph import ( collect_execution_evidence, graph_schema, @@ -335,11 +317,9 @@ def test_orrery_summary_replays_dense_and_size_artifacts_without_solving( ) rows = summary["tables"]["targets"] assert rows[0]["target"] == expected.diagnostics[0].target - assert rows[0]["achieved"] == expected.diagnostics[0].final_estimate - assert ( - rows[0]["residual"] - == expected.diagnostics[0].final_estimate - expected.diagnostics[0].target - ) + # The summaries may be published, so they carry no row's model figures + # (Vahid's review of #1396, M1); the diagnostics keep them. + assert "achieved" not in rows[0] and "residual" not in rows[0] assert rows[0]["uncertainty"]["status"] == "not_recorded" assert summary["overview"]["final_weights"]["total"] == float( expected.weights.sum() @@ -367,6 +347,8 @@ def test_orrery_summary_replays_dense_and_size_artifacts_without_solving( ) assert {row["status"] for row in preflight["tables"]["gates"]} == {"passed"} assert "details" not in preflight["tables"]["gates"][0] + assert "failures" not in preflight["tables"]["gates"][0] + assert public_summary_findings(evidence["summaries"]) == [] serialized = json.dumps(evidence) assert '"household_ids":' not in serialized assert '"pool_row_indices":' not in serialized diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_full_gates.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_full_gates.py index 67866b50eb..f9c92ef3c7 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_full_gates.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_full_gates.py @@ -119,8 +119,7 @@ def evidence(monkeypatch): ) solution = OrderedSolution(np.ones(2), (1, 2), "a" * 64, {}, "b" * 64) # A real national frame: the context reads it through the release export - # boundary, which renumbers identifiers (microcosm#1194). The household - # region places the constituency row in its region's withholding block. + # boundary, which renumbers identifiers (microcosm#1194). ids = np.asarray([1, 2], dtype="int64") frame = uk_national_frame( person=pd.DataFrame( @@ -190,6 +189,20 @@ def test_gate_diagnostics_use_bound_matrix_and_row_identity(evidence): assert context.artifacts["rules_engine"] is context.artifacts["coverage_engine"] +def test_gate_context_carries_every_rows_figures(evidence): + """María's ruling of 2026-10-26 dropped the withholding: each row rests on + two source households here, and the gates get its figures all the same.""" + + context = _context(evidence) + assert "model_figures_withheld" not in context.artifacts + assert not hasattr(context.artifacts["parity_evidence"], "withheld_targets") + rows = context.artifacts["target_diagnostics"] + assert len(rows) == 2 + for row in rows: + assert "model_figures_withheld" not in row + assert np.isfinite(row["estimate"]) and np.isfinite(row["relative_error"]) + + def test_gate_context_subtracts_the_support_floor_drops(evidence): """A national row the support floor dropped (microcosm#1095 U3) was selected but never solved: the reference side and the activated count diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_gambling_participation.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_gambling_participation.py index 10bce2a7a1..8bc226024b 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_gambling_participation.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_gambling_participation.py @@ -406,10 +406,16 @@ def test_the_receipt_withholds_a_stratum_resting_on_few_households() -> None: assert "households" not in recorded["adults_1:youngest_35_to_54"] -def test_top_up_refuses_a_donor_with_too_few_stakes() -> None: +def test_top_up_flags_few_donor_stakes_and_refuses_too_few_to_fit() -> None: + """Fewer than ten donor households only flags (María's ruling of + 2026-10-26): the fits' support reads "<10". The fit needs two.""" inputs = participation_inputs() stakes = np.zeros(len(inputs["donor_weights"])) stakes[:5] = 10.0 inputs["donor_keys"] = {**inputs["donor_keys"], "national_lottery": stakes} - with pytest.raises(ValueError, match="10 or more households"): + result = top_up_gambling_participation(**inputs) + key = result.receipt["keys"]["national_lottery"] + assert key["propensity"]["positive_support"] == "<10" + stakes[1:] = 0.0 + with pytest.raises(ValueError, match="2 or more households"): top_up_gambling_participation(**inputs) diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_graph_terminal.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_graph_terminal.py index 8235ca734e..9bbf51a94e 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_graph_terminal.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_graph_terminal.py @@ -951,23 +951,6 @@ def test_both_gate_kernels_are_registered(): assert type(registry.get(UKFullHoldoutKernel.ref)) is UKFullHoldoutKernel -@pytest.fixture(autouse=True) -def _toy_national_rows_published(monkeypatch): - """Publish the two-household toy frame's national rows. - - A national row's model figures leave a build only when ten distinct - source households carry it (María's rule of 2026-10-21), and no row here - rests on more than two. These kernel tests lower that floor to one; the - BRMA floor stays at ten, so the withheld BRMA row keeps its own test, and - the national withheld path has its tests in test_uk_diagnostics.py and - test_uk_national_graph.py. - """ - - from microcosm.build.uk_runtime import diagnostics - - monkeypatch.setattr(diagnostics, "UK_DIAGNOSTIC_MIN_SOURCE_HOUSEHOLDS", 1) - - def _run_final_gate_kernel(monkeypatch, *, brma_row: bool = False, solved=None): """Run the terminal gate kernel on a two-household fixture. @@ -976,11 +959,9 @@ def _run_final_gate_kernel(monkeypatch, *, brma_row: bool = False, solved=None): ``solved``, a list, receives the calibration result the kernel decodes. - ``brma_row`` adds a Scottish BRMA rent row far from its target: its two - carriers sit under the ten-household floor, so its figures are withheld - (microcosm#1262). Its rent differs between the two households, so the - national count, which both carry once, does not give it back (Vahid's - second review of #1333: a row that did would be withheld beside it). + ``brma_row`` adds a Scottish BRMA rent row far from its target, resting + on two source households; every row carries its figures (María's ruling + of 2026-10-26). """ from dataclasses import replace from types import SimpleNamespace @@ -1297,115 +1278,58 @@ def test_final_gate_kernel_owns_complete_diagnostics_and_reuses_decoded_result( @pytest.mark.parametrize( - "brma_row", [False, True], ids=["published_rows", "withheld_brma_row"] + "brma_row", [False, True], ids=["national_rows", "thin_brma_row"] ) def test_final_gate_kernel_diagnostics_match_the_published_json_schema( monkeypatch, brma_row ): - # The withheld BRMA row exercises the parts #1305 added: the ``brma`` - # geography level and ``uk_diagnostics.model_figures_withheld``. + # The BRMA row exercises the ``brma`` geography level. stored = _run_final_gate_kernel(monkeypatch, brma_row=brma_row) document = load_strict_json(stored.artifacts["calibration_diagnostics"]) assert published_json_schema_errors(document) == [] - if brma_row: - assert document["uk_diagnostics"]["model_figures_withheld"]["targets"] == 1 + assert "model_figures_withheld" not in document["uk_diagnostics"] -def test_the_gate_kernel_keeps_a_withheld_brma_row_out_of_its_gates(monkeypatch): - """The third review of #1305: the real bindings, through the kernel. +def test_the_gate_kernel_judges_a_thin_brma_row_and_ships_its_figures(monkeypatch): + """María's ruling of 2026-10-26 dropped the withholding of microcosm#1262. - The BRMA row misses its target by about 90% on two source households. - Both fit gates decide on the published rows and count it (María's ruling - of 2026-10-19); the targets table, the embedded rows and the calibration - diagnostics leave its figures out, and nothing the kernel writes gives - them back. + The BRMA row misses its target by about 90% on two source households, + through the real bindings: both fit gates judge it, and the targets + table, the embedded rows and the calibration diagnostics carry its + figures and the solve's own totals. """ import io import json - from microcosm.build.uk_runtime.diagnostics import uk_refuse_named_withheld_rows - solved: list = [] stored = _run_final_gate_kernel(monkeypatch, brma_row=True, solved=solved) key = "private_rent/S33999999/rent/private_rent_brma" document = json.loads(stored.artifacts["gate_report"]) outcomes = {row["id"]: row for row in document["report"]["outcomes"]} fit = outcomes["uk_local_target_fit"] - assert fit["details"]["withheld_targets"] == 1 - assert key not in fit["details"]["failing_targets"] - assert not any(key in line for line in fit["failures"]) + assert "withheld_targets" not in fit["details"] + assert key in fit["details"]["failing_targets"] family = outcomes["uk_local_per_family_fit"]["details"] - assert family["withheld_targets"] == {"private_rent": 1} - assert "private_rent" not in family["family_sizes"] + assert "withheld_targets" not in family + assert family["family_sizes"]["private_rent"] == 1 (embedded,) = [ row for row in document["target_diagnostics"] if row["family"] == "private_rent" ] - assert embedded["model_figures_withheld"] is True - assert embedded["estimate"] is None and embedded["relative_error"] is None - uk_refuse_named_withheld_rows( - document["report"], names=frozenset({embedded["name"]}), keys=frozenset({key}) - ) + assert "model_figures_withheld" not in embedded + assert np.isfinite(embedded["estimate"]) and np.isfinite(embedded["relative_error"]) table = pd.read_csv(io.BytesIO(stored.artifacts["target_diagnostics_csv"])) - flags = dict(zip(table["family"], table["model_figures_withheld"], strict=True)) - assert flags == { - "households": False, - "census_households": False, - "private_rent": True, - } - withheld = table.loc[table["family"] == "private_rent"].iloc[0] - assert pd.isna(withheld["estimate"]) and pd.isna(withheld["relative_error"]) + assert "model_figures_withheld" not in table.columns + assert table[["estimate", "relative_error"]].notna().all().all() diagnostics = json.loads(stored.artifacts["calibration_diagnostics"]) (row,) = [r for r in diagnostics["targets"] if r["target_name"] == "brma_rent"] - assert row["final_estimate"] is None and row["initial_estimate"] is None - assert row.get("final_loss_contribution") is None - # The totals cover the published rows (María's ruling of 2026-10-18), and - # no loss over every row survives, in the options or anywhere else (the - # third review of #1305). - assert diagnostics["loss_trajectory"] == [] - assert diagnostics["uk_diagnostics"]["model_figures_withheld"]["targets"] == 1 + assert np.isfinite(row["final_estimate"]) and np.isfinite(row["initial_estimate"]) + assert "model_figures_withheld" not in (row.get("metadata") or {}) + assert "carrier_floor_met" not in (row.get("metadata") or {}) (result,) = solved - receipt = dict(result.options.get("iterate_selection_receipt") or {}) - every_row = [ - float(result.final_loss), - float(result.initial_loss), - *( - float(receipt[field]) - for field in ("selected_loss_float32", "closing_iterate_loss_float32") - if isinstance(receipt.get(field), float) - ), - ] - - def numbers(value): - if isinstance(value, bool): - return - if isinstance(value, (int, float)): - yield float(value) - elif isinstance(value, dict): - for item in value.values(): - yield from numbers(item) - elif isinstance(value, list): - for item in value: - yield from numbers(item) - - import math - - for document in (diagnostics, json.loads(stored.artifacts["gate_report"])): - for number in numbers(document): - assert not any( - math.isclose(number, loss, rel_tol=1e-9) for loss in every_row - ) - - -def test_the_gate_kernel_fails_closed_on_a_binding_that_leaks(monkeypatch): - """A binding that wrote a withheld row's error stops the build.""" - from microcosm.build.uk_runtime import battery_bindings - - monkeypatch.setattr( - battery_bindings, "uk_withheld_gate_keys", lambda rows: frozenset() - ) - with pytest.raises(ValueError, match="names a withheld row"): - _run_final_gate_kernel(monkeypatch, brma_row=True) + assert diagnostics["final_loss"] == pytest.approx(float(result.final_loss)) + assert diagnostics["loss_trajectory"] + assert "model_figures_withheld" not in diagnostics["uk_diagnostics"] def test_package_validates_materialized_evidence_against_graph_bytes(tmp_path): diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_local_release_preflight.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_local_release_preflight.py index 7ff8cc2b47..445e0b6fa7 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_local_release_preflight.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_local_release_preflight.py @@ -234,33 +234,6 @@ def test_good_candidate_dir_passes(tmp_path: Path) -> None: ) -def test_the_candidate_walk_warns_on_shipped_support_figures(tmp_path: Path) -> None: - """The files the assembler ships byte for byte get the release's - disclosure walk right after the build, as warnings (microcosm#1301).""" - module = _load() - candidate = _good_candidate(tmp_path) - assert module.candidate_disclosure_warnings(candidate) == [] - - manifest_path = candidate / "rowwise_candidate_manifest.json" - manifest = json.loads(manifest_path.read_text()) - manifest["support"] = {"min_nonzero_households": 7} - # A cross-grain relation's excess is not an ESS extreme. - manifest["cross_grain"] = {"subset_relations": [{"max_excess": 0.0}]} - manifest_path.write_text(json.dumps(manifest)) - (warning,) = module.candidate_disclosure_warnings(candidate) - assert warning.startswith("rowwise_candidate_manifest.json carries 1 minimum") - assert "support.min_nonzero_households" in warning - # The warning names where the figure is, never its value. - assert "7" not in warning - - -#: A placeholder area code no area carries, so a planted figure never sits -#: beside a real area (as in the sign-off drafter's tests). -_AREA = "E06999999" -#: The synthetic support figures the walk tests plant; no output may repeat one. -_PLANTED = ("37", "23.75", "29") - - def _in_force_today(candidate: Path) -> None: """Centre the synthetic measure exclusion's window on today: ``main`` checks the run on the real clock.""" @@ -275,13 +248,11 @@ def _in_force_today(candidate: Path) -> None: path.write_text(json.dumps(manifest)) -def test_candidate_dir_prints_the_findings_in_every_shipped_file_without_failing( +def test_the_candidate_preflight_warns_on_no_support_figure( tmp_path: Path, capsys ) -> None: - """--candidate-dir carries the walk through to its output: a figure in - the candidate manifest, the diagnostics, the signed local report or an - opt-in incumbent file is a WARN line naming the file and the path, never - a failure (review of microcosm#1307).""" + """María's ruling of 2026-10-26: a release ships per-area support figures + (microcosm#1301), so the candidate pre-flight no longer walks for them.""" module = _load() candidate = _good_candidate(tmp_path) @@ -290,101 +261,29 @@ def test_candidate_dir_prints_the_findings_in_every_shipped_file_without_failing manifest = json.loads(manifest_path.read_text()) manifest["support"] = {"min_nonzero_households": 37} manifest_path.write_text(json.dumps(manifest)) - (candidate / "microcosm_uk_2024_25_local.diagnostics.json").write_text( - json.dumps({"weakest_areas": [{"area_code": _AREA, "rows": 37}]}) - ) - # Planted before signing, so the report still authenticates. - (candidate / "microcosm_uk_2024_25_local.local_gates.json").write_text( - json.dumps( - _signed_report( - area_support_details={ - "reviewed_exclusions": { - f"local_authority/{_AREA}": { - "shortfalls": ["ESS < 50"], - "ess": 23.75, - } - } - } - ) - ) - ) - (candidate / "score_vs_incumbent.json").write_text( - json.dumps({"support": {"sources_by_area": {_AREA: 29}}}) - ) - (candidate / "incumbent_surface_evaluation.json").write_text( - json.dumps({"notes": [f"local_authority/{_AREA}: rows 37 < 50"]}) - ) - incumbent = tmp_path / "incumbent_local_surface_manifest.json" - incumbent.write_text( - json.dumps({"areas": [{"geography_id": _AREA, "nonzero_households": "3,729"}]}) - ) - - argv = ["--candidate-dir", str(candidate), "--incumbent-manifest", str(incumbent)] - assert module.main(argv) == 0 + assert not hasattr(module, "candidate_disclosure_warnings") + assert module.main(["--candidate-dir", str(candidate)]) == 0 err = capsys.readouterr().err - for name in ( - "rowwise_candidate_manifest.json", - "microcosm_uk_2024_25_local.diagnostics.json", - "microcosm_uk_2024_25_local.local_gates.json", - "score_vs_incumbent.json", - "incumbent_surface_evaluation.json", - "incumbent_local_surface_manifest.json", - ): - assert f"WARN {name} carries 1 " in err, name - assert "FAIL" not in err - assert "preflight: OK, 6 warning(s)" in err - for figure in _PLANTED: - assert figure not in err - - -def test_the_candidate_walk_reads_the_incumbent_manifest_only_when_named( - tmp_path: Path, capsys -) -> None: + assert "WARN" not in err and "FAIL" not in err + + +def test_a_named_incumbent_manifest_must_exist(tmp_path: Path, capsys) -> None: module = _load() candidate = _good_candidate(tmp_path) - incumbent = tmp_path / "incumbent_local_surface_manifest.json" - incumbent.write_text(json.dumps({"min_rows": 37})) - assert module.candidate_disclosure_warnings(candidate) == [] - (warning,) = module.candidate_disclosure_warnings( - candidate, incumbent_manifest=incumbent - ) - assert warning.startswith("incumbent_local_surface_manifest.json carries 1 min") - _in_force_today(candidate) missing = tmp_path / "no-such-manifest.json" argv = ["--candidate-dir", str(candidate), "--incumbent-manifest", str(missing)] assert module.main(argv) == 1 assert f"FAIL incumbent manifest missing: {missing}" in capsys.readouterr().err with pytest.raises(SystemExit): - module.main(["--env", "--incumbent-manifest", str(incumbent)]) - - -@pytest.mark.parametrize( - "content", - [b'{"weakest_areas": [{"rows": NaN}]}', b"[" * 100_000 + b"]" * 100_000], - ids=["non-standard-constant", "nested-too-deep"], -) -def test_the_candidate_walk_reports_a_file_it_cannot_walk( - tmp_path: Path, content: bytes -) -> None: - """The walk reads a run's files as the contract does: NaN is refused and - a nesting too deep to recurse is reported, never a crash.""" - - module = _load() - candidate = _good_candidate(tmp_path) - (candidate / "microcosm_uk_2024_25_local.diagnostics.json").write_bytes(content) - (warning,) = module.candidate_disclosure_warnings(candidate) - assert warning.startswith( - "microcosm_uk_2024_25_local.diagnostics.json cannot be read and walked as " - "JSON, so the disclosure walk cannot rule out" - ) + module.main(["--env", "--incumbent-manifest", str(missing)]) def test_release_dir_contract_warnings_print_without_failing( tmp_path: Path, monkeypatch, capsys ) -> None: - """The contract's warnings (its disclosure walk, microcosm#1301) never - fail the pre-flight; its failures still do.""" + """The contract's warnings never fail the pre-flight; its failures + still do.""" from microcosm.data import contract module = _load() diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_national_graph.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_national_graph.py index 63eb90c0ac..b828a47ef3 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_national_graph.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_national_graph.py @@ -65,7 +65,6 @@ from test_support.microcosm_build import uk_calibration_run as seam from test_support.microcosm_build.uk_calibration_run import ( # noqa: F401 _cgt_projection, - _every_seam_row_published, _signing_key, ) @@ -511,33 +510,28 @@ def test_national_gates_evaluate_the_seam_scope_and_record_the_evidence( } -def test_national_gates_withhold_a_thin_row_and_judge_only_the_published( - tmp_path, monkeypatch -): - """María's rule of 2026-10-21 on the seam: the fixture's one row is thin. - - Two source households carry it, so its figures stay in the build: the - evidence row is blank and flagged, the manifest's losses are read over the - published rows, and the fit gate, with no published row to judge, blocks - without naming the row. - """ - from microcosm.build.uk_runtime import diagnostics +def test_national_gates_judge_a_thin_row_with_its_figures(tmp_path, monkeypatch): + """María's ruling of 2026-10-26 on the seam: the fixture's one row rests + on two source households, and it keeps its figures and is judged; the + manifest's losses are the solve's own.""" - monkeypatch.setattr(diagnostics, "UK_DIAGNOSTIC_MIN_SOURCE_HOUSEHOLDS", 10) national, manifest, store, frame, registry = _run(tmp_path, monkeypatch) row_name = registry.specs[0].to_target().row_name evidence = json.loads( _payload(manifest, store, NATIONAL_GATES_NODE, "calibration_evidence") ) (row,) = evidence["diagnostics"] - assert row["name"] == row_name and row["model_figures_withheld"] is True - assert row["estimate"] is None and row["relative_error"] is None + assert row["name"] == row_name and "model_figures_withheld" not in row + assert np.isfinite(row["estimate"]) and np.isfinite(row["relative_error"]) calibration = evidence["calibration"] - assert calibration["totals_basis"] == "published_rows" - assert calibration["model_figures_withheld"] == 1 + assert "totals_basis" not in calibration + assert "model_figures_withheld" not in calibration report = json.loads(_payload(manifest, store, NATIONAL_GATES_NODE, "gate_report")) - assert report["blocking"] == ["uk_target_fit"] - assert row_name.split("@")[0] not in json.dumps(report["report"]) + outcomes = {outcome["id"]: outcome for outcome in report["report"]["outcomes"]} + fit = outcomes["uk_target_fit"] + assert fit["status"] == "passed" + assert fit["details"]["targets_checked"] == 1 + assert "withheld_targets" not in fit["details"] def test_national_problem_refuses_an_empty_register(tmp_path, monkeypatch): diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_orrery_contract.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_orrery_contract.py index 06770675d8..af288d6d8c 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_orrery_contract.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_orrery_contract.py @@ -272,11 +272,7 @@ def test_unavailable_checkpoint_bytes_are_named_not_linked(tmp_path): def _brma_problem(n: int = 12, level: str = "brma"): """An ordered problem over ``n`` households binding one constituency row on - all of them and one Scottish BRMA row on four, its level spelt ``level``. - - Every row with fewer than ten source households is withheld (María's - rule of 2026-10-21), so the constituency row needs the twelve to publish. - """ + all of them and one Scottish BRMA row on four, its level spelt ``level``.""" import numpy as np import pandas as pd @@ -331,207 +327,18 @@ def _brma_problem(n: int = 12, level: str = "brma"): return frame, decode_problem(payload), payload -def _brma_summary(): - """A two-row result and its summary data: a published row and a thin BRMA row.""" +@pytest.mark.parametrize("level", ["brma", "statistical_scope", "constituency"]) +def test_a_size_summary_keeps_its_all_row_totals_but_no_rows_figure(level): + """The size summary keeps the losses over every row, whatever it binds, + but not the largest change in one row, which may rest on fewer than ten + source households (Vahid's review of #1396, M1).""" from types import SimpleNamespace - import numpy as np - - frame, ordered, _ = _brma_problem() - - def row(name, target, estimate): - return SimpleNamespace( - name=name, - target=target, - initial_estimate=estimate, - final_estimate=estimate, - relative_error=(estimate - target) / target, - ) - - result = SimpleNamespace( - weights=np.ones(12), - frame=frame, - diagnostics=[ - row(ordered.problem.names[0], 4.0, 4.0), - row(ordered.problem.names[1], 40.0, 4.0), - ], - target_loss_weights=np.ones(2), - target_loss_scales=np.array([4.0, 40.0]), - target_loss_cap=10.0, - options={"target_loss_cap": 10.0}, - ) - data = { - "overview": {"final_loss": 0.45}, - "tables": { - "targets": [ - { - "name": diagnostic.name, - "target": diagnostic.target, - "initial": diagnostic.initial_estimate, - "achieved": diagnostic.final_estimate, - "residual": diagnostic.final_estimate - diagnostic.target, - "relative_error": diagnostic.relative_error, - "within_tolerance": False, - } - for diagnostic in result.diagnostics - ] - }, - } - return result, data, ordered - - -def test_the_published_result_summary_withholds_a_thin_brma_row(): - """microcosm#1262: Orrery publishes no figure a build withholds. - - The BRMA row rests on four source households, so its summary row keeps - its target and loses its figures, and the final loss covers the - published row (María's rulings of 2026-10-17 and 2026-10-18). - """ - from microcosm.build.uk_runtime.orrery_contract import _withhold_summary_rows - - result, data, ordered = _brma_summary() - _withhold_summary_rows(data, result, ordered) - published, withheld = data["tables"]["targets"] - assert published["achieved"] == 4.0 - assert withheld["target"] == 40.0 and withheld["model_figures_withheld"] is True - assert all( - withheld[field] is None - for field in ("initial", "achieved", "residual", "relative_error") - ) - assert data["overview"]["final_loss"] == 0.0 - assert data["overview"]["model_figures_withheld"] == { - "targets": 1, - "totals_basis": "published_rows", - } - - -def _gate_context(names, nodes, predecessors): - """A summary context over node ``result``: gate receipts and their payloads. - - ``nodes`` maps a node to the output it recorded (``calibration_evidence`` - for the national gates, ``calibration_diagnostics`` for the full build's - terminal) and the rows it withheld. - """ - - from types import SimpleNamespace - - from microcosm.build.uk_runtime.graph_national import NATIONAL_EVIDENCE_TYPE - from microcosm.build.uk_runtime.graph_terminal import FULL_DIAGNOSTICS_TYPE - - types = { - "calibration_evidence": NATIONAL_EVIDENCE_TYPE, - "calibration_diagnostics": FULL_DIAGNOSTICS_TYPE, - } - payloads, receipts = {}, {} - for node, (output, withheld) in nodes.items(): - if output == "calibration_evidence": - rows = [{"name": n, "model_figures_withheld": n in withheld} for n in names] - payloads[node] = {"diagnostics": rows} - else: - rows = [ - {"name": n, "metadata": {"model_figures_withheld": "withheld"}} - if n in withheld - else {"name": n, "metadata": {}} - for n in names - ] - payloads[node] = {"targets": rows} - type_ = types[output] - receipts[node] = SimpleNamespace( - typed_artifacts={ - "outputs": { - output: { - "type": { - "name": type_.name, - "schema_version": type_.schema_version, - }, - "key": node, - } - } - }, - opaque_artifacts={output}, - ) - return SimpleNamespace( - node_id="result", - run=SimpleNamespace( - compiled=SimpleNamespace(predecessors={"result": (), **predecessors}), - manifest=SimpleNamespace(nodes=receipts), - ), - store=SimpleNamespace( - load_bytes=lambda key: json.dumps(payloads[key]).encode() - ), - ) - - -def test_the_summary_takes_the_rows_a_gate_on_its_result_withheld(monkeypatch): - """Vahid's third review of #1383, item 32: a build withholds once. - - A gate that reads the result directly recorded the rows it withheld; the - summary takes that set without counting again, and counts again only when - the gate did not see every summary row. - """ - - from microcosm.build.uk_runtime import diagnostics from microcosm.build.uk_runtime.orrery_contract import ( - _recorded_withheld, - _withhold_summary_rows, + _size_summary, + public_summary_findings, ) - result, data, ordered = _brma_summary() - published, thin = ordered.problem.names - names = [published, thin] - for output in ("calibration_evidence", "calibration_diagnostics"): - context = _gate_context( - names, {"gates": (output, {thin})}, {"gates": ("problem", "result")} - ) - assert _recorded_withheld(context) == (frozenset(names), frozenset({thin})) - - def counted_again(*args, **kwargs): - raise AssertionError("the summary counted the withholding again") - - with monkeypatch.context() as patch: - patch.setattr(diagnostics, "uk_withheld_rows", counted_again) - _withhold_summary_rows(data, result, ordered, _recorded_withheld(context)) - first, second = data["tables"]["targets"] - assert first["achieved"] == 4.0 - assert second["model_figures_withheld"] is True and second["achieved"] is None - - # A gate that saw only the published row is not taken: the summary counts. - result, data, ordered = _brma_summary() - _withhold_summary_rows(data, result, ordered, (frozenset({published}), frozenset())) - assert data["tables"]["targets"][1]["model_figures_withheld"] is True - - -def test_only_a_gate_reading_the_result_directly_records_its_withheld_rows(): - """A gate on another node, or one that has not run, records nothing here.""" - - from microcosm.build.uk_runtime.orrery_contract import _recorded_withheld - - names = ["a", "b"] - elsewhere = _gate_context( - names, {"gates": ("calibration_evidence", {"a"})}, {"gates": ("other",)} - ) - assert _recorded_withheld(elsewhere) is None - not_run = _gate_context(names, {}, {"gates": ("result",)}) - assert _recorded_withheld(not_run) is None - disagreeing = _gate_context( - names, - { - "national": ("calibration_evidence", {"a"}), - "terminal": ("calibration_diagnostics", {"b"}), - }, - {"national": ("result",), "terminal": ("result",)}, - ) - with pytest.raises(ValueError, match="different withheld rows"): - _recorded_withheld(disagreeing) - - -@pytest.mark.parametrize("level", ["brma", "statistical_scope"]) -def test_a_size_summary_over_brma_rows_publishes_no_all_row_total(level): - """Either spelling of the level is a BRMA row (the fourth review of #1305).""" - from types import SimpleNamespace - - from microcosm.build.uk_runtime.orrery_contract import _size_summary - _, ordered, payload = _brma_problem(level=level) receipt = { "method": "full_pool", @@ -545,51 +352,21 @@ def test_a_size_summary_over_brma_rows_publishes_no_all_row_total(level): payload=json.dumps(receipt).encode(), input_payload=lambda name: payload, ) - overview = _size_summary(context)["overview"] + data = _size_summary(context) + overview = data["overview"] assert overview["requested_households"] == 4 - assert all( - overview[field] is None - for field in ("dense_loss", "compact_loss", "max_target_scaled_change") - ) - - -def test_a_size_summary_over_any_problem_publishes_no_all_row_total(): - """Since María's rule of 2026-10-21 any problem may bind a thin row. - - The summary cannot count a row's carriers without the weights, so a - problem with no BRMA row withholds its all-row totals too. - """ - from types import SimpleNamespace - - from microcosm.build.uk_runtime.orrery_contract import _size_summary - - _, ordered, payload = _brma_problem(level="constituency") - receipt = { - "method": "full_pool", - "problem_sha256": ordered.sha256, - "dense_loss": 0.2, - "compact_loss": 0.3, - "max_target_scaled_change": 0.4, - "requested_households": 4, - } - context = SimpleNamespace( - payload=json.dumps(receipt).encode(), - input_payload=lambda name: payload, - ) - overview = _size_summary(context)["overview"] - assert all( - overview[field] is None - for field in ("dense_loss", "compact_loss", "max_target_scaled_change") - ) + assert (overview["dense_loss"], overview["compact_loss"]) == (0.2, 0.3) + assert "max_target_scaled_change" not in overview + assert public_summary_findings([{"data": data}]) == [] + overview["max_target_scaled_change"] = 0.4 + assert public_summary_findings([{"node": "size", "artifact": "size", "data": data}]) @pytest.mark.parametrize("level", ["brma", "statistical_scope"]) -def test_the_registered_result_provider_withholds_a_thin_brma_row(level, monkeypatch): - """The third review of #1305: through the provider, not the helper alone. - - Deleting the withholding call from the registered provider failed no - test, and a row spelt ``statistical_scope`` escaped it. - """ +def test_the_registered_result_provider_publishes_no_rows_figures(level, monkeypatch): + """The BRMA row rests on four source households. Since María's ruling of + 2026-10-26 the build no longer marks such rows, so the registered provider + projects no row's figures, thin or not (Vahid's review of #1396, M1).""" from types import SimpleNamespace import numpy as np @@ -644,9 +421,67 @@ def row(name, target, estimate): (RESULT_TYPE.name, RESULT_TYPE.schema_version) ] data = provider(context) - published, withheld = data["tables"]["targets"] - assert published["achieved"] == 4.0 - assert withheld["model_figures_withheld"] is True - assert withheld["achieved"] is None and withheld["relative_error"] is None - assert data["overview"]["final_loss"] == 0.0 - assert data["overview"]["model_figures_withheld"]["targets"] == 1 + rows = data["tables"]["targets"] + assert [row["target"] for row in rows] == [4.0, 40.0] + for row in rows: + assert not { + "initial", + "achieved", + "residual", + "relative_error", + "within_tolerance", + } & set(row) + assert data["overview"]["final_loss"] == 0.45 + assert "model figures" in data["overview"]["record_scope"] + summary = {"node": "uk.full.dense", "artifact": "result", "data": data} + assert orrery_contract.public_summary_findings([summary]) == [] + rows[1]["achieved"] = 4.0 + assert orrery_contract.public_summary_findings([summary]) == [ + "uk.full.dense/result carries achieved" + ] + + +def test_a_gate_summary_counts_failure_lines_without_carrying_them(): + """A failure line can state a row's figures or an area's support, so the + summary keeps each gate's verdict and the number of its lines (Vahid's + review of #1396, M1).""" + from types import SimpleNamespace + + from microcosm.build.uk_runtime.orrery_contract import ( + _gate_report_summary, + public_summary_findings, + ) + + def outcome(gate, status, failures): + return { + "id": gate, + "gate": gate, + "phase": "calibrated", + "criticality": "release_blocking", + "status": status, + "reason": None, + "failures": failures, + "evidence_sha256": "0" * 64, + } + + report = { + "schema_version": 1, + "phase": "calibrated", + "gates_manifest_sha256": "1" * 64, + "outcomes": [ + outcome("uk_area_support", "failed", ["E14000001: rows 3 < 10"]), + outcome("uk_target_fit", "passed", []), + ], + } + data = _gate_report_summary(SimpleNamespace(payload=json.dumps(report).encode())) + support, fit = data["tables"]["gates"] + assert (support["status"], support["failure_count"]) == ("failed", 1) + assert (fit["status"], fit["failure_count"]) == ("passed", 0) + assert "failures" not in support and "E14000001" not in json.dumps(data) + assert data["overview"]["status_counts"]["failed"] == 1 + summary = {"node": "uk.full.gates.calibrated", "artifact": "gate_report"} + assert public_summary_findings([{**summary, "data": data}]) == [] + support["failures"] = ["E14000001: rows 3 < 10"] + assert public_summary_findings([{**summary, "data": data}]) == [ + "uk.full.gates.calibrated/gate_report carries gate failure lines" + ] diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_orrery_publication.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_orrery_publication.py index 393e4040eb..a4fa49c0ef 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_orrery_publication.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_orrery_publication.py @@ -13,7 +13,10 @@ orrery_publication, rowwise_staging, ) -from microcosm.build.uk_runtime.orrery_contract import save_uk_graph_schema +from microcosm.build.uk_runtime.orrery_contract import ( + public_summary_findings, + save_uk_graph_schema, +) from microcosm.graph import ( ContentStore, Graph, @@ -254,16 +257,20 @@ def publish(directory, inventory, **options): @pytest.mark.parametrize( "explicit,local,disabled,expected", [ - (None, False, False, True), + (None, False, False, False), (None, True, False, False), (None, False, True, False), + (True, False, False, True), (True, True, True, True), (False, False, False, False), ], ) -def test_publication_has_explicit_local_only_and_opt_out_controls( +def test_publication_is_opt_in_whatever_the_staging( explicit, local, disabled, expected ): + """María's ruling of 2026-10-26: a build publishes its graph to the + public Orrery only on ``--publish-orrery``, staged or not.""" + args = Namespace( publish_orrery=explicit, staging_local_only=local, no_staging=disabled ) @@ -342,20 +349,105 @@ def publish_graph(self, directory, inventory, *, wait_seconds): assert (args.out / "orrery.evidence-manifest.json").is_file() -def synthetic_build_request(tmp_path, monkeypatch, failure=None): +def synthetic_build_request(tmp_path, monkeypatch, failure=None, extra=()): """A synthetic dense build request whose run records execution.""" pytest.importorskip("tables") full_build_support.patch_certification(monkeypatch) - args = full_build_support.arguments(tmp_path) + args = full_build_support.arguments(tmp_path, *extra) return args, full_build_support.prepared(tmp_path, failure) -def synthetic_full_build(tmp_path, monkeypatch, failure=None): +def synthetic_full_build(tmp_path, monkeypatch, failure=None, extra=()): """Run a synthetic dense build; return its arguments and exit status.""" - args, build = synthetic_build_request(tmp_path, monkeypatch, failure) + args, build = synthetic_build_request(tmp_path, monkeypatch, failure, extra) return args, full_build_support.cli.execute_full_build(build, args) +def published_summaries(directory: Path) -> list[dict]: + """The recorded summaries a preserved publication would submit.""" + inventory = json.loads((directory / "orrery.upload.json").read_bytes()) + return [ + summary + for entry in inventory["files"] + if entry["role"] == "summaries" + for summary in json.loads((directory / entry["name"]).read_bytes()) + ] + + +def test_a_refused_build_submits_gate_verdicts_without_their_failure_lines( + tmp_path, monkeypatch +): + """Vahid's review of #1396, M1: a failure line can state a row's figures + or an area's support, so the published summaries count the lines.""" + args, status = synthetic_full_build( + tmp_path, + monkeypatch, + "uk_local_geography_ladder_post_calibration", + extra=("--publish-orrery",), + ) + assert status == 1 + evidence = json.loads( + (args.out / orrery_publication.EVIDENCE_MANIFEST_NAME).read_bytes() + ) + assert evidence["orrery_publication"]["status"] == "pending" + preserved = args.attempt_evidence / "orrery-publication" + summaries = published_summaries(preserved) + gates = [ + row + for summary in summaries + for row in summary["data"].get("tables", {}).get("gates", []) + ] + failed = [row for row in gates if row["status"] == "failed"] + assert failed and all(row["failure_count"] > 0 for row in failed) + assert not any("failures" in row for row in gates) + assert public_summary_findings(summaries) == [] + document = json.loads((preserved / "graph.orrery.json").read_bytes()) + assert public_summary_findings(document["metadata"]["execution"]["summaries"]) == [] + + +def test_a_summary_with_failure_lines_is_never_preserved_for_publication( + tmp_path, monkeypatch, fake_telemetry_emitters +): + """Vahid's review of #1396, M1: the export checks the summaries before it + preserves anything, so a provider that regresses leaves no inventory for + the build or the emitter's retry to submit.""" + from microcosm.build.uk_runtime import orrery_contract + from microcosm.build.uk_runtime.graph_terminal import FULL_GATE_REPORT_TYPE + + key = (FULL_GATE_REPORT_TYPE.name, FULL_GATE_REPORT_TYPE.schema_version) + projected = orrery_contract.UK_SUMMARY_PROVIDERS[key] + + def regressed(context): + data = projected(context) + for row in data["tables"]["gates"]: + row["failures"] = ["a line"] + return data + + monkeypatch.setitem(orrery_contract.UK_SUMMARY_PROVIDERS, key, regressed) + monkeypatch.setattr( + orrery_publication, + "publish_graph", + lambda *a, **k: pytest.fail("submitted an unpublishable summary"), + ) + args, status = synthetic_full_build( + tmp_path, monkeypatch, extra=("--publish-orrery",) + ) + assert status == 0 + receipt = json.loads((args.out / orrery_publication.RECEIPT_NAME).read_bytes()) + assert (receipt["status"], receipt["error_code"]) == ( + "failed", + "unpublishable_summary", + ) + preserved = args.attempt_evidence / "orrery-publication" + assert not (preserved / orrery_publication.INVENTORY_NAME).exists() + assert not (preserved / "graph.orrery.json").exists() + assert not any( + message.get("action") == "graph_publication" + for emitter in fake_telemetry_emitters + for message in emitter.messages + ) + + def test_execution_overlay_reprojects_to_the_exported_orrery_artifact( tmp_path, monkeypatch ): diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_release_certification.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_release_certification.py index eb60003785..5baac52743 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_release_certification.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_release_certification.py @@ -142,27 +142,25 @@ class _Reference: parity_reference=_Reference(), ) assert evidence.candidate_targets == {"dwp.uc.households@2025"} - assert evidence.withheld_targets == frozenset() - # A row that fewer than ten source households carry is published without - # its figures (María's rule of 2026-10-21): stated, kept on the candidate - # side, and outside the fit gate's errors. - thin = "dwp.uc.payment_distribution_single_thin@2025" - evidence = uk_release_parity_evidence( - _Frame(), - diagnostics_targets=[ - {"name": "dwp.uc.households@2025", "relative_error": 0.1}, - { - "name": thin, - "relative_error": None, - "metadata": {"model_figures_withheld": "model figures withheld"}, - }, - ], - reference_registry=_Registry(), - parity_reference=_Reference(), - ) assert evidence.target_relative_errors == {"dwp.uc.households@2025": 0.1} - assert evidence.withheld_targets == {thin} - assert evidence.candidate_targets == {"dwp.uc.households@2025", thin} + # A run built before María's ruling of 2026-10-26 dropped the withholding + # left a thin row's figures blank; the fit gate judges every row, so such + # a run is refused rather than certified without the row. + thin = "dwp.uc.payment_distribution_single_thin@2025" + with pytest.raises(UKReleaseCertificationError, match="withholds its model"): + uk_release_parity_evidence( + _Frame(), + diagnostics_targets=[ + {"name": "dwp.uc.households@2025", "relative_error": 0.1}, + { + "name": thin, + "relative_error": None, + "metadata": {"model_figures_withheld": "model figures withheld"}, + }, + ], + reference_registry=_Registry(), + parity_reference=_Reference(), + ) def test_compose_green_certification(green_certification_inputs): @@ -563,8 +561,7 @@ def test_release_cut_battery_runs_and_signs(tmp_path: Path, monkeypatch): local_ledger_registries={2025: object()}, ledger_unsupported={2025: ()}, local_ledger_unsupported={2025: ()}, - # Every producer states its withheld rows (María's rule of 2026-10-21). - parity_evidence=SimpleNamespace(withheld_targets=frozenset()), + parity_evidence=SimpleNamespace(), fit_weight_records=None, input_mass_reference={}, exclusions_evaluated_on=date(2026, 8, 27), diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_rowwise_national_role.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_rowwise_national_role.py index f65a09640d..e684c94f39 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_rowwise_national_role.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_rowwise_national_role.py @@ -65,7 +65,6 @@ from test_support.microcosm_build import uk_rowwise_candidate as candidate from test_support.microcosm_build.uk_calibration_run import ( # noqa: F401 _cgt_projection, - _every_seam_row_published, _signing_key, ) diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_stage_health.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_stage_health.py index 8bdb248900..bce86d584b 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_stage_health.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_stage_health.py @@ -2358,8 +2358,13 @@ def gate(families, **counts): assert not gate( {**good, "LONE_PARENT": family(2_100.0, 1_400.0, 1_100.0, 0.0, 0.0)} ).passed - # A caseload resting on fewer than ten sources cannot be checked. - assert not gate({**good, "SINGLE": family(3_000.0, "<10", 1.0, 0.0, 0.0)}).passed + # A caseload resting on fewer than ten sources cannot be checked: it is + # flagged, never failed (María's ruling of 2026-10-26); one missing fails. + thin = gate({**good, "SINGLE": family(3_000.0, "<10", 1.0, 0.0, 0.0)}) + assert thin.passed, thin.failures + assert thin.details["family_types_unchecked_small_cells"] == ["SINGLE"] + assert gate(good).details["family_types_unchecked_small_cells"] == [] + assert not gate({**good, "SINGLE": family(3_000.0, None, 1.0, 0.0, 0.0)}).passed assert not gate({}).passed # The caseloads are population facts: a synthetic smoke fixture records the # failure without blocking, every other posture blocks on it. @@ -2758,6 +2763,21 @@ def test_property_purchases_gate_holds_each_kind_to_hmrc_within_the_contract() - ) +def test_property_purchases_gate_flags_a_kind_on_fewer_than_ten_buyers() -> None: + """A kind whose buyers rest on fewer than ten sources prints "<10": it is + flagged unchecked, never failed (María's ruling of 2026-10-26).""" + thin = _purchases_receipt() + name = thin["kinds"][0]["property_type"] + thin["kinds"][0].update( + fitted_transactions="<10", fitted_value="<10", value_shortfall_share="<10" + ) + result = _gate("uk_stage_property_purchases_fit", thin) + assert result.passed, result.failures + assert result.details["kinds_unchecked_small_cells"] == [name] + clean = _gate("uk_stage_property_purchases_fit", _purchases_receipt()) + assert clean.details["kinds_unchecked_small_cells"] == [] + + def _home_values_receipt() -> dict: regions = [f"E1200000{index}" for index in range(1, 10)] + ["W92000004"] return { @@ -2779,6 +2799,8 @@ def _home_values_receipt() -> dict: (lambda r: r["rows_rewritten_by_region"].update(E12000007=0), "no row"), (lambda r: r.update(rows=40), "more rows"), (lambda r: r.update(sources_at_cap=1), "value cap"), + # A band past the limit fails as plainly as the count it stands for. + (lambda r: r.update(sources_at_cap="<10"), "value cap"), (lambda r: r.update(knots_basis_year=2023), "basis year"), (lambda r: r["ranking"].update(rank_basis="national"), "ranking basis"), (lambda r: r.update(weighted_value_after=0.0), "not positive"), @@ -2795,6 +2817,17 @@ def test_regional_home_values_gate_holds_the_ranking_contract(mutate, fragment) assert any(fragment in failure for failure in result.failures), result.failures +def test_regional_home_values_gate_flags_a_region_of_fewer_than_ten_rows() -> None: + """A region the receipt prints "<10" rewrote one to nine rows: not empty, + and flagged rather than failed (María's ruling of 2026-10-26).""" + receipt = _home_values_receipt() + receipt["rows_rewritten_by_region"]["W92000004"] = "<10" + result = _gate("uk_stage_regional_home_values_ranking", receipt) + assert result.passed, result.failures + assert result.details["regions_rewritten_under_ten"] == ["W92000004"] + assert result.details["sources_at_cap_unchecked"] is False + + def _legacy_closure_receipt() -> dict: return { "stage": "uc_legacy_closure_take_up", @@ -2823,7 +2856,11 @@ def test_legacy_closure_gate_reads_what_the_receipt_prints() -> None: # A thin drawn cohort prints its share withheld. withheld = _legacy_closure_receipt() withheld["great_britain_weighted_share_claiming_at_closure"] = "<10" - assert _passed(_gate(gate_id, withheld)) + flagged = _gate(gate_id, withheld) + assert _passed(flagged) + # What it could not read is flagged (María's ruling of 2026-10-26). + assert flagged.details["share_claiming_at_closure_withheld"] is True + assert flagged.details["unreachable_flags_withheld"] == 1 for mutate, fragment in ( (lambda r: r.update(p_basis="calibrated_weights"), "measured on"), (lambda r: r["combinations"]["housing_benefit"].update(rate=1.2), "rate 1.2"), @@ -3022,7 +3059,9 @@ def failing(change, fragment: str) -> None: # A residual withheld for resting on under ten donors is under the ceiling. withheld = copy.deepcopy(shares) withheld[tobacco]["donor"]["total_beside_lines"] = "<10" - assert run(receipt, withheld).passed + flagged = run(receipt, withheld) + assert flagged.passed + assert flagged.details["residuals_unchecked_small_cells"] == [tobacco] with pytest.raises(ValueError, match="excise_quantities must be an object"): run(None) @@ -3138,11 +3177,21 @@ def failing(change, fragment: str) -> None: lambda r, e: e["keys"]["national_lottery"].update(positive_share=0.1), "excise levelling", ) - failing( - lambda r, e: r["keys"].update(national_lottery={"withheld": True}), - "withholds", - ) failing(lambda r, e: r["keys"].pop("betting_and_gaming"), "tops up no") + # A key withheld nationally is named unchecked, never failed (María's + # ruling of 2026-10-26). + national = copy.deepcopy(receipt) + national["keys"]["national_lottery"] = { + **{ + name: national["keys"]["national_lottery"][name] + for name in ("added_without_stake", "propensity", "strata") + }, + "withheld": True, + } + result = run(national) + assert result.passed, result.failures + assert result.details["keys_unchecked_small_cells"] == ["national_lottery"] + assert passed.details["keys_unchecked_small_cells"] == [] # A withheld stratum is counted, not checked. withheld = copy.deepcopy(receipt) withheld["keys"]["national_lottery"]["strata"][shipped] = {"withheld": True} diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_take_up_contract.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_take_up_contract.py index 0bfc2f958d..d566f2d3c0 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_take_up_contract.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_take_up_contract.py @@ -46,15 +46,15 @@ def test_uk_contract_loads_and_selects_build_year_rates() -> None: 0.6, 0.55, 0.5, - # The tool-version-7 refit: the DfE rows at the spring term, universal - # nested under working parent (at its lower bound), one usage share per - # DfE age under 2 (age 1 at its upper bound). - 0.9697, - 0.8262, - 0.6962, + # The tool-version-7 refit on policyengine-uk 2.151.0: the DfE rows at + # the spring term, universal nested under working parent (at its lower + # bound), one usage share per DfE age under 2 (age 1 at its upper bound). + 0.9134, + 0.8217, + 0.7, 1.0, 0.0, - 0.6551, + 0.8687, 0.441, 0.2682, 0.97, @@ -139,7 +139,7 @@ def test_year_selection_uses_latest_value_at_or_before_build_year() -> None: assert contract.rate("child_benefit", 2021) == 0.97 assert contract.rate("child_benefit", 2023) == 0.89 - assert contract.rate("tax_free_childcare", 2024) == 0.9697 + assert contract.rate("tax_free_childcare", 2024) == 0.9134 assert contract.rate("tax_free_childcare", 2023) == 0.586 assert contract.rate("tv_licence_evasion_rate", 2024) == 0.1252 assert contract.rate("tax_free_childcare_spend_routed_share", 2017) == 0.359 diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_take_up_gate.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_take_up_gate.py index 894a808fc7..e0abd8aa5e 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_take_up_gate.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_take_up_gate.py @@ -200,3 +200,38 @@ def test_take_up_gate_measures_under_two_usage_over_claiming_children() -> None: missing = uk_take_up_signal_gate(frame, contract=_Contract()) assert missing.passed is False assert "max_free_entitlement_hours_used: missing" in " ".join(missing.failures) + + +class _OffRateContract(_Contract): + """The fixture's realised shares are 0.5; these rates sit 0.075 above them.""" + + def rate(self, key: str, build_year: int | None = None) -> float: + if key in ( + "extended_childcare_age_0_usage", + "extended_childcare_age_1_usage", + "property_purchase_rate", + ): + return 0.575 + return super().rate(key, build_year) + + +def test_take_up_gate_holds_under_two_usage_to_its_own_bound() -> None: + usage = "person.max_free_entitlement_hours_used" + + shared = uk_take_up_signal_gate(_frame(), contract=_OffRateContract()) + assert any(usage in failure for failure in shared.failures) + assert shared.details[usage]["maximum_share_deviation"] == 0.05 + + own = uk_take_up_signal_gate( + _frame(), + contract=_OffRateContract(), + under_two_usage_maximum_share_deviation=0.1, + ) + # The under-2 share is inside its own bound; every other flag keeps the + # shared one, so the household draw 0.075 off its rate still fails. + assert not any(usage in failure for failure in own.failures) + assert own.details[usage]["maximum_share_deviation"] == 0.1 + assert ( + own.details["household.property_purchased"]["maximum_share_deviation"] == 0.05 + ) + assert any("household.property_purchased" in failure for failure in own.failures) diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_terminal_gates.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_terminal_gates.py index 16b8837fc6..170f750bf4 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_terminal_gates.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_terminal_gates.py @@ -605,21 +605,12 @@ def test_committed_target_fit_register_retains_only_live_deferrals() -> None: # to +23.4 % across the C3 and final arms, inside the bound, and the gate # fails the deferral as stale. assert set(register) == { - "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_0_to_1_200@2025", - "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_1_200_to_2_400@2025", - "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_2_400_to_3_600@2025", - "dwp/uc_payment_dist/SINGLE_annual_payment_2_400_to_3_600@2025", - "hmrc.itl.taxpayers_by_total_income_band.band_2000000_plus@2025", - "hmrc.spi.savings_interest_income.count_by_total_income_band.band_150000@2025", - "hmrc.spi_region.taxpayers_by_region_200000_plus@E12000004@2025", - "hmrc/dividend_income_income_band_15_000_to_20_000@2025", "hmrc/dividend_income_income_band_20_000_to_30_000@2025", "hmrc/dividend_income_income_band_30_000_to_40_000@2025", "hmrc/dividend_income_income_band_40_000_to_50_000@2025", "hmrc/private_pension_income_income_band_12_570_to_15_000@2025", "hmrc/private_pension_income_income_band_15_000_to_20_000@2025", - "hmrc/property_income_income_band_12_570_to_15_000@2025", - "hmrc/property_income_income_band_15_000_to_20_000@2025", + "hmrc/state_pension_count_income_band_500_000_to_1_000_000@2025", } assert {record.release_lines for record in register.values()} == {("local",)} @@ -646,35 +637,27 @@ def test_committed_local_target_fit_register_is_empty_and_well_formed() -> None: assert set(register) == { "age_structure/E07000008/age/20_30", "age_structure/E14001080/age/20_30", - "age_structure/E14001081/age/20_30", - "age_structure/E14001086/age/20_30", "age_structure/E14001096/age/20_30", - "age_structure/E14001120/age/20_30", "age_structure/E14001131/age/20_30", "age_structure/E14001149/age/20_30", "age_structure/E14001182/age/20_30", + "age_structure/E14001301/age/20_30", "age_structure/E14001319/age/20_30", "age_structure/E14001338/age/20_30", - "age_structure/E14001352/age/20_30", "age_structure/E14001353/age/20_30", "age_structure/E14001412/age/20_30", "age_structure/E14001467/age/20_30", - "age_structure/S14000085/age/20_30", "age_structure/W07000091/age/20_30", "council_tax/E06000014/council_tax/band_a", - "council_tax/E09000033/council_tax/band_g", + "council_tax/E09000020/council_tax/band_b", + "council_tax/E09000033/council_tax/band_b", "council_tax/S12000013/council_tax/band_a", "domestic_energy/S12000013/energy/gas_connected_households", "domestic_energy/S12000017/energy/gas_connected_households", "domestic_energy/S12000023/energy/electricity_kwh", - "domestic_energy/S12000027/energy/electricity_kwh", - "hmrc_income_by_area/E14001538/hmrc/self_employment_income/count", - "private_rent/E06000043/rent/private_rent", - "private_rent/E08000003/rent/private_rent", - "private_rent/E09000033/rent/private_rent", - "tenure/E09000012/tenure/private_rent", - "tenure/E09000019/tenure/private_rent", - "tenure/E09000019/tenure/social_rent", + "domestic_energy/W06000008/energy/gas_connected_households", + "tenure/E09000020/tenure/owned_outright", + "tenure/S12000029/tenure/private_rent", } assert {record.release_lines for record in register.values()} == {("local",)} diff --git a/packages/microcosm-data/src/microcosm/data/contract.py b/packages/microcosm-data/src/microcosm/data/contract.py index 7ad3ced30b..52b98456ef 100644 --- a/packages/microcosm-data/src/microcosm/data/contract.py +++ b/packages/microcosm-data/src/microcosm/data/contract.py @@ -451,13 +451,13 @@ def compatibility_claim_declarer_error(declared_by: object) -> str | None: # fingerprint derives from the manifest digest. Editing the spec moves all # three here in the same reviewed change. _UK_GATE_BATTERY_POLICY_SHA256 = ( - "83ca8470cbc1801dc037b0b1d8c572846f6882f6e562a9db6b0c1bbb005efe0e" + "ce740f872559d9956314330765af414f7d8e767c1e666408fe9a7d209c41d04b" ) _UK_GATE_BATTERY_GATES_MANIFEST_SHA256 = ( - "ac1ad35e724feaa36ed498d7a4d20a8bbe9ffee75535cba7f8a4a79a0330f0d7" + "5be43f9fa28f0fa17c40b8d2035727b96e62d4e50bc674d266b425e67abb455d" ) _UK_GATE_BATTERY_SPEC_FINGERPRINT = ( - "486d32ed31529cea44f38c8419c1ed3678a83af622784f9cb3ba4eb5b9966f5b" + "0fdeef15e7590d85b30dc301481f24d4a093b2b139eb06c79b5303ae74b4b53a" ) #: Spec entry id -> the legacy gate name whose observable detail checks #: apply unchanged (the battery re-keys the report by entry id; the gate @@ -968,10 +968,10 @@ def _uk_line_cut_tag_re(release_id: str) -> re.Pattern[str] | None: }, "release_cut": { "gates_manifest_sha256": ( - "a7b17431dd71284bf93b5337036bc1b9b64a17eab0b161f78549ed72ab0ca61c" + "d64809b38019b29bc7bb07b3119dc5b29d4b3f1c95cdb1726657d0612eae47c6" ), "policy_sha256": ( - "ab5f2a1c14ffe72cbc5d65c7658827b81b9470a56278e6f961f3b6dfa12ca2d7" + "6c56029fafbd8eeb36693bdcb3a719675bbb9286a377953aa6050bb03cbe5d3e" ), }, } @@ -4551,8 +4551,8 @@ def _validate_uk_dense_release_dir(release_dir: Path, release_id: str) -> list[s the incumbent files ship all together or not at all, and the manifest's reviewed limitations must say what the release does not claim. Artifacts pin to the release id or to one of its immutable per-cut tags. - A shipped JSON document carrying a per-area support figure is a warning, - returned rather than refused (microcosm#1301). + Per-area support figures ship (María's ruling of 2026-10-26 dropped their + withholding, microcosm#1301), so the line returns no warnings. """ failures: list[str] = [] @@ -4612,7 +4612,6 @@ def _validate_uk_dense_release_dir(release_dir: Path, release_id: str) -> list[s if gate_summary is not None: _check_local_area_gates(gate_summary, failures) diagnostics_path = release_dir / "calibration_diagnostics.json" - floor_warnings: list[str] = [] if diagnostics_path.is_file(): diagnostics = _load_json(diagnostics_path, failures) if diagnostics is not None: @@ -4621,7 +4620,6 @@ def _validate_uk_dense_release_dir(release_dir: Path, release_id: str) -> list[s ): _check_calibration_diagnostics(diagnostics, failures) _check_local_area_calibration_diagnostics(diagnostics, failures) - floor_warnings = _uk_brma_floor_verdict_warnings(diagnostics) report: Mapping | None = None report_path = release_dir / _UK_DENSE_GATE_REPORT_FILE if report_path.is_file(): @@ -4647,9 +4645,6 @@ def _validate_uk_dense_release_dir(release_dir: Path, release_id: str) -> list[s coverage, failures, incumbent_attached=incumbent_attached ) _check_uk_measure_exclusions(coverage.get("measure_exclusions"), failures) - # Warned, not refused: the walk runs only after both builds, so a finding - # is weighed rather than paid for with a rebuild (microcosm#1301). - disclosure_warnings = _uk_dense_disclosure_warnings(release_dir) + floor_warnings # The core joins run whether or not the incumbent comparison is attached. candidate_identity = _check_uk_dense_surface_files( release_dir, release_manifest or {}, failures @@ -4682,7 +4677,7 @@ def _validate_uk_dense_release_dir(release_dir: Path, release_id: str) -> list[s _check_local_artifact_hashes(release_dir, release_manifest, failures) if failures: raise ReleaseContractError(release_dir, failures) - return disclosure_warnings + return [] def _check_uk_dense_gate_report( @@ -5096,12 +5091,13 @@ def _check_area_support_block( ) -# Per-area support figures a dense release withholds (microcosm#1301): an -# area's rows, Kish ESS and distinct source households, under each name the -# support table, the support gate, the diagnostics and the size evaluation -# have used for them, and the plain synonyms a converted table would carry. -# Weights and per-cell estimates are not support figures and ship as they are. -# Names match whatever their case. +# Per-area support figures (microcosm#1301): an area's rows, Kish ESS and +# distinct source households, under each name the support table, the support +# gate, the diagnostics and the size evaluation have used for them, and the +# plain synonyms a converted table would carry. A release ships them since +# María's ruling of 2026-10-26; the sign-off drafter still walks the entries +# it drafts for them, since those go into a public pull request. Weights and +# per-cell estimates are not support figures. Names match whatever their case. _UK_AREA_SUPPORT_FIGURE_KEYS = frozenset( { "rows", @@ -5233,7 +5229,11 @@ def _uk_names_only_regions(value: object) -> bool: def _uk_dense_disclosure_findings(name: str, payload: object) -> list[str]: - """Per-area support figures in one shipped JSON document (microcosm#1301). + """Per-area support figures in one JSON document (microcosm#1301). + + The sign-off drafter walks the entries it drafts with it, since they go + into a public pull request; a release no longer withholds these figures + (María's ruling of 2026-10-26). An area's rows, Kish ESS or distinct sources (a number, or a number written as text with or without thousands separators, under its name in @@ -5360,48 +5360,13 @@ def walk( "text": "string(s) stating an area's measured support", } return [ - f"{name} carries {len(paths)} {wording[kind]}, which a dense release " - "should withhold (microcosm#1301); first at " + f"{name} carries {len(paths)} {wording[kind]} (microcosm#1301); first at " f"{paths[:_UK_DISCLOSURE_PATHS_SHOWN]}." for kind, paths in found.items() if paths ] -def _uk_dense_disclosure_file_warnings(path: Path) -> list[str]: - """The disclosure walk's warnings for one JSON file (microcosm#1301). - - The file is read as the contract reads JSON, refusing NaN and the - infinities. A file the walk cannot read, parse or walk to the bottom of - (a nesting too deep to recurse) is reported, since a figure in it could - not be ruled out. The release pre-flight walks a run's files with it too. - """ - - try: - payload = json.loads(path.read_bytes(), parse_constant=_reject_json_constant) - return _uk_dense_disclosure_findings(path.name, payload) - except (OSError, ValueError, RecursionError): - return [ - f"{path.name} cannot be read and walked as JSON, so the disclosure " - "walk cannot rule out a per-area support figure in it " - "(microcosm#1301)." - ] - - -def _uk_dense_disclosure_warnings(release_dir: Path) -> list[str]: - """Shipped JSON documents carrying a per-area support figure (microcosm#1301). - - Every ``*.json`` in the release directory is walked, the signed gate - report and the release manifest's strings included. A document the walk - cannot read is reported too, since a figure in it could not be ruled out. - """ - - warnings: list[str] = [] - for path in sorted(release_dir.glob("*.json")): - warnings.extend(_uk_dense_disclosure_file_warnings(path)) - return warnings - - def _check_local_area_release_manifest( manifest: Mapping, release_id: str, @@ -6444,54 +6409,6 @@ def _uk_census_over(rows: list[Mapping], census: object) -> dict[str, object] | return counts -def _uk_brma_floor_verdict_warnings(diagnostics: Mapping) -> list[str]: - """BRMA rows whose ten-household verdict is missing or disagrees. - - microcosm#1262: every BRMA row carries ``metadata.carrier_floor_met``, and - a row withholds its model figures exactly when the verdict is false or the - row is withheld beside a thin one (``metadata.complementary_withholding``, - Vahid's second review of #1333), so the contract can see a thin row the - build never flagged. María's ruling of 2026-10-19 on the fourth review of - #1305: this is warned, not refused. The warnings give counts only, never a - row. - """ - - missing = disagreeing = 0 - for row in diagnostics.get("targets") or (): - metadata = row.get("metadata") if isinstance(row, Mapping) else None - if not isinstance(metadata, Mapping) or not _uk_brma_row(metadata): - continue - verdict = metadata.get("carrier_floor_met") - withheld = bool(metadata.get("model_figures_withheld")) - complementary = metadata.get("complementary_withholding") is True - if not isinstance(verdict, bool): - missing += 1 - elif (not verdict and (complementary or not withheld)) or ( - verdict and withheld != complementary - ): - disagreeing += 1 - warnings = [] - if missing: - warnings.append( - f"calibration_diagnostics.json has {missing} BRMA row(s) without a " - "ten-household carrier verdict (metadata.carrier_floor_met), so the " - "contract cannot see whether their model figures may be published " - "(microcosm#1262)." - ) - if disagreeing: - warnings.append( - f"calibration_diagnostics.json has {disagreeing} BRMA row(s) whose " - "carrier verdict disagrees with their withheld flag (microcosm#1262)." - ) - return warnings - - -def _uk_brma_row(metadata: Mapping) -> bool: - level = str(metadata.get("geography_level") or "").strip().lower() - area_type = str(metadata.get("area_type") or "").strip().lower() - return area_type == "brma" or level in {"brma", "statistical_scope"} - - def _check_uk_candidate_restated_losses( candidate: Mapping, diagnostics: Mapping, failures: list[str] ) -> None: @@ -6732,10 +6649,9 @@ def validate_release_dir( Returns: The contract's warnings, each a sentence naming the file, for the - caller to print. Only the dense UK line has any: its disclosure walk - reports per-area support figures (microcosm#1301), and a BRMA row - without its ten-household carrier verdict, or with one its withheld - flag contradicts, is reported (microcosm#1262), without refusing. + caller to print; they never refuse a release. No line returns any + since María's ruling of 2026-10-26 dropped the dense line's + disclosure walk (microcosm#1301). Raises: ReleaseContractError: Naming every violation found — missing files, diff --git a/packages/microcosm-data/src/microcosm/data/publish_cli.py b/packages/microcosm-data/src/microcosm/data/publish_cli.py index e41c9f1727..29cffb2a48 100644 --- a/packages/microcosm-data/src/microcosm/data/publish_cli.py +++ b/packages/microcosm-data/src/microcosm/data/publish_cli.py @@ -368,10 +368,10 @@ def main(argv: list[str] | None = None) -> int: preflight["narrowed_claims"] = narrowed if measurement: preflight["claim_measurement"] = measurement - # The contract's warnings (the dense line's disclosure walk, - # microcosm#1301) never refuse, so the verdict carries them for - # whatever parses stdout; each names a file and paths in it, never a - # value. Publication's printed pointer carries them the same way. + # The contract's warnings never refuse, so the verdict carries them + # for whatever parses stdout; each names a file and paths in it, + # never a value. Publication's printed pointer carries them the same + # way. if prepared.contract_warnings: preflight["contract_warnings"] = list(prepared.contract_warnings) print(json.dumps(preflight)) diff --git a/packages/microcosm-data/src/microcosm/data/release.py b/packages/microcosm-data/src/microcosm/data/release.py index 80a7a7ed87..4545fec77f 100644 --- a/packages/microcosm-data/src/microcosm/data/release.py +++ b/packages/microcosm-data/src/microcosm/data/release.py @@ -262,8 +262,7 @@ class PreparedRelease: """Validated local paths and upload destinations, prepared without Hub activity. ``contract_warnings`` are the release contract's warnings, which never - refuse a release: the dense UK line's disclosure walk names where a - shipped JSON document may carry a per-area support figure (microcosm#1301). + refuse a release; each names a file and paths in it, never a value. """ release_dir: Path diff --git a/packages/microcosm-data/tests/engine_free/shared/test_contract.py b/packages/microcosm-data/tests/engine_free/shared/test_contract.py index 7f1bdf16e5..410586399a 100644 --- a/packages/microcosm-data/tests/engine_free/shared/test_contract.py +++ b/packages/microcosm-data/tests/engine_free/shared/test_contract.py @@ -213,13 +213,13 @@ def _trusted_terminal_gate_signing_key(monkeypatch) -> None: UK_GATE_BATTERY_PRODUCER = "microcosm.build.gate_battery" UK_GATE_BATTERY_SIGNING_KEY_ENV = "MICROCOSM_UK_TERMINAL_GATE_SIGNING_KEY" UK_GATE_BATTERY_POLICY_SHA256 = ( - "83ca8470cbc1801dc037b0b1d8c572846f6882f6e562a9db6b0c1bbb005efe0e" + "ce740f872559d9956314330765af414f7d8e767c1e666408fe9a7d209c41d04b" ) UK_GATE_BATTERY_GATES_MANIFEST_SHA256 = ( - "ac1ad35e724feaa36ed498d7a4d20a8bbe9ffee75535cba7f8a4a79a0330f0d7" + "5be43f9fa28f0fa17c40b8d2035727b96e62d4e50bc674d266b425e67abb455d" ) UK_GATE_BATTERY_SPEC_FINGERPRINT = ( - "486d32ed31529cea44f38c8419c1ed3678a83af622784f9cb3ba4eb5b9966f5b" + "0fdeef15e7590d85b30dc301481f24d4a093b2b139eb06c79b5303ae74b4b53a" ) UK_GATE_BATTERY_DEGENERATE_EVIDENCE_SHA256 = ( "6a179222c6b6058ad9caacfd347f7bdb8cb98a62237b50d1fc1136df09337251" diff --git a/packages/microcosm-data/tests/engine_free/shared/test_release.py b/packages/microcosm-data/tests/engine_free/shared/test_release.py index fa7b05b7d3..efc73d6a39 100644 --- a/packages/microcosm-data/tests/engine_free/shared/test_release.py +++ b/packages/microcosm-data/tests/engine_free/shared/test_release.py @@ -1605,8 +1605,7 @@ def test_preflight_prepares_the_bound_gate_evidence_for_upload( def test_publication_repeats_the_contract_warnings_and_proceeds( release_dir: Path, artifact_root: Path, monkeypatch ) -> None: - """A contract warning, such as the dense line's disclosure walk finding a - per-area support figure (microcosm#1301), is repeated, not refused.""" + """A contract warning is repeated, not refused.""" monkeypatch.setattr( release_module, "validate_release_dir", @@ -1622,8 +1621,9 @@ def test_publication_repeats_the_contract_warnings_and_proceeds( assert prepared.contract_warnings == ("synthetic.json carries a synthetic finding",) -#: Contract warnings as the dense line's disclosure walk words them: a file -#: and the paths in it, never a value (microcosm#1301). +#: Synthetic contract warnings, worded as the dense line's disclosure walk +#: worded them until María's ruling of 2026-10-26 dropped it: a file and the +#: paths in it, never a value (microcosm#1301). _CONTRACT_WARNINGS = [ "synthetic.json carries 1 per-area support figure(s) (rows, ESS or distinct " "sources), which a dense release should withhold (microcosm#1301); first " diff --git a/packages/microcosm-data/tests/engine_free/uk/test_uk_dense_release_contract.py b/packages/microcosm-data/tests/engine_free/uk/test_uk_dense_release_contract.py index 76a2bca8f1..109b9eb48d 100644 --- a/packages/microcosm-data/tests/engine_free/uk/test_uk_dense_release_contract.py +++ b/packages/microcosm-data/tests/engine_free/uk/test_uk_dense_release_contract.py @@ -702,50 +702,21 @@ def test_the_candidate_manifest_restates_the_diagnostics_totals() -> None: assert len(failures) == 3, failures -def test_a_brma_row_without_its_carrier_verdict_is_warned_not_refused() -> None: - """María's ruling of 2026-10-19 on the fourth review of #1305: warn only.""" +def test_a_brma_row_needs_no_carrier_verdict() -> None: + """María's ruling of 2026-10-26 dropped the withholding and its BRMA + carrier verdict; an earlier release's verdicts still read, unchecked.""" - assert dc._uk_brma_floor_verdict_warnings(_withheld_diagnostics()) == [] unflagged = _withheld_diagnostics() del unflagged["targets"][1]["metadata"]["carrier_floor_met"] - (warning,) = dc._uk_brma_floor_verdict_warnings(unflagged) - # A count, never a row. - assert warning.startswith("calibration_diagnostics.json has 1 BRMA row(s) without") - disagreeing = _withheld_diagnostics() - disagreeing["targets"][1]["metadata"]["carrier_floor_met"] = True - (warning,) = dc._uk_brma_floor_verdict_warnings(disagreeing) - assert "disagrees with their withheld flag" in warning failures: list[str] = [] dc._check_local_area_calibration_diagnostics(unflagged, failures) assert failures == [] - - -def test_a_brma_row_withheld_beside_a_thin_one_agrees_with_its_verdict() -> None: - """Vahid's second review of #1333, item 10: a row withheld beside a thin - one meets the floor and says so (``metadata.complementary_withholding``).""" - - beside = _withheld_diagnostics() - beside["targets"][1]["metadata"].update( - carrier_floor_met=True, complementary_withholding=True - ) - assert dc._uk_brma_floor_verdict_warnings(beside) == [] - # Flagged as withheld beside a thin row, yet published. - published = _withheld_diagnostics() - published["targets"][1]["metadata"].update( - carrier_floor_met=True, complementary_withholding=True - ) - del published["targets"][1]["metadata"]["model_figures_withheld"] - (warning,) = dc._uk_brma_floor_verdict_warnings(published) - assert "disagrees with their withheld flag" in warning - # A thin row is withheld for itself, never only beside another. - thin = _withheld_diagnostics() - thin["targets"][1]["metadata"]["complementary_withholding"] = True - (warning,) = dc._uk_brma_floor_verdict_warnings(thin) - assert "disagrees with their withheld flag" in warning + assert not hasattr(dc, "_uk_brma_floor_verdict_warnings") def test_the_dense_validator_runs_the_withheld_checks(tmp_path, monkeypatch) -> None: - """The candidate cross-check and the verdict warnings run on a release.""" + """The candidate cross-check still runs on a release, for the releases + built while rows were withheld.""" seen: list[str] = [] @@ -753,15 +724,9 @@ def restated(candidate, diagnostics, failures) -> None: seen.append("restated") assert "solve" in candidate and "targets" in diagnostics - def verdicts(diagnostics) -> list[str]: - seen.append("verdicts") - return ["a synthetic verdict warning"] - monkeypatch.setattr(dc, "_check_uk_candidate_restated_losses", restated) - monkeypatch.setattr(dc, "_uk_brma_floor_verdict_warnings", verdicts) - warnings = validate_release_dir(write_dense_bundle(tmp_path)) - assert sorted(seen) == ["restated", "verdicts"] - assert "a synthetic verdict warning" in warnings + validate_release_dir(write_dense_bundle(tmp_path)) + assert seen == ["restated"] def test_the_withheld_block_must_count_the_withheld_rows() -> None: @@ -1762,17 +1727,11 @@ def today(cls): #: with support figures never reads as a real area's figures. _AREA = "E06999999" _OTHER_AREA = "E06999998" -#: The synthetic support figures the warning tests inject; no warning may +#: The synthetic support figures the walk tests inject; no finding may #: repeat one. _FIGURES = ("37", "23.75", "29", "41") -def _warning_lines(release_dir: Path) -> str: - """The contract's warnings for a release it otherwise passes: the - disclosure walk warns, never refuses (microcosm#1301).""" - return "\n".join(validate_release_dir(release_dir)) - - #: The area-support details a signed report may ship: the floors an excused #: area misses and its signed record, and area counts by level. _FLOOR_ONLY_DETAILS = { @@ -1813,18 +1772,13 @@ def _with_figures(details: dict) -> dict: return figures -@pytest.mark.parametrize( - "inject,expected", - [ - ("summary_shortfall_text", "string(s) stating an area's measured support"), - ("signed_report_figures", "per-area support figure(s)"), - ], -) -def test_dense_release_warns_on_per_area_support_figures( - tmp_path: Path, inject: str, expected: str +@pytest.mark.parametrize("inject", ["summary_shortfall_text", "signed_report_figures"]) +def test_a_dense_release_ships_per_area_support_figures( + tmp_path: Path, inject: str ) -> None: - """A shipped document carrying an area's rows, ESS or sources is a - warning, not a refusal (microcosm#1301).""" + """María's ruling of 2026-10-26 dropped the withholding of per-area + support figures (microcosm#1301): a shipped document carrying an area's + rows, ESS or sources draws no warning.""" if inject == "signed_report_figures": release_dir = write_dense_bundle( @@ -1833,11 +1787,9 @@ def test_dense_release_warns_on_per_area_support_figures( area_support_details=_with_figures(_FLOOR_ONLY_DETAILS) ), ) - name = "uk_local_gates.json" else: release_dir = write_dense_bundle(tmp_path) - name = "gate_summary.json" - path = release_dir / name + path = release_dir / "gate_summary.json" summary = json.loads(path.read_text()) summary["diagnostic_gates"]["uk_local_area_support"] = { "failures": [f"local_authority/{_AREA}: rows 37 < 50"] @@ -1845,12 +1797,7 @@ def test_dense_release_warns_on_per_area_support_figures( path.write_text(json.dumps(summary)) _refresh_packaging_checksums(release_dir) - warnings = _warning_lines(release_dir) - assert expected in warnings - assert name in warnings - # The warning names where the figure is, never its value. - for figure in _FIGURES: - assert figure not in warnings + assert validate_release_dir(release_dir) == [] _FIGURE = "per-area support figure(s)" @@ -1962,45 +1909,20 @@ def test_dense_release_warns_on_per_area_support_figures( @pytest.mark.parametrize("shape", sorted(_SUPPORT_FIGURE_SHAPES)) -def test_dense_release_warns_on_support_figures_in_every_shape( - tmp_path: Path, shape: str -) -> None: +def test_the_walk_finds_support_figures_in_every_shape(shape: str) -> None: """Records keyed by any area identifier, code-keyed maps, columnar tables, - lists and the extremes of a figure are warned about alike (microcosm#1301).""" + lists and the extremes of a figure are found alike (microcosm#1301). The + sign-off drafter walks the entries it drafts for a public PR with it.""" key, value, expected = _SUPPORT_FIGURE_SHAPES[shape] - release_dir = write_dense_bundle(tmp_path) - _rewrite_manifest(release_dir, lambda manifest: manifest.__setitem__(key, value)) - warnings = _warning_lines(release_dir) - assert "release_manifest.json carries" in warnings and expected in warnings - # The warning names where the figures are, never their values. - assert f"first at ['{key}" in warnings + findings = "\n".join( + dc._uk_dense_disclosure_findings("release_manifest.json", {key: value}) + ) + assert "release_manifest.json carries" in findings and expected in findings + # A finding names where the figures are, never their values. + assert f"first at ['{key}" in findings for figure in _FIGURES: - assert figure not in warnings - - -@pytest.mark.parametrize( - "content", - [ - b'{"support": {"rows": ', - b'{"rows": NaN}', - b'{"rows": "\xc3\x28"}', - b"[" * 100_000 + b"]" * 100_000, - ], - ids=["truncated", "non-standard-constant", "undecodable", "nested-too-deep"], -) -def test_dense_release_warns_on_a_json_document_it_cannot_walk( - tmp_path: Path, content: bytes -) -> None: - """A document the walk cannot read could hide a figure, so it is warned - about too.""" - - release_dir = write_dense_bundle(tmp_path) - (release_dir / "support_notes.json").write_bytes(content) - assert ( - "support_notes.json cannot be read and walked as JSON, so the disclosure " - "walk cannot rule out" - ) in _warning_lines(release_dir) + assert figure not in findings def test_disclosure_walker_allows_floors_counts_weights_and_estimates() -> None: diff --git a/packages/microcosm-diagnostics/src/microcosm/diagnostics/schema.py b/packages/microcosm-diagnostics/src/microcosm/diagnostics/schema.py index d504047ff2..ff318513d5 100644 --- a/packages/microcosm-diagnostics/src/microcosm/diagnostics/schema.py +++ b/packages/microcosm-diagnostics/src/microcosm/diagnostics/schema.py @@ -400,9 +400,9 @@ class UKAreaFit(DiagnosticsModel): worst_target: NonBlankText worst_abs_relative_error: NonNegativeFiniteFloat loss_contribution: NonNegativeFiniteFloat - # Per-area support figures are withheld from released diagnostics - # (microcosm#1301); a row carries the floor flag instead. The figure - # fields stay optional so earlier payloads still parse. + # The per-area support figures, which the releases built between + # microcosm#1301 and María's ruling of 2026-10-26 withheld; optional so + # those payloads still parse. The floor flag rides beside them. support_below_floor: bool | None = None nonzero_households: NonNegativeInt | None = None nonzero_source_households: NonNegativeInt | None = None diff --git a/packages/microcosm-graph/tests/fixtures/parity/uk_spine/uk_spine.json b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/uk_spine.json index 72650905b0..6a0581f884 100644 --- a/packages/microcosm-graph/tests/fixtures/parity/uk_spine/uk_spine.json +++ b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/uk_spine.json @@ -1 +1 @@ -{"country":"uk","nodes":[{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Load the source-bound UK FRS root population.","id":"create_uk_frs","inputs":[],"kernel":"uk.create@1","mass":"conserve","outputs":[{"column":"age","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"gender","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"months_since_last_birthday","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"marital_status","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"hours_worked","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"care_hours","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"is_household_head","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_benunit_head","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_parent","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_blind","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_uc_claimant","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_claimant_or_partner","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_hbai_dependent_child","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"uc_is_in_startup_period","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"uc_is_in_gainful_self_employment","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"rent_paid_as_boarder","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"rent_paid_as_lodger","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"employment_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"self_employment_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"trading_loss","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"loss_relief","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"ni_class_4_losses_brought_forward","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"private_pension_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"tax_free_savings_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"savings_interest_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"dividend_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"stands_as_sole_owner_or_partner_of_company","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_engaged_in_owned_company_trade","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"owned_company_is_main_employment","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"owned_company_carries_on_trade","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"owned_company_carries_on_property_business","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"owned_company_income_share","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"property_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"reports_rent_from_other_property","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"maintenance_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"spousal_maintenance_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"miscellaneous_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"private_transfer_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"lump_sum_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"student_loan_repayments","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"statutory_sick_pay","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"statutory_maternity_pay","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"statutory_paternity_pay","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"student_loans","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"access_fund","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"education_grants","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"healthy_start_vouchers","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"free_school_breakfasts","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"free_school_fruit_veg","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"free_school_meals","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"council_tax_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"maintenance_expenses","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"childcare_expenses","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"personal_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"employee_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"pension_contributions_via_salary_sacrifice","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"salary_sacrifice_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"salary_sacrifice_asked","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"frs_bonus_amount","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"child_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"income_support_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"housing_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"attendance_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"dla_sc_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"dla_m_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"iidb_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"carers_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"would_claim_carers_allowance","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"sda_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"afcs_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"ssmg_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"pension_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"child_tax_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"working_tax_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"state_pension_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"winter_fuel_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"incapacity_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"universal_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"pip_m_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"pip_dl_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"jsa_contrib_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"jsa_income_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"esa_contrib_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"esa_income_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"esa_includes_support_component","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"bsp_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"war_widows_pension_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"widowed_parents_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"frs_benunit_capital","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"is_married","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"dependent_children","dtype":"int64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"liable_for_share_of_household_rent","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"region","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"tenure_type","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"accommodation_type","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"num_bedrooms","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"council_tax_reported","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"council_tax_band","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"council_tax_rebate","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"council_tax_single_adult_raw","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"water_and_sewerage_charges","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"domestic_rates","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"rent","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"subrent","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"mortgage_interest_repayment","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"mortgage_capital_repayment","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"structural_insurance_payments","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"housing_service_charges","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"external_child_payments","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"sample_fraction":1.0,"sample_seed":578,"stage_contract_sha256":"937edbec02c73aa144424f03d1e828293477cbe3dae2a4d72f6c6d7739ab9d1c","time_period":"2024"},"population":null,"sources":["frs"],"structural":"create","weights":null},{"base":"create_uk_frs","citation":"","description":"Ownership boundary for the source-assembling root stage.","id":"frs_spine.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"base":null,"citation":"","description":"Claim the cells assembled by the UK FRS root transform.","id":"frs_spine","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"age","dtype":"int64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"gender","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"months_since_last_birthday","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"marital_status","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"hours_worked","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"care_hours","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_household_head","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_benunit_head","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_parent","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_blind","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_uc_claimant","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_claimant_or_partner","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_hbai_dependent_child","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"uc_is_in_startup_period","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"uc_is_in_gainful_self_employment","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"rent_paid_as_boarder","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"rent_paid_as_lodger","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"employment_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"self_employment_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"trading_loss","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"loss_relief","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"ni_class_4_losses_brought_forward","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"private_pension_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"tax_free_savings_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"savings_interest_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dividend_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"stands_as_sole_owner_or_partner_of_company","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_engaged_in_owned_company_trade","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_company_is_main_employment","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_company_carries_on_trade","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_company_carries_on_property_business","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_company_income_share","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"property_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"reports_rent_from_other_property","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"maintenance_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"spousal_maintenance_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"miscellaneous_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"private_transfer_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"lump_sum_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"student_loan_repayments","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"statutory_sick_pay","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"statutory_maternity_pay","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"statutory_paternity_pay","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"student_loans","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"access_fund","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"education_grants","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"healthy_start_vouchers","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"free_school_breakfasts","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"free_school_fruit_veg","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"free_school_meals","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"maintenance_expenses","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"childcare_expenses","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"personal_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"employee_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pension_contributions_via_salary_sacrifice","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"salary_sacrifice_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"salary_sacrifice_asked","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"frs_bonus_amount","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"child_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"income_support_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"housing_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"attendance_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dla_sc_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dla_m_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"iidb_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"carers_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"would_claim_carers_allowance","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"sda_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"afcs_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"ssmg_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pension_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"child_tax_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"working_tax_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"state_pension_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"winter_fuel_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"incapacity_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"universal_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pip_m_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pip_dl_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"jsa_contrib_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"jsa_income_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"esa_contrib_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"esa_income_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"esa_includes_support_component","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"bsp_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"war_widows_pension_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"widowed_parents_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"frs_benunit_capital","dtype":"float64","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_married","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dependent_children","dtype":"int64","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"liable_for_share_of_household_rent","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"region","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"tenure_type","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"accommodation_type","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"num_bedrooms","dtype":"int64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_reported","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_band","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_rebate","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_single_adult_raw","dtype":"int64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"water_and_sewerage_charges","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"domestic_rates","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"rent","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"subrent","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"mortgage_interest_repayment","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"mortgage_capital_repayment","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"structural_insurance_payments","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"housing_service_charges","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"external_child_payments","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"}],"params":{},"population":"frs_spine.boundary","sources":[],"structural":"none","weights":null},{"base":"frs_spine.boundary","citation":"","description":"Ownership boundary before age_tail rewrites.","id":"age_tail.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage age_tail.","id":"age_tail","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["external_child_payments","region"],"entity":"household","rows":"all"},{"columns":["gender"],"entity":"person","rows":"all"}],"kernel":"uk.stage.age_tail@1","mass":"conserve","outputs":[{"column":"age","dtype":"int64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"age_tail","stage_contract_sha256":"963a34f38caede2525e3b8735f904bb70a1bbef5a272f0eefd4346343444484f","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_relationships.","id":"frs_relationships","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","is_household_head"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_relationships@1","mass":"conserve","outputs":[{"column":"relationship_to_head","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"ons_family_role","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"ons_family_index","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"is_looked_after_by_local_authority","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"ons_household_type","dtype":"string","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_relationships","stage_contract_sha256":"85aca92dcc0590c2147cfc7e0886664f26cd8e1bc0b1de728d11fa567e9fd8b4","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_employment.","id":"frs_employment","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["ons_household_type","region"],"entity":"household","rows":"all"},{"columns":["age"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_employment@1","mass":"conserve","outputs":[{"column":"employment_status","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"employment_sector","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"sic_industry_division","dtype":"int64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_employment","stage_contract_sha256":"ddbefaf05b44788d794a6e4b0e8926c14318d66e50d2f11f50ca549538bbf60c","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_council_tax.","id":"frs_council_tax","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","sic_industry_division"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_council_tax@1","mass":"conserve","outputs":[{"column":"council_tax","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_council_tax","stage_contract_sha256":"06804f54c12d25f2afcb31eec27789802f663cb42689a932dc32f3ba5fc05fff","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_disability.","id":"frs_disability","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["council_tax","region"],"entity":"household","rows":"all"},{"columns":["afcs_reported","age","attendance_allowance_reported","dla_m_reported","dla_sc_reported","esa_contrib_reported","esa_income_reported","iidb_reported","incapacity_benefit_reported","pip_dl_reported","pip_m_reported","sda_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_disability@1","mass":"conserve","outputs":[{"column":"aa_category","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"dla_sc_category","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"dla_m_category","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"pip_m_category","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"pip_dl_category","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"is_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_enhanced_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_severely_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_disability","stage_contract_sha256":"ac500b4cb1bc04d4fb72d198592dd376d61da8c150921a6ac53914ac18be0508","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_education.","id":"frs_education","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","esa_contrib_reported","esa_income_reported","is_severely_disabled_for_benefits","jsa_contrib_reported","jsa_income_reported","universal_credit_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_education@1","mass":"conserve","outputs":[{"column":"current_education","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"highest_education","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"is_in_non_advanced_education","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_in_approved_training","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"age_started_or_accepted_current_education_or_training","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"is_before_universal_credit_qualifying_young_person_terminal_date","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"adult_ema","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"child_ema","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"receives_benefits_in_own_right","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"reports_outstanding_student_loan","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"age_left_full_time_education","dtype":"int64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_education","stage_contract_sha256":"592ddc77703f19bb3e1d48b6aecffc98b4e2abd3379db84a06e011bde4fa5549","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_legacy_proxies.","id":"frs_legacy_proxies","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_legacy_proxies@1","mass":"conserve","outputs":[{"column":"legacy_jobseeker_proxy","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"esa_health_condition_proxy","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"esa_support_group_proxy","dtype":"bool","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_legacy_proxies","stage_contract_sha256":"1ecf761cf3fa7180da15659e138e67a8654e58272b4fde28344aa27a874ad0aa","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"age_tail.boundary","citation":"","description":"Ownership boundary before frs_education_grant_split rewrites.","id":"frs_education_grant_split.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_education_grant_split.","id":"frs_education_grant_split","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_education_grant_split@1","mass":"conserve","outputs":[{"column":"disabled_students_allowance_eligible_expenses","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"education_grants","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_education_grant_split","stage_contract_sha256":"8718f014b90498c2cc7c754289775ca4a41452d9b978d8cbc5f34b64cbdc7df2","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_take_up.","id":"frs_take_up","inputs":[{"columns":["frs_benunit_capital","is_married"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","child_benefit_reported","education_grants","is_uc_claimant","months_since_last_birthday","pension_credit_reported","universal_credit_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_take_up@1","mass":"conserve","outputs":[{"column":"would_claim_child_benefit","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"child_benefit_opts_out","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"would_claim_pc","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"would_claim_uc","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"would_claim_tfc","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"would_claim_extended_childcare","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"would_claim_universal_childcare","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"would_claim_targeted_childcare","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"would_claim_uc_childcare","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"maximum_extended_childcare_hours_usage","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"max_free_entitlement_hours_used","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_take_up","stage_contract_sha256":"78aec80408c50455b37308e5a977fb70df3ecf915d6c1e8f80715ad9b58e62cf","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_person_draws.","id":"frs_person_draws","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","max_free_entitlement_hours_used"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_person_draws@1","mass":"conserve","outputs":[{"column":"would_claim_marriage_allowance","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"would_claim_scp","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"attends_private_school_random_draw","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"tax_free_childcare_spend_routed_share","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_person_draws","stage_contract_sha256":"c94c2ddd548017a6e7f43e1da51d727601b3f323e20fe4ee6ed120fa0f0f6e41","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_household_draws.","id":"frs_household_draws","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","tax_free_childcare_spend_routed_share"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_household_draws@1","mass":"conserve","outputs":[{"column":"household_owns_tv","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"would_evade_tv_licence_fee","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"main_residential_property_purchased_is_first_home","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"property_purchased","dtype":"bool","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_household_draws","stage_contract_sha256":"c74c63b09264319c4bf0049dabba00ecd0ce660beb7b53d6dae71518434bc949","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_brma.","id":"frs_brma","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_brma@1","mass":"conserve","outputs":[{"column":"brma","dtype":"string","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_brma","stage_contract_sha256":"4285376b37299d375ed583b7f6b1747bd8b7cb1c8c0d19a36481156b5314a854","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"frs_education_grant_split.boundary","citation":"","description":"Freeze the assembled-spine gate population.","id":"frs_brma.checkpoint","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_hmrc_spine_leaves.","id":"frs_hmrc_spine_leaves","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["brma","region"],"entity":"household","rows":"all"},{"columns":["age","employment_income"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_hmrc_spine_leaves@1","mass":"conserve","outputs":[{"column":"hmrc_spi_pay","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_unemployment_benefit_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_incapacity_benefit_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"ossben_identifiable_subset","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"srp_regular_code5","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"employer_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_hmrc_spine_leaves","stage_contract_sha256":"5fc311107a78562d5ceea294f16e85ffb5f43426fba0de2133a1cd92bf208eb9","time_period":"2024"},"population":"frs_brma.checkpoint","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_annual_income_spells.","id":"frs_annual_income_spells","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","employer_pension_contributions","employment_income","gender","self_employment_income"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_annual_income_spells@1","mass":"conserve","outputs":[{"column":"employment_income_annual_share","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"employment_income_other_spells","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"self_employment_income_annual_share","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"self_employment_income_other_spells","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"private_pension_income_annual_share","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"contributory_benefits_annual_share","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_annual_income_spells","stage_contract_sha256":"75e1f6877fbb99748dd66cf9aad266a204df66df04a5f88c854dabae6ddf3ab1","time_period":"2024"},"population":"frs_brma.checkpoint","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"frs_brma.checkpoint","citation":"","description":"Run structural UK stage spi_support_channel.","id":"spi_support_channel","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.spi_support_channel@1","mass":"declared","outputs":[],"params":{"expand_cells":[["person","person_source_id","int64"],["person","person_support_channel","string"],["person","person_support_clone_index","int64"],["benunit","benunit_source_id","int64"],["benunit","benunit_support_channel","string"],["benunit","benunit_support_clone_index","int64"],["household","source_household_id","int64"],["household","source_year","int64"],["household","source_household_key","string"],["household","household_source_id","int64"],["household","household_support_channel","string"],["household","household_support_clone_index","int64"],["household","household_is_spi_synthetic","bool"]],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"spi_support_channel","stage_contract_sha256":"2c682605139c0a8f96e8ba45a2c03f506d3f758ef437841066a8fdb8b74269b6","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by spi_support_channel.","id":"spi_support_channel.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"person_source_id","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"person_support_channel","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"person_support_clone_index","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"benunit_source_id","dtype":"int64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"benunit_support_channel","dtype":"string","entity":"benunit","ownership":"produced","rows":"all"},{"column":"benunit_support_clone_index","dtype":"int64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"source_household_id","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"source_year","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"source_household_key","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"household_source_id","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"household_support_channel","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"household_support_clone_index","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"household_is_spi_synthetic","dtype":"bool","entity":"household","ownership":"produced","rows":"all"}],"params":{"materialized_expand_outputs":["person.person_source_id","person.person_support_channel","person.person_support_clone_index","benunit.benunit_source_id","benunit.benunit_support_channel","benunit.benunit_support_clone_index","household.source_household_id","household.source_year","household.source_household_key","household.household_source_id","household.household_support_channel","household.household_support_clone_index","household.household_is_spi_synthetic"]},"population":"spi_support_channel","sources":[],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"spi_support_channel","citation":"","description":"Run structural UK stage spi_income_band_donors.","id":"spi_income_band_donors","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.spi_income_band_donors@1","mass":"declared","outputs":[],"params":{"expand_cells":[["person","person_source_id","int64"],["person","person_support_channel","string"],["person","person_support_clone_index","int64"],["benunit","benunit_source_id","int64"],["benunit","benunit_support_channel","string"],["benunit","benunit_support_clone_index","int64"],["household","household_source_id","int64"],["household","household_support_channel","string"],["household","household_support_clone_index","int64"],["household","household_is_spi_synthetic","bool"],["household","household_is_spi_income_band_donor","bool"],["household","spi_income_band_donor_lower_bound","float64"],["person","person_is_spi_income_band_carrier","bool"]],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"spi_income_band_donors","stage_contract_sha256":"ceb6b7f8ca1f46aa44198ff6ddc759f7f669a9c45d702ccd21a3b44b02759d3c","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by spi_income_band_donors.","id":"spi_income_band_donors.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"person_source_id","dtype":"int64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"person_support_channel","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"person_support_clone_index","dtype":"int64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"benunit_source_id","dtype":"int64","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"benunit_support_channel","dtype":"string","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"benunit_support_clone_index","dtype":"int64","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"household_source_id","dtype":"int64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"household_support_channel","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"household_support_clone_index","dtype":"int64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"household_is_spi_synthetic","dtype":"bool","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"household_is_spi_income_band_donor","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"spi_income_band_donor_lower_bound","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"person_is_spi_income_band_carrier","dtype":"bool","entity":"person","ownership":"produced","rows":"all"}],"params":{"materialized_expand_outputs":["household.household_is_spi_income_band_donor","household.spi_income_band_donor_lower_bound","person.person_is_spi_income_band_carrier"]},"population":"spi_income_band_donors","sources":[],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage hmrc_spi_income_spine.","id":"hmrc_spi_income_spine","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","rent_paid_as_boarder","rent_paid_as_lodger","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","maintenance_expenses","childcare_expenses","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","ssmg_reported","incapacity_benefit_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","ossben_identifiable_subset","srp_regular_code5","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier"],"entity":"person","rows":"all"}],"kernel":"uk.stage.hmrc_spi_income_spine@1","mass":"conserve","outputs":[{"column":"charitable_investment_gifts","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"gift_aid","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"other_investment_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_employment_benefits","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_employment_expenses","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_other_social_security_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_taxable_termination_pay","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_miscellaneous_employment_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_other_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_state_pension_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"property_finance_costs","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_employed_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_total_earned_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_total_investment_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_assessable_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"employment_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"self_employment_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"savings_interest_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dividend_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"private_pension_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"property_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"employee_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"employer_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"personal_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pension_contributions_via_salary_sacrifice","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"tax_free_savings_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"universal_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pension_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"child_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"housing_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"income_support_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"working_tax_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"child_tax_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"attendance_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"state_pension_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dla_sc_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dla_m_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pip_m_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pip_dl_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"sda_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"carers_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"iidb_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"afcs_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"bsp_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"war_widows_pension_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"widowed_parents_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"winter_fuel_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"jsa_contrib_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"jsa_income_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"esa_contrib_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"esa_income_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"trading_loss","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"loss_relief","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"ni_class_4_losses_brought_forward","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_company_income_share","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"hmrc_spi_pay","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"hmrc_spi_unemployment_benefit_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"hmrc_spi_incapacity_benefit_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"employment_income_annual_share","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"employment_income_other_spells","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"self_employment_income_annual_share","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"self_employment_income_other_spells","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"private_pension_income_annual_share","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"contributory_benefits_annual_share","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"aa_category","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dla_sc_category","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dla_m_category","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pip_m_category","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pip_dl_category","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_enhanced_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_severely_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"would_claim_carers_allowance","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"uc_is_in_startup_period","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"uc_is_in_gainful_self_employment","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"esa_includes_support_component","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"reports_rent_from_other_property","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"stands_as_sole_owner_or_partner_of_company","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_engaged_in_owned_company_trade","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_company_is_main_employment","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_company_carries_on_trade","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_company_carries_on_property_business","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"person_is_spi_income_recipient","dtype":"bool","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"hmrc_spi_income_spine","stage_contract_sha256":"e29d18a70a59fb2f1398bcfb21308ec8446a1cdd7cdc44fa030feacf01ef960a","time_period":"2024"},"population":"spi_income_band_donors","sources":["frs"],"structural":"none","weights":null},{"base":"spi_income_band_donors","citation":"","description":"Ownership boundary before spi_housing_shell rewrites.","id":"spi_housing_shell.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage spi_housing_shell.","id":"spi_housing_shell","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["council_tax_single_adult_raw","household_support_channel","ons_household_type","region"],"entity":"household","rows":"all"},{"columns":["age","dividend_income","employment_income","is_household_head","other_investment_income","person_is_spi_income_recipient","private_pension_income","property_income","savings_interest_income","self_employment_income","state_pension_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.spi_housing_shell@1","mass":"conserve","outputs":[{"column":"tenure_type","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"accommodation_type","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_band","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"num_bedrooms","dtype":"int64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_reported","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"rent","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"mortgage_interest_repayment","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"mortgage_capital_repayment","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"structural_insurance_payments","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"housing_service_charges","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"water_and_sewerage_charges","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"domestic_rates","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"subrent","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_rebate","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"housing_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"spi_housing_shell","stage_contract_sha256":"524549b7dfbd0fceb505311eb0c3b923cfe3b11a8acd5ecfbfbcbb477e142eb1","time_period":"2024"},"population":"spi_housing_shell.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage was_wealth.","id":"was_wealth","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient"],"entity":"person","rows":"all"}],"kernel":"uk.stage.was_wealth@1","mass":"conserve","outputs":[{"column":"owned_land","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"property_wealth","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"corporate_wealth","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"private_pension_wealth","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"gross_financial_wealth","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"net_financial_wealth","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"main_residence_value","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"other_residential_property_value","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"non_residential_property_value","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"savings","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"num_vehicles","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"cash_isa","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"stocks_and_shares_isa","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"mortgage_debt","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"consumer_debt","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"student_loan_balance","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"directly_held_shares","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"unit_and_investment_trusts","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"other_residential_property_secured_debt","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"non_residential_property_secured_debt","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"was_wealth","stage_contract_sha256":"e648f94320deffd15d4e7c2f51e044e8b3572b24bb62d65f157edcb8f31753b5","time_period":"2024"},"population":"spi_housing_shell.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage was_lisa.","id":"was_lisa","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance"],"entity":"person","rows":"all"}],"kernel":"uk.stage.was_lisa@1","mass":"conserve","outputs":[{"column":"has_lifetime_isa","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"lifetime_isa_balance","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"household_lifetime_isa_balance","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"was_lisa","stage_contract_sha256":"46f12fdf9228f721d860ff7858b78b25406bb8737628acf63ac17d44d549f657","time_period":"2024"},"population":"spi_housing_shell.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"spi_housing_shell.boundary","citation":"","description":"Ownership boundary before regional_property_uprating rewrites.","id":"regional_property_uprating.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage regional_property_uprating.","id":"regional_property_uprating","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["household_lifetime_isa_balance","household_support_channel","region"],"entity":"household","rows":"all"},{"columns":["age"],"entity":"person","rows":"all"}],"kernel":"uk.stage.regional_property_uprating@1","mass":"conserve","outputs":[{"column":"main_residence_value","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"property_wealth","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_land","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"other_residential_property_value","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"non_residential_property_value","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"regional_property_uprating","stage_contract_sha256":"f45db95fde3f93731c0925b9bf8c12021921df2e4908770acdec1e3c97889277","time_period":"2024"},"population":"regional_property_uprating.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"regional_property_uprating.boundary","citation":"","description":"Run structural UK stage high_value_home_support.","id":"high_value_home_support","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.high_value_home_support@1","mass":"conserve","outputs":[],"params":{"expand_cells":[["household","household_is_high_value_support_copy","bool"],["household","high_value_support_copies","int64"],["household","high_value_support_copy_index","int64"]],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"high_value_home_support","stage_contract_sha256":"174f4b38228d98107bee1639d1a297a2748bb618e87c7bd0a6c869c6ab06f8fa","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by high_value_home_support.","id":"high_value_home_support.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"household_is_high_value_support_copy","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"high_value_support_copies","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"high_value_support_copy_index","dtype":"int64","entity":"household","ownership":"produced","rows":"all"}],"params":{"materialized_expand_outputs":["household.household_is_high_value_support_copy","household.high_value_support_copies","household.high_value_support_copy_index"]},"population":"high_value_home_support","sources":[],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage regional_home_values.","id":"regional_home_values","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["high_value_support_copy_index","household_is_high_value_support_copy","household_source_id","region","tenure_type"],"entity":"household","rows":"all"},{"columns":["age"],"entity":"person","rows":"all"}],"kernel":"uk.stage.regional_home_values@1","mass":"conserve","outputs":[{"column":"main_residence_value","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"property_wealth","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"main_residence_value_rank_basis","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"regional_home_values","stage_contract_sha256":"48e8a622c8830a54a4c48d9d8cb4f011751aa05d7cb5f6c7f0e06e1121b720b1","time_period":"2024"},"population":"high_value_home_support","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage property_components.","id":"property_components","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["main_residence_value_rank_basis","non_residential_property_value","other_residential_property_value","region","subrent"],"entity":"household","rows":"all"},{"columns":["age","is_household_head","person_is_spi_income_recipient","person_support_channel"],"entity":"person","rows":"all"}],"kernel":"uk.stage.property_components@1","mass":"conserve","outputs":[{"column":"property_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"property_finance_costs","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"property_rental_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"property_components","stage_contract_sha256":"5c84a402f34dc5bfcfc0b3c3c7a5e57576cfd21e7bfdeba3e80dcaf4e9d478ba","time_period":"2024"},"population":"high_value_home_support","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage property_purchases.","id":"property_purchases","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["household_source_id","non_residential_property_value","other_residential_property_value","region"],"entity":"household","rows":"all"},{"columns":["age","property_rental_income"],"entity":"person","rows":"all"}],"kernel":"uk.stage.property_purchases@1","mass":"conserve","outputs":[{"column":"additional_residential_property_purchased","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"non_residential_property_purchased","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"property_purchases","stage_contract_sha256":"078a79ce6f8c768c06526f1c05288602ce781e30c77b575b0bdf3f5b7d16da1b","time_period":"2024"},"population":"high_value_home_support","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage nts_bus_travel.","id":"nts_bus_travel","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income"],"entity":"person","rows":"all"}],"kernel":"uk.stage.nts_bus_travel@1","mass":"conserve","outputs":[{"column":"local_bus_use_band","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"bus_in_london_trips","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"other_local_bus_trips","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"local_bus_trips","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"bus_pass_eligible","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"local_bus_single_fare_share","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"household_local_bus_trips","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"nts_bus_travel","stage_contract_sha256":"87177e34a811bb488ca952f98825f823baeb9fd723cef41f8ee4acfab0ffb107","time_period":"2024"},"population":"high_value_home_support","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage lcfs_consumption.","id":"lcfs_consumption","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share"],"entity":"person","rows":"all"}],"kernel":"uk.stage.lcfs_consumption@1","mass":"conserve","outputs":[{"column":"food_and_non_alcoholic_beverages_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"alcohol_and_tobacco_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"clothing_and_footwear_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"housing_water_and_electricity_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"household_furnishings_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"health_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"transport_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"communication_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"recreation_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"education_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"restaurants_and_hotels_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"miscellaneous_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"petrol_spending","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"diesel_spending","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"bus_fare_spending","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"domestic_energy_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"electricity_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"gas_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"liquid_fuel_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"solid_fuel_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"has_fuel_consumption","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"uses_energy_prepayment_meter","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"beer_litres","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"cider_litres","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"wine_litres","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"spirits_litres","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"other_fermented_litres","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"beer_draught_share","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"cider_draught_share","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"cigarettes_per_week","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"hand_rolling_tobacco_grams_per_week","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"cigars_grams_per_week","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"other_tobacco_grams_per_week","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"remote_gaming_net_losses","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"pool_betting_net_receipts","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"bingo_net_receipts","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"national_lottery_ticket_spending","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"land_based_casino_net_losses","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"machine_games_lower_rate_net_takings","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"machine_games_standard_rate_net_takings","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"machine_games_higher_rate_net_takings","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"land_based_fixed_odds_betting_net_losses","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"remote_uk_horseracing_betting_net_losses","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"remote_other_betting_net_losses","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"betting_exchange_commission","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"horse_and_dog_pool_betting_net_losses","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"lcfs_consumption","stage_contract_sha256":"91a3358c59b5383b91156f66b0443c910e672e17f73ea19aff1ecd91ca42c029","time_period":"2024"},"population":"high_value_home_support","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage etb_vat.","id":"etb_vat","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share"],"entity":"person","rows":"all"}],"kernel":"uk.stage.etb_vat@1","mass":"conserve","outputs":[{"column":"full_rate_vat_expenditure_rate","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"etb_vat","stage_contract_sha256":"216b28835eba7a952243134dffbb45a1b3a0cdff2e3e7d0e94e2acbf754052b5","time_period":"2024"},"population":"high_value_home_support","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage etb_services.","id":"etb_services","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share"],"entity":"person","rows":"all"}],"kernel":"uk.stage.etb_services@1","mass":"conserve","outputs":[{"column":"dfe_education_spending","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"rail_subsidy_spending","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"bus_subsidy_spending","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"rail_usage","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"a_and_e_visits","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"admitted_patient_visits","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"outpatient_visits","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"nhs_a_and_e_spending","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"nhs_admitted_patient_spending","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"nhs_outpatient_spending","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"etb_services","stage_contract_sha256":"211e488552e57cda3138f98a6acb9d56e24db372b2a1d717fba63f9b80ff92ab","time_period":"2024"},"population":"high_value_home_support","sources":["frs"],"structural":"none","weights":null},{"base":"high_value_home_support","citation":"","description":"Ownership boundary before uc_reporter_redraw rewrites.","id":"uc_reporter_redraw.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage uc_reporter_redraw.","id":"uc_reporter_redraw","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.uc_reporter_redraw@1","mass":"conserve","outputs":[{"column":"universal_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"uc_reporter_redraw","stage_contract_sha256":"b03d4947d6cb0404ba410c548e1850d5abe0c7dae2dc097d419b63eea04920a9","time_period":"2024"},"population":"uc_reporter_redraw.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"uc_reporter_redraw.boundary","citation":"","description":"Ownership boundary before spi_benefit_coherence rewrites.","id":"spi_benefit_coherence.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage spi_benefit_coherence.","id":"spi_benefit_coherence","inputs":[{"columns":["benunit_support_channel","frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["aa_category","age","attendance_allowance_reported","dla_m_category","dla_m_reported","dla_sc_category","dla_sc_reported","esa_contrib_reported","incapacity_benefit_reported","is_uc_claimant","person_source_id","person_support_channel","pip_dl_category","pip_dl_reported","pip_m_category","pip_m_reported","universal_credit_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.spi_benefit_coherence@1","mass":"conserve","outputs":[{"column":"jsa_contrib_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"jsa_income_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"esa_income_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"income_support_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"working_tax_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"child_tax_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"sda_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"ssmg_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"iidb_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"afcs_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"bsp_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"war_widows_pension_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"widowed_parents_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_enhanced_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_severely_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"receives_benefits_in_own_right","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"would_claim_uc","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"spi_benefit_coherence","stage_contract_sha256":"ad3bfd51b377963c1d976a82416283aeb7b80d9f89b44c0e5db79e3598e815d5","time_period":"2024"},"population":"spi_benefit_coherence.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"spi_benefit_coherence.boundary","citation":"","description":"Ownership boundary before uc_capital_coherence rewrites.","id":"uc_capital_coherence.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage uc_capital_coherence.","id":"uc_capital_coherence","inputs":[{"columns":["benunit_support_channel","dependent_children","is_married"],"entity":"benunit","rows":"all"},{"columns":["non_residential_property_secured_debt","non_residential_property_value","other_residential_property_secured_debt","other_residential_property_value","owned_land","region"],"entity":"household","rows":"all"},{"columns":["age","dividend_income","is_benunit_head","is_household_head","is_parent","other_investment_income","person_support_channel","savings_interest_income","universal_credit_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.uc_capital_coherence@1","mass":"conserve","outputs":[{"column":"uc_reported_capital","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"pension_credit_reported_capital","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"frs_benunit_capital","dtype":"float64","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"would_claim_uc","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"uc_capital_coherence","stage_contract_sha256":"e7c7311b3852e67ae755c09456cc10c46136681fa92ade60daa1fbeb581288d5","time_period":"2024"},"population":"uc_capital_coherence.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"uc_capital_coherence.boundary","citation":"","description":"Ownership boundary before uc_take_up rewrites.","id":"uc_take_up.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage uc_take_up.","id":"uc_take_up","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.uc_take_up@1","mass":"conserve","outputs":[{"column":"would_claim_uc","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"uc_take_up","stage_contract_sha256":"9818609b1003442f197e99ca741dc8db658a82f36c67f35308ceef25537b739e","time_period":"2024"},"population":"uc_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage uc_legacy_closure_take_up.","id":"uc_legacy_closure_take_up","inputs":[{"columns":["frs_benunit_capital","would_claim_uc"],"entity":"benunit","rows":"all"},{"columns":["household_source_id","region"],"entity":"household","rows":"all"},{"columns":["age","child_tax_credit_reported","esa_income_reported","housing_benefit_reported","income_support_reported","is_claimant_or_partner","jsa_income_reported","universal_credit_reported","working_tax_credit_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.uc_legacy_closure_take_up@1","mass":"conserve","outputs":[{"column":"would_claim_uc_at_legacy_closure","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"uc_legacy_closure_take_up","stage_contract_sha256":"0bf6d4151d9cbd32bde34c2538bf6142d458c8828cc698fa1a9aad0d9e432246","time_period":"2024"},"population":"uc_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"uc_take_up.boundary","citation":"","description":"Ownership boundary before pension_credit_take_up rewrites.","id":"pension_credit_take_up.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital","would_claim_uc_at_legacy_closure"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage pension_credit_take_up.","id":"pension_credit_take_up","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital","would_claim_uc_at_legacy_closure"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.pension_credit_take_up@1","mass":"conserve","outputs":[{"column":"would_claim_pc","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"has_mixed_age_couple_pension_credit_saving","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"pension_credit_take_up","stage_contract_sha256":"e887dbbb186cb79f6d3fc9a629269dbac4a43381b9574df65353b816f01a3a35","time_period":"2024"},"population":"pension_credit_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"pension_credit_take_up.boundary","citation":"","description":"Ownership boundary before child_benefit_take_up rewrites.","id":"child_benefit_take_up.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage child_benefit_take_up.","id":"child_benefit_take_up","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.child_benefit_take_up@1","mass":"conserve","outputs":[{"column":"would_claim_child_benefit","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"child_benefit_opts_out","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"child_benefit_take_up","stage_contract_sha256":"78c889ae5a4bd4c61b1e0b259e3fe3e805f76e12c952d0523c92969957db05d5","time_period":"2024"},"population":"child_benefit_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"child_benefit_take_up.boundary","citation":"","description":"Ownership boundary before carers_allowance_take_up rewrites.","id":"carers_allowance_take_up.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage carers_allowance_take_up.","id":"carers_allowance_take_up","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.carers_allowance_take_up@1","mass":"conserve","outputs":[{"column":"would_claim_carers_allowance","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"carers_allowance_take_up","stage_contract_sha256":"c4c1ddf4b7da2c3082e09d6e77a9b4a0dc617743ff2c3c1f546f930bcac0635f","time_period":"2024"},"population":"carers_allowance_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage uc_deduction_attributes.","id":"uc_deduction_attributes","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","would_claim_carers_allowance"],"entity":"person","rows":"all"}],"kernel":"uk.stage.uc_deduction_attributes@1","mass":"conserve","outputs":[{"column":"uc_deduction_random_draw","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"uc_deduction_type_random_draw","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"uc_latent_deduction_rate","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"uc_deduction_combination","dtype":"string","entity":"benunit","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"uc_deduction_attributes","stage_contract_sha256":"6bc7e3ec1a5712e23ca1b7d2956e8b17f2526b94431ba3e5a9294b04658e4fe0","time_period":"2024"},"population":"carers_allowance_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"carers_allowance_take_up.boundary","citation":"","description":"Run structural UK stage cgt_support_split.","id":"cgt_support_split","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.cgt_support_split@1","mass":"conserve","outputs":[],"params":{"expand_cells":[["household","household_is_cgt_support_copy","bool"],["household","cgt_support_copies","int64"],["household","cgt_support_copy_index","int64"]],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"cgt_support_split","stage_contract_sha256":"d91faf93fc9fc0251b2165af1c79514dc5d942373bc8f13d8d7d5454e0fd931c","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by cgt_support_split.","id":"cgt_support_split.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"household_is_cgt_support_copy","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"cgt_support_copies","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"cgt_support_copy_index","dtype":"int64","entity":"household","ownership":"produced","rows":"all"}],"params":{"materialized_expand_outputs":["household.household_is_cgt_support_copy","household.cgt_support_copies","household.cgt_support_copy_index"]},"population":"cgt_support_split","sources":[],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"cgt_support_split","citation":"","description":"Run structural UK stage cgt_incidence_clone.","id":"cgt_incidence_clone","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.cgt_incidence_clone@1","mass":"conserve","outputs":[],"params":{"expand_cells":[["household","household_is_capital_gains_clone","bool"],["person","capital_gains","float64"]],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"cgt_incidence_clone","stage_contract_sha256":"ee30278543cc0297a5366d855b7753aa04af5518971594c193c52be36bf8a7b4","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by cgt_incidence_clone.","id":"cgt_incidence_clone.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"household_is_capital_gains_clone","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"capital_gains","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"materialized_expand_outputs":["household.household_is_capital_gains_clone","person.capital_gains"]},"population":"cgt_incidence_clone","sources":[],"structural":"none","weights":null},{"base":"cgt_incidence_clone","citation":"","description":"Ownership boundary before hmrc_cgt_gains_spine rewrites.","id":"hmrc_cgt_gains_spine.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage hmrc_cgt_gains_spine.","id":"hmrc_cgt_gains_spine","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["cgt_support_copies","corporate_wealth","gross_financial_wealth","household_is_cgt_support_copy","non_residential_property_value","other_residential_property_value","region"],"entity":"household","rows":"all"},{"columns":["age","dividend_income","employment_income","miscellaneous_income","private_pension_income","property_income","savings_interest_income","self_employment_income","state_pension_reported","tax_free_savings_income"],"entity":"person","rows":"all"}],"kernel":"uk.stage.hmrc_cgt_gains_spine@1","mass":"conserve","outputs":[{"column":"capital_gains","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"hmrc_cgt_gains_spine","stage_contract_sha256":"8400624c4efaf1ab36add705318f660bafff7b73b9770080b6950e50de231bb7","time_period":"2024"},"population":"hmrc_cgt_gains_spine.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"hmrc_cgt_gains_spine.boundary","citation":"","description":"Run structural UK stage cgt_incidence_anchor.","id":"cgt_incidence_anchor","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["household_is_capital_gains_clone","region"],"entity":"household","rows":"all"},{"columns":["age","capital_gains","dividend_income","employment_income","miscellaneous_income","private_pension_income","property_income","savings_interest_income","self_employment_income","state_pension_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.cgt_incidence_anchor@1","mass":"conserve","outputs":[],"params":{"expand_cells":[],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"cgt_incidence_anchor","stage_contract_sha256":"b79ce806015de2f1e1703fa68bf4ad871c6df54b5b32633c864632ab68919a48","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"cgt_incidence_anchor","citation":"","description":"Run structural UK stage cgt_residential_split.","id":"cgt_residential_split","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.cgt_residential_split@1","mass":"conserve","outputs":[],"params":{"expand_cells":[["household","household_is_cgt_residential_clone","bool"],["household","cgt_residential_clone_index","int64"],["person","cgt_residential_probability","float64"],["person","capital_gains_residential_property","float64"]],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"cgt_residential_split","stage_contract_sha256":"e4ef9c4f94f3d5944a524e8e1e24b8ea983790c9f7ea491a75b6ae3893371a59","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by cgt_residential_split.","id":"cgt_residential_split.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"household_is_cgt_residential_clone","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"cgt_residential_clone_index","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"cgt_residential_probability","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"capital_gains_residential_property","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"materialized_expand_outputs":["household.household_is_cgt_residential_clone","household.cgt_residential_clone_index","person.cgt_residential_probability","person.capital_gains_residential_property"]},"population":"cgt_residential_split","sources":[],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage hmrc_cgt_asset_type_spine.","id":"hmrc_cgt_asset_type_spine","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["corporate_wealth","gross_financial_wealth","other_residential_property_value","region","stocks_and_shares_isa"],"entity":"household","rows":"all"},{"columns":["age","capital_gains","capital_gains_residential_property","dividend_income","property_income","reports_rent_from_other_property","self_employment_income"],"entity":"person","rows":"all"}],"kernel":"uk.stage.hmrc_cgt_asset_type_spine@1","mass":"conserve","outputs":[{"column":"capital_gains_asset_type","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"capital_gains_badr","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"hmrc_cgt_asset_type_spine","stage_contract_sha256":"52148b13d8ce5e4292991a7840d441c6b49d67a609d99497854c2a45a21adb98","time_period":"2024"},"population":"cgt_residential_split","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage salary_sacrifice.","id":"salary_sacrifice","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone","household_is_cgt_residential_clone","cgt_residential_clone_index"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains","cgt_residential_probability","capital_gains_residential_property","capital_gains_asset_type","capital_gains_badr"],"entity":"person","rows":"all"}],"kernel":"uk.stage.salary_sacrifice@1","mass":"conserve","outputs":[{"column":"pension_contributions_via_salary_sacrifice","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pension_contributions_via_bonus_sacrifice","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"employee_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"employment_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"salary_sacrifice_pre_conversion_pay","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"salary_sacrifice","stage_contract_sha256":"76c0120b5d27115d732faac38f9fe3c1a474be944a06bbecd0380a209b0a7331","time_period":"2024"},"population":"cgt_residential_split","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage student_loans.","id":"student_loans","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","age_left_full_time_education","current_education","highest_education","reports_outstanding_student_loan","salary_sacrifice_pre_conversion_pay","student_loan_repayments","student_loans"],"entity":"person","rows":"all"}],"kernel":"uk.stage.student_loans@1","mass":"conserve","outputs":[{"column":"student_loan_plan","dtype":"string","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"student_loans","stage_contract_sha256":"157d9ee607633e4246ed06eeee3aac3cdff98118e72400e18b84c11b3fd2b92b","time_period":"2024"},"population":"cgt_residential_split","sources":["frs"],"structural":"none","weights":null},{"base":"cgt_residential_split","citation":"","description":"Ownership boundary before childcare_copy_take_up rewrites.","id":"childcare_copy_take_up.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone","household_is_cgt_residential_clone","cgt_residential_clone_index"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains","cgt_residential_probability","capital_gains_residential_property","capital_gains_asset_type","capital_gains_badr","pension_contributions_via_bonus_sacrifice","salary_sacrifice_pre_conversion_pay","student_loan_plan"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage childcare_copy_take_up.","id":"childcare_copy_take_up","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_uc_childcare","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone","household_is_cgt_residential_clone","cgt_residential_clone_index"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains","cgt_residential_probability","capital_gains_residential_property","capital_gains_asset_type","capital_gains_badr","pension_contributions_via_bonus_sacrifice","salary_sacrifice_pre_conversion_pay","student_loan_plan"],"entity":"person","rows":"all"}],"kernel":"uk.stage.childcare_copy_take_up@1","mass":"conserve","outputs":[{"column":"would_claim_tfc","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"would_claim_extended_childcare","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"would_claim_universal_childcare","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"would_claim_targeted_childcare","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"maximum_extended_childcare_hours_usage","dtype":"float64","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"max_free_entitlement_hours_used","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"childcare_copy_take_up","stage_contract_sha256":"cdbb7e135b16fac7ca1bcd6c54222821e2976b4da99f10a60913efd0ba03c13c","time_period":"2024"},"population":"childcare_copy_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage private_school_attendance.","id":"private_school_attendance","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone","household_is_cgt_residential_clone","cgt_residential_clone_index"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains","cgt_residential_probability","capital_gains_residential_property","capital_gains_asset_type","capital_gains_badr","pension_contributions_via_bonus_sacrifice","salary_sacrifice_pre_conversion_pay","student_loan_plan"],"entity":"person","rows":"all"}],"kernel":"uk.stage.private_school_attendance@1","mass":"conserve","outputs":[{"column":"attends_private_school","dtype":"bool","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"private_school_attendance","stage_contract_sha256":"7e44379c0331fe4c9de05cd76a075c1a6aa22cf0dec6cd2f91b277e70f14a038","time_period":"2024"},"population":"childcare_copy_take_up.boundary","sources":["frs"],"structural":"none","weights":null}],"sources":[{"codec":"csv-tables","description":"Content-bound UK FRS and donor fixture/source bundle.","name":"frs"}]} +{"country":"uk","nodes":[{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Load the source-bound UK FRS root population.","id":"create_uk_frs","inputs":[],"kernel":"uk.create@1","mass":"conserve","outputs":[{"column":"age","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"gender","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"months_since_last_birthday","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"marital_status","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"hours_worked","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"care_hours","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"is_household_head","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_benunit_head","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_parent","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_blind","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_uc_claimant","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_claimant_or_partner","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_hbai_dependent_child","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"uc_is_in_startup_period","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"uc_is_in_gainful_self_employment","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"rent_paid_as_boarder","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"rent_paid_as_lodger","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"employment_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"self_employment_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"trading_loss","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"loss_relief","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"ni_class_4_losses_brought_forward","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"private_pension_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"tax_free_savings_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"savings_interest_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"dividend_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"stands_as_sole_owner_or_partner_of_company","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_engaged_in_owned_company_trade","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"owned_company_is_main_employment","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"owned_company_carries_on_trade","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"owned_company_carries_on_property_business","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"owned_company_income_share","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"property_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"reports_rent_from_other_property","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"maintenance_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"spousal_maintenance_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"miscellaneous_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"private_transfer_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"lump_sum_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"student_loan_repayments","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"statutory_sick_pay","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"statutory_maternity_pay","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"statutory_paternity_pay","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"student_loans","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"access_fund","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"education_grants","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"healthy_start_vouchers","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"free_school_breakfasts","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"free_school_fruit_veg","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"free_school_meals","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"council_tax_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"maintenance_expenses","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"childcare_expenses","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"personal_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"employee_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"pension_contributions_via_salary_sacrifice","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"salary_sacrifice_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"salary_sacrifice_asked","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"frs_bonus_amount","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"child_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"income_support_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"housing_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"attendance_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"dla_sc_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"dla_m_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"iidb_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"carers_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"would_claim_carers_allowance","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"sda_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"afcs_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"ssmg_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"pension_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"child_tax_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"working_tax_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"state_pension_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"winter_fuel_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"incapacity_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"universal_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"pip_m_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"pip_dl_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"jsa_contrib_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"jsa_income_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"esa_contrib_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"esa_income_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"esa_includes_support_component","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"bsp_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"war_widows_pension_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"widowed_parents_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"frs_benunit_capital","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"is_married","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"dependent_children","dtype":"int64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"liable_for_share_of_household_rent","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"region","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"tenure_type","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"accommodation_type","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"num_bedrooms","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"council_tax_reported","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"council_tax_band","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"council_tax_rebate","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"council_tax_single_adult_raw","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"water_and_sewerage_charges","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"domestic_rates","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"rent","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"subrent","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"mortgage_interest_repayment","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"mortgage_capital_repayment","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"structural_insurance_payments","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"housing_service_charges","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"external_child_payments","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"sample_fraction":1.0,"sample_seed":578,"stage_contract_sha256":"937edbec02c73aa144424f03d1e828293477cbe3dae2a4d72f6c6d7739ab9d1c","time_period":"2024"},"population":null,"sources":["frs"],"structural":"create","weights":null},{"base":"create_uk_frs","citation":"","description":"Ownership boundary for the source-assembling root stage.","id":"frs_spine.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"base":null,"citation":"","description":"Claim the cells assembled by the UK FRS root transform.","id":"frs_spine","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"age","dtype":"int64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"gender","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"months_since_last_birthday","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"marital_status","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"hours_worked","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"care_hours","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_household_head","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_benunit_head","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_parent","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_blind","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_uc_claimant","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_claimant_or_partner","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_hbai_dependent_child","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"uc_is_in_startup_period","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"uc_is_in_gainful_self_employment","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"rent_paid_as_boarder","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"rent_paid_as_lodger","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"employment_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"self_employment_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"trading_loss","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"loss_relief","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"ni_class_4_losses_brought_forward","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"private_pension_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"tax_free_savings_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"savings_interest_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dividend_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"stands_as_sole_owner_or_partner_of_company","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_engaged_in_owned_company_trade","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_company_is_main_employment","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_company_carries_on_trade","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_company_carries_on_property_business","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_company_income_share","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"property_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"reports_rent_from_other_property","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"maintenance_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"spousal_maintenance_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"miscellaneous_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"private_transfer_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"lump_sum_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"student_loan_repayments","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"statutory_sick_pay","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"statutory_maternity_pay","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"statutory_paternity_pay","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"student_loans","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"access_fund","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"education_grants","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"healthy_start_vouchers","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"free_school_breakfasts","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"free_school_fruit_veg","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"free_school_meals","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"maintenance_expenses","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"childcare_expenses","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"personal_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"employee_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pension_contributions_via_salary_sacrifice","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"salary_sacrifice_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"salary_sacrifice_asked","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"frs_bonus_amount","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"child_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"income_support_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"housing_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"attendance_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dla_sc_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dla_m_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"iidb_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"carers_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"would_claim_carers_allowance","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"sda_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"afcs_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"ssmg_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pension_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"child_tax_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"working_tax_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"state_pension_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"winter_fuel_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"incapacity_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"universal_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pip_m_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pip_dl_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"jsa_contrib_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"jsa_income_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"esa_contrib_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"esa_income_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"esa_includes_support_component","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"bsp_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"war_widows_pension_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"widowed_parents_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"frs_benunit_capital","dtype":"float64","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_married","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dependent_children","dtype":"int64","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"liable_for_share_of_household_rent","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"region","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"tenure_type","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"accommodation_type","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"num_bedrooms","dtype":"int64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_reported","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_band","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_rebate","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_single_adult_raw","dtype":"int64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"water_and_sewerage_charges","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"domestic_rates","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"rent","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"subrent","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"mortgage_interest_repayment","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"mortgage_capital_repayment","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"structural_insurance_payments","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"housing_service_charges","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"external_child_payments","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"}],"params":{},"population":"frs_spine.boundary","sources":[],"structural":"none","weights":null},{"base":"frs_spine.boundary","citation":"","description":"Ownership boundary before age_tail rewrites.","id":"age_tail.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage age_tail.","id":"age_tail","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["external_child_payments","region"],"entity":"household","rows":"all"},{"columns":["gender"],"entity":"person","rows":"all"}],"kernel":"uk.stage.age_tail@1","mass":"conserve","outputs":[{"column":"age","dtype":"int64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"age_tail","stage_contract_sha256":"963a34f38caede2525e3b8735f904bb70a1bbef5a272f0eefd4346343444484f","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_relationships.","id":"frs_relationships","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","is_household_head"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_relationships@1","mass":"conserve","outputs":[{"column":"relationship_to_head","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"ons_family_role","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"ons_family_index","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"is_looked_after_by_local_authority","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"ons_household_type","dtype":"string","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_relationships","stage_contract_sha256":"85aca92dcc0590c2147cfc7e0886664f26cd8e1bc0b1de728d11fa567e9fd8b4","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_employment.","id":"frs_employment","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["ons_household_type","region"],"entity":"household","rows":"all"},{"columns":["age"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_employment@1","mass":"conserve","outputs":[{"column":"employment_status","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"employment_sector","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"sic_industry_division","dtype":"int64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_employment","stage_contract_sha256":"ddbefaf05b44788d794a6e4b0e8926c14318d66e50d2f11f50ca549538bbf60c","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_council_tax.","id":"frs_council_tax","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","sic_industry_division"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_council_tax@1","mass":"conserve","outputs":[{"column":"council_tax","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_council_tax","stage_contract_sha256":"06804f54c12d25f2afcb31eec27789802f663cb42689a932dc32f3ba5fc05fff","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_disability.","id":"frs_disability","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["council_tax","region"],"entity":"household","rows":"all"},{"columns":["afcs_reported","age","attendance_allowance_reported","dla_m_reported","dla_sc_reported","esa_contrib_reported","esa_income_reported","iidb_reported","incapacity_benefit_reported","pip_dl_reported","pip_m_reported","sda_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_disability@1","mass":"conserve","outputs":[{"column":"aa_category","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"dla_sc_category","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"dla_m_category","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"pip_m_category","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"pip_dl_category","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"is_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_enhanced_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_severely_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_disability","stage_contract_sha256":"ac500b4cb1bc04d4fb72d198592dd376d61da8c150921a6ac53914ac18be0508","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_education.","id":"frs_education","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","esa_contrib_reported","esa_income_reported","is_severely_disabled_for_benefits","jsa_contrib_reported","jsa_income_reported","universal_credit_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_education@1","mass":"conserve","outputs":[{"column":"current_education","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"highest_education","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"is_in_non_advanced_education","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_in_approved_training","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"age_started_or_accepted_current_education_or_training","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"is_before_universal_credit_qualifying_young_person_terminal_date","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"adult_ema","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"child_ema","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"receives_benefits_in_own_right","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"reports_outstanding_student_loan","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"age_left_full_time_education","dtype":"int64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_education","stage_contract_sha256":"592ddc77703f19bb3e1d48b6aecffc98b4e2abd3379db84a06e011bde4fa5549","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_legacy_proxies.","id":"frs_legacy_proxies","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_legacy_proxies@1","mass":"conserve","outputs":[{"column":"legacy_jobseeker_proxy","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"esa_health_condition_proxy","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"esa_support_group_proxy","dtype":"bool","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_legacy_proxies","stage_contract_sha256":"1ecf761cf3fa7180da15659e138e67a8654e58272b4fde28344aa27a874ad0aa","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"age_tail.boundary","citation":"","description":"Ownership boundary before frs_education_grant_split rewrites.","id":"frs_education_grant_split.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_education_grant_split.","id":"frs_education_grant_split","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_education_grant_split@1","mass":"conserve","outputs":[{"column":"disabled_students_allowance_eligible_expenses","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"education_grants","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_education_grant_split","stage_contract_sha256":"8718f014b90498c2cc7c754289775ca4a41452d9b978d8cbc5f34b64cbdc7df2","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_take_up.","id":"frs_take_up","inputs":[{"columns":["frs_benunit_capital","is_married"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","child_benefit_reported","education_grants","is_uc_claimant","months_since_last_birthday","pension_credit_reported","universal_credit_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_take_up@1","mass":"conserve","outputs":[{"column":"would_claim_child_benefit","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"child_benefit_opts_out","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"would_claim_pc","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"would_claim_uc","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"would_claim_tfc","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"would_claim_extended_childcare","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"would_claim_universal_childcare","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"would_claim_targeted_childcare","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"would_claim_uc_childcare","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"maximum_extended_childcare_hours_usage","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"max_free_entitlement_hours_used","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_take_up","stage_contract_sha256":"78aec80408c50455b37308e5a977fb70df3ecf915d6c1e8f80715ad9b58e62cf","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_person_draws.","id":"frs_person_draws","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","max_free_entitlement_hours_used"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_person_draws@1","mass":"conserve","outputs":[{"column":"would_claim_marriage_allowance","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"would_claim_scp","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"attends_private_school_random_draw","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"tax_free_childcare_spend_routed_share","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_person_draws","stage_contract_sha256":"118d16966a648ed208e75c9ce3c3ac88e36d4ece669a3a6096e73b544ed29e18","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_household_draws.","id":"frs_household_draws","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","tax_free_childcare_spend_routed_share"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_household_draws@1","mass":"conserve","outputs":[{"column":"household_owns_tv","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"would_evade_tv_licence_fee","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"main_residential_property_purchased_is_first_home","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"property_purchased","dtype":"bool","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_household_draws","stage_contract_sha256":"c74c63b09264319c4bf0049dabba00ecd0ce660beb7b53d6dae71518434bc949","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_brma.","id":"frs_brma","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_brma@1","mass":"conserve","outputs":[{"column":"brma","dtype":"string","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_brma","stage_contract_sha256":"4285376b37299d375ed583b7f6b1747bd8b7cb1c8c0d19a36481156b5314a854","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"frs_education_grant_split.boundary","citation":"","description":"Freeze the assembled-spine gate population.","id":"frs_brma.checkpoint","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_hmrc_spine_leaves.","id":"frs_hmrc_spine_leaves","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["brma","region"],"entity":"household","rows":"all"},{"columns":["age","employment_income"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_hmrc_spine_leaves@1","mass":"conserve","outputs":[{"column":"hmrc_spi_pay","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_unemployment_benefit_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_incapacity_benefit_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"ossben_identifiable_subset","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"srp_regular_code5","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"employer_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_hmrc_spine_leaves","stage_contract_sha256":"5fc311107a78562d5ceea294f16e85ffb5f43426fba0de2133a1cd92bf208eb9","time_period":"2024"},"population":"frs_brma.checkpoint","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_annual_income_spells.","id":"frs_annual_income_spells","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","employer_pension_contributions","employment_income","gender","self_employment_income"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_annual_income_spells@1","mass":"conserve","outputs":[{"column":"employment_income_annual_share","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"employment_income_other_spells","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"self_employment_income_annual_share","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"self_employment_income_other_spells","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"private_pension_income_annual_share","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"contributory_benefits_annual_share","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_annual_income_spells","stage_contract_sha256":"75e1f6877fbb99748dd66cf9aad266a204df66df04a5f88c854dabae6ddf3ab1","time_period":"2024"},"population":"frs_brma.checkpoint","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"frs_brma.checkpoint","citation":"","description":"Run structural UK stage spi_support_channel.","id":"spi_support_channel","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.spi_support_channel@1","mass":"declared","outputs":[],"params":{"expand_cells":[["person","person_source_id","int64"],["person","person_support_channel","string"],["person","person_support_clone_index","int64"],["benunit","benunit_source_id","int64"],["benunit","benunit_support_channel","string"],["benunit","benunit_support_clone_index","int64"],["household","source_household_id","int64"],["household","source_year","int64"],["household","source_household_key","string"],["household","household_source_id","int64"],["household","household_support_channel","string"],["household","household_support_clone_index","int64"],["household","household_is_spi_synthetic","bool"]],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"spi_support_channel","stage_contract_sha256":"2c682605139c0a8f96e8ba45a2c03f506d3f758ef437841066a8fdb8b74269b6","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by spi_support_channel.","id":"spi_support_channel.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"person_source_id","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"person_support_channel","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"person_support_clone_index","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"benunit_source_id","dtype":"int64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"benunit_support_channel","dtype":"string","entity":"benunit","ownership":"produced","rows":"all"},{"column":"benunit_support_clone_index","dtype":"int64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"source_household_id","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"source_year","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"source_household_key","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"household_source_id","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"household_support_channel","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"household_support_clone_index","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"household_is_spi_synthetic","dtype":"bool","entity":"household","ownership":"produced","rows":"all"}],"params":{"materialized_expand_outputs":["person.person_source_id","person.person_support_channel","person.person_support_clone_index","benunit.benunit_source_id","benunit.benunit_support_channel","benunit.benunit_support_clone_index","household.source_household_id","household.source_year","household.source_household_key","household.household_source_id","household.household_support_channel","household.household_support_clone_index","household.household_is_spi_synthetic"]},"population":"spi_support_channel","sources":[],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"spi_support_channel","citation":"","description":"Run structural UK stage spi_income_band_donors.","id":"spi_income_band_donors","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.spi_income_band_donors@1","mass":"declared","outputs":[],"params":{"expand_cells":[["person","person_source_id","int64"],["person","person_support_channel","string"],["person","person_support_clone_index","int64"],["benunit","benunit_source_id","int64"],["benunit","benunit_support_channel","string"],["benunit","benunit_support_clone_index","int64"],["household","household_source_id","int64"],["household","household_support_channel","string"],["household","household_support_clone_index","int64"],["household","household_is_spi_synthetic","bool"],["household","household_is_spi_income_band_donor","bool"],["household","spi_income_band_donor_lower_bound","float64"],["person","person_is_spi_income_band_carrier","bool"]],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"spi_income_band_donors","stage_contract_sha256":"ceb6b7f8ca1f46aa44198ff6ddc759f7f669a9c45d702ccd21a3b44b02759d3c","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by spi_income_band_donors.","id":"spi_income_band_donors.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"person_source_id","dtype":"int64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"person_support_channel","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"person_support_clone_index","dtype":"int64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"benunit_source_id","dtype":"int64","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"benunit_support_channel","dtype":"string","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"benunit_support_clone_index","dtype":"int64","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"household_source_id","dtype":"int64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"household_support_channel","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"household_support_clone_index","dtype":"int64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"household_is_spi_synthetic","dtype":"bool","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"household_is_spi_income_band_donor","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"spi_income_band_donor_lower_bound","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"person_is_spi_income_band_carrier","dtype":"bool","entity":"person","ownership":"produced","rows":"all"}],"params":{"materialized_expand_outputs":["household.household_is_spi_income_band_donor","household.spi_income_band_donor_lower_bound","person.person_is_spi_income_band_carrier"]},"population":"spi_income_band_donors","sources":[],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage hmrc_spi_income_spine.","id":"hmrc_spi_income_spine","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","rent_paid_as_boarder","rent_paid_as_lodger","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","maintenance_expenses","childcare_expenses","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","ssmg_reported","incapacity_benefit_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","ossben_identifiable_subset","srp_regular_code5","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier"],"entity":"person","rows":"all"}],"kernel":"uk.stage.hmrc_spi_income_spine@1","mass":"conserve","outputs":[{"column":"charitable_investment_gifts","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"gift_aid","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"other_investment_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_employment_benefits","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_employment_expenses","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_other_social_security_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_taxable_termination_pay","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_miscellaneous_employment_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_other_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_state_pension_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"property_finance_costs","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_employed_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_total_earned_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_total_investment_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_assessable_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"employment_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"self_employment_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"savings_interest_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dividend_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"private_pension_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"property_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"employee_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"employer_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"personal_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pension_contributions_via_salary_sacrifice","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"tax_free_savings_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"universal_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pension_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"child_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"housing_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"income_support_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"working_tax_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"child_tax_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"attendance_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"state_pension_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dla_sc_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dla_m_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pip_m_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pip_dl_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"sda_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"carers_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"iidb_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"afcs_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"bsp_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"war_widows_pension_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"widowed_parents_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"winter_fuel_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"jsa_contrib_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"jsa_income_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"esa_contrib_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"esa_income_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"trading_loss","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"loss_relief","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"ni_class_4_losses_brought_forward","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_company_income_share","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"hmrc_spi_pay","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"hmrc_spi_unemployment_benefit_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"hmrc_spi_incapacity_benefit_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"employment_income_annual_share","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"employment_income_other_spells","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"self_employment_income_annual_share","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"self_employment_income_other_spells","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"private_pension_income_annual_share","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"contributory_benefits_annual_share","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"aa_category","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dla_sc_category","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dla_m_category","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pip_m_category","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pip_dl_category","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_enhanced_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_severely_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"would_claim_carers_allowance","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"uc_is_in_startup_period","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"uc_is_in_gainful_self_employment","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"esa_includes_support_component","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"reports_rent_from_other_property","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"stands_as_sole_owner_or_partner_of_company","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_engaged_in_owned_company_trade","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_company_is_main_employment","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_company_carries_on_trade","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_company_carries_on_property_business","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"person_is_spi_income_recipient","dtype":"bool","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"hmrc_spi_income_spine","stage_contract_sha256":"e29d18a70a59fb2f1398bcfb21308ec8446a1cdd7cdc44fa030feacf01ef960a","time_period":"2024"},"population":"spi_income_band_donors","sources":["frs"],"structural":"none","weights":null},{"base":"spi_income_band_donors","citation":"","description":"Ownership boundary before spi_housing_shell rewrites.","id":"spi_housing_shell.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage spi_housing_shell.","id":"spi_housing_shell","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["council_tax_single_adult_raw","household_support_channel","ons_household_type","region"],"entity":"household","rows":"all"},{"columns":["age","dividend_income","employment_income","is_household_head","other_investment_income","person_is_spi_income_recipient","private_pension_income","property_income","savings_interest_income","self_employment_income","state_pension_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.spi_housing_shell@1","mass":"conserve","outputs":[{"column":"tenure_type","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"accommodation_type","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_band","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"num_bedrooms","dtype":"int64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_reported","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"rent","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"mortgage_interest_repayment","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"mortgage_capital_repayment","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"structural_insurance_payments","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"housing_service_charges","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"water_and_sewerage_charges","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"domestic_rates","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"subrent","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_rebate","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"housing_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"spi_housing_shell","stage_contract_sha256":"524549b7dfbd0fceb505311eb0c3b923cfe3b11a8acd5ecfbfbcbb477e142eb1","time_period":"2024"},"population":"spi_housing_shell.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage was_wealth.","id":"was_wealth","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient"],"entity":"person","rows":"all"}],"kernel":"uk.stage.was_wealth@1","mass":"conserve","outputs":[{"column":"owned_land","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"property_wealth","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"corporate_wealth","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"private_pension_wealth","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"gross_financial_wealth","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"net_financial_wealth","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"main_residence_value","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"other_residential_property_value","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"non_residential_property_value","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"savings","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"num_vehicles","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"cash_isa","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"stocks_and_shares_isa","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"mortgage_debt","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"consumer_debt","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"student_loan_balance","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"directly_held_shares","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"unit_and_investment_trusts","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"other_residential_property_secured_debt","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"non_residential_property_secured_debt","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"was_wealth","stage_contract_sha256":"e648f94320deffd15d4e7c2f51e044e8b3572b24bb62d65f157edcb8f31753b5","time_period":"2024"},"population":"spi_housing_shell.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage was_lisa.","id":"was_lisa","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance"],"entity":"person","rows":"all"}],"kernel":"uk.stage.was_lisa@1","mass":"conserve","outputs":[{"column":"has_lifetime_isa","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"lifetime_isa_balance","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"household_lifetime_isa_balance","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"was_lisa","stage_contract_sha256":"46f12fdf9228f721d860ff7858b78b25406bb8737628acf63ac17d44d549f657","time_period":"2024"},"population":"spi_housing_shell.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"spi_housing_shell.boundary","citation":"","description":"Ownership boundary before regional_property_uprating rewrites.","id":"regional_property_uprating.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage regional_property_uprating.","id":"regional_property_uprating","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["household_lifetime_isa_balance","household_support_channel","region"],"entity":"household","rows":"all"},{"columns":["age"],"entity":"person","rows":"all"}],"kernel":"uk.stage.regional_property_uprating@1","mass":"conserve","outputs":[{"column":"main_residence_value","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"property_wealth","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_land","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"other_residential_property_value","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"non_residential_property_value","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"regional_property_uprating","stage_contract_sha256":"f45db95fde3f93731c0925b9bf8c12021921df2e4908770acdec1e3c97889277","time_period":"2024"},"population":"regional_property_uprating.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"regional_property_uprating.boundary","citation":"","description":"Run structural UK stage high_value_home_support.","id":"high_value_home_support","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.high_value_home_support@1","mass":"conserve","outputs":[],"params":{"expand_cells":[["household","household_is_high_value_support_copy","bool"],["household","high_value_support_copies","int64"],["household","high_value_support_copy_index","int64"]],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"high_value_home_support","stage_contract_sha256":"174f4b38228d98107bee1639d1a297a2748bb618e87c7bd0a6c869c6ab06f8fa","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by high_value_home_support.","id":"high_value_home_support.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"household_is_high_value_support_copy","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"high_value_support_copies","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"high_value_support_copy_index","dtype":"int64","entity":"household","ownership":"produced","rows":"all"}],"params":{"materialized_expand_outputs":["household.household_is_high_value_support_copy","household.high_value_support_copies","household.high_value_support_copy_index"]},"population":"high_value_home_support","sources":[],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage regional_home_values.","id":"regional_home_values","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["high_value_support_copy_index","household_is_high_value_support_copy","household_source_id","region","tenure_type"],"entity":"household","rows":"all"},{"columns":["age"],"entity":"person","rows":"all"}],"kernel":"uk.stage.regional_home_values@1","mass":"conserve","outputs":[{"column":"main_residence_value","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"property_wealth","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"main_residence_value_rank_basis","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"regional_home_values","stage_contract_sha256":"48e8a622c8830a54a4c48d9d8cb4f011751aa05d7cb5f6c7f0e06e1121b720b1","time_period":"2024"},"population":"high_value_home_support","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage property_components.","id":"property_components","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["main_residence_value_rank_basis","non_residential_property_value","other_residential_property_value","region","subrent"],"entity":"household","rows":"all"},{"columns":["age","is_household_head","person_is_spi_income_recipient","person_support_channel"],"entity":"person","rows":"all"}],"kernel":"uk.stage.property_components@1","mass":"conserve","outputs":[{"column":"property_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"property_finance_costs","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"property_rental_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"property_components","stage_contract_sha256":"5c84a402f34dc5bfcfc0b3c3c7a5e57576cfd21e7bfdeba3e80dcaf4e9d478ba","time_period":"2024"},"population":"high_value_home_support","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage property_purchases.","id":"property_purchases","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["household_source_id","non_residential_property_value","other_residential_property_value","region"],"entity":"household","rows":"all"},{"columns":["age","property_rental_income"],"entity":"person","rows":"all"}],"kernel":"uk.stage.property_purchases@1","mass":"conserve","outputs":[{"column":"additional_residential_property_purchased","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"non_residential_property_purchased","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"property_purchases","stage_contract_sha256":"078a79ce6f8c768c06526f1c05288602ce781e30c77b575b0bdf3f5b7d16da1b","time_period":"2024"},"population":"high_value_home_support","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage nts_bus_travel.","id":"nts_bus_travel","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income"],"entity":"person","rows":"all"}],"kernel":"uk.stage.nts_bus_travel@1","mass":"conserve","outputs":[{"column":"local_bus_use_band","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"bus_in_london_trips","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"other_local_bus_trips","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"local_bus_trips","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"bus_pass_eligible","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"local_bus_single_fare_share","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"household_local_bus_trips","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"nts_bus_travel","stage_contract_sha256":"87177e34a811bb488ca952f98825f823baeb9fd723cef41f8ee4acfab0ffb107","time_period":"2024"},"population":"high_value_home_support","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage lcfs_consumption.","id":"lcfs_consumption","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share"],"entity":"person","rows":"all"}],"kernel":"uk.stage.lcfs_consumption@1","mass":"conserve","outputs":[{"column":"food_and_non_alcoholic_beverages_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"alcohol_and_tobacco_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"clothing_and_footwear_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"housing_water_and_electricity_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"household_furnishings_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"health_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"transport_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"communication_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"recreation_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"education_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"restaurants_and_hotels_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"miscellaneous_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"petrol_spending","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"diesel_spending","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"bus_fare_spending","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"domestic_energy_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"electricity_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"gas_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"liquid_fuel_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"solid_fuel_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"has_fuel_consumption","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"uses_energy_prepayment_meter","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"beer_litres","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"cider_litres","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"wine_litres","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"spirits_litres","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"other_fermented_litres","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"beer_draught_share","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"cider_draught_share","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"cigarettes_per_week","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"hand_rolling_tobacco_grams_per_week","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"cigars_grams_per_week","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"other_tobacco_grams_per_week","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"remote_gaming_net_losses","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"pool_betting_net_receipts","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"bingo_net_receipts","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"national_lottery_ticket_spending","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"land_based_casino_net_losses","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"machine_games_lower_rate_net_takings","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"machine_games_standard_rate_net_takings","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"machine_games_higher_rate_net_takings","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"land_based_fixed_odds_betting_net_losses","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"remote_uk_horseracing_betting_net_losses","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"remote_other_betting_net_losses","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"betting_exchange_commission","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"horse_and_dog_pool_betting_net_losses","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"lcfs_consumption","stage_contract_sha256":"91a3358c59b5383b91156f66b0443c910e672e17f73ea19aff1ecd91ca42c029","time_period":"2024"},"population":"high_value_home_support","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage etb_vat.","id":"etb_vat","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share"],"entity":"person","rows":"all"}],"kernel":"uk.stage.etb_vat@1","mass":"conserve","outputs":[{"column":"full_rate_vat_expenditure_rate","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"etb_vat","stage_contract_sha256":"216b28835eba7a952243134dffbb45a1b3a0cdff2e3e7d0e94e2acbf754052b5","time_period":"2024"},"population":"high_value_home_support","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage etb_services.","id":"etb_services","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share"],"entity":"person","rows":"all"}],"kernel":"uk.stage.etb_services@1","mass":"conserve","outputs":[{"column":"dfe_education_spending","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"rail_subsidy_spending","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"bus_subsidy_spending","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"rail_usage","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"a_and_e_visits","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"admitted_patient_visits","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"outpatient_visits","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"nhs_a_and_e_spending","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"nhs_admitted_patient_spending","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"nhs_outpatient_spending","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"etb_services","stage_contract_sha256":"211e488552e57cda3138f98a6acb9d56e24db372b2a1d717fba63f9b80ff92ab","time_period":"2024"},"population":"high_value_home_support","sources":["frs"],"structural":"none","weights":null},{"base":"high_value_home_support","citation":"","description":"Ownership boundary before uc_reporter_redraw rewrites.","id":"uc_reporter_redraw.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage uc_reporter_redraw.","id":"uc_reporter_redraw","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.uc_reporter_redraw@1","mass":"conserve","outputs":[{"column":"universal_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"uc_reporter_redraw","stage_contract_sha256":"b03d4947d6cb0404ba410c548e1850d5abe0c7dae2dc097d419b63eea04920a9","time_period":"2024"},"population":"uc_reporter_redraw.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"uc_reporter_redraw.boundary","citation":"","description":"Ownership boundary before spi_benefit_coherence rewrites.","id":"spi_benefit_coherence.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage spi_benefit_coherence.","id":"spi_benefit_coherence","inputs":[{"columns":["benunit_support_channel","frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["aa_category","age","attendance_allowance_reported","dla_m_category","dla_m_reported","dla_sc_category","dla_sc_reported","esa_contrib_reported","incapacity_benefit_reported","is_uc_claimant","person_source_id","person_support_channel","pip_dl_category","pip_dl_reported","pip_m_category","pip_m_reported","universal_credit_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.spi_benefit_coherence@1","mass":"conserve","outputs":[{"column":"jsa_contrib_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"jsa_income_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"esa_income_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"income_support_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"working_tax_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"child_tax_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"sda_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"ssmg_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"iidb_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"afcs_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"bsp_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"war_widows_pension_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"widowed_parents_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_enhanced_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_severely_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"receives_benefits_in_own_right","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"would_claim_uc","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"spi_benefit_coherence","stage_contract_sha256":"ad3bfd51b377963c1d976a82416283aeb7b80d9f89b44c0e5db79e3598e815d5","time_period":"2024"},"population":"spi_benefit_coherence.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"spi_benefit_coherence.boundary","citation":"","description":"Ownership boundary before uc_capital_coherence rewrites.","id":"uc_capital_coherence.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage uc_capital_coherence.","id":"uc_capital_coherence","inputs":[{"columns":["benunit_support_channel","dependent_children","is_married"],"entity":"benunit","rows":"all"},{"columns":["non_residential_property_secured_debt","non_residential_property_value","other_residential_property_secured_debt","other_residential_property_value","owned_land","region"],"entity":"household","rows":"all"},{"columns":["age","dividend_income","is_benunit_head","is_household_head","is_parent","other_investment_income","person_support_channel","savings_interest_income","universal_credit_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.uc_capital_coherence@1","mass":"conserve","outputs":[{"column":"uc_reported_capital","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"pension_credit_reported_capital","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"frs_benunit_capital","dtype":"float64","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"would_claim_uc","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"uc_capital_coherence","stage_contract_sha256":"e7c7311b3852e67ae755c09456cc10c46136681fa92ade60daa1fbeb581288d5","time_period":"2024"},"population":"uc_capital_coherence.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"uc_capital_coherence.boundary","citation":"","description":"Ownership boundary before uc_take_up rewrites.","id":"uc_take_up.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage uc_take_up.","id":"uc_take_up","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.uc_take_up@1","mass":"conserve","outputs":[{"column":"would_claim_uc","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"uc_take_up","stage_contract_sha256":"9818609b1003442f197e99ca741dc8db658a82f36c67f35308ceef25537b739e","time_period":"2024"},"population":"uc_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage uc_legacy_closure_take_up.","id":"uc_legacy_closure_take_up","inputs":[{"columns":["frs_benunit_capital","would_claim_uc"],"entity":"benunit","rows":"all"},{"columns":["household_source_id","region"],"entity":"household","rows":"all"},{"columns":["age","child_tax_credit_reported","esa_income_reported","housing_benefit_reported","income_support_reported","is_claimant_or_partner","jsa_income_reported","universal_credit_reported","working_tax_credit_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.uc_legacy_closure_take_up@1","mass":"conserve","outputs":[{"column":"would_claim_uc_at_legacy_closure","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"uc_legacy_closure_take_up","stage_contract_sha256":"0bf6d4151d9cbd32bde34c2538bf6142d458c8828cc698fa1a9aad0d9e432246","time_period":"2024"},"population":"uc_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"uc_take_up.boundary","citation":"","description":"Ownership boundary before pension_credit_take_up rewrites.","id":"pension_credit_take_up.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital","would_claim_uc_at_legacy_closure"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage pension_credit_take_up.","id":"pension_credit_take_up","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital","would_claim_uc_at_legacy_closure"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.pension_credit_take_up@1","mass":"conserve","outputs":[{"column":"would_claim_pc","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"has_mixed_age_couple_pension_credit_saving","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"pension_credit_take_up","stage_contract_sha256":"e887dbbb186cb79f6d3fc9a629269dbac4a43381b9574df65353b816f01a3a35","time_period":"2024"},"population":"pension_credit_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"pension_credit_take_up.boundary","citation":"","description":"Ownership boundary before child_benefit_take_up rewrites.","id":"child_benefit_take_up.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage child_benefit_take_up.","id":"child_benefit_take_up","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.child_benefit_take_up@1","mass":"conserve","outputs":[{"column":"would_claim_child_benefit","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"child_benefit_opts_out","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"child_benefit_take_up","stage_contract_sha256":"78c889ae5a4bd4c61b1e0b259e3fe3e805f76e12c952d0523c92969957db05d5","time_period":"2024"},"population":"child_benefit_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"child_benefit_take_up.boundary","citation":"","description":"Ownership boundary before carers_allowance_take_up rewrites.","id":"carers_allowance_take_up.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage carers_allowance_take_up.","id":"carers_allowance_take_up","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.carers_allowance_take_up@1","mass":"conserve","outputs":[{"column":"would_claim_carers_allowance","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"carers_allowance_take_up","stage_contract_sha256":"c4c1ddf4b7da2c3082e09d6e77a9b4a0dc617743ff2c3c1f546f930bcac0635f","time_period":"2024"},"population":"carers_allowance_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage uc_deduction_attributes.","id":"uc_deduction_attributes","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","would_claim_carers_allowance"],"entity":"person","rows":"all"}],"kernel":"uk.stage.uc_deduction_attributes@1","mass":"conserve","outputs":[{"column":"uc_deduction_random_draw","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"uc_deduction_type_random_draw","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"uc_latent_deduction_rate","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"uc_deduction_combination","dtype":"string","entity":"benunit","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"uc_deduction_attributes","stage_contract_sha256":"6bc7e3ec1a5712e23ca1b7d2956e8b17f2526b94431ba3e5a9294b04658e4fe0","time_period":"2024"},"population":"carers_allowance_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"carers_allowance_take_up.boundary","citation":"","description":"Run structural UK stage cgt_support_split.","id":"cgt_support_split","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.cgt_support_split@1","mass":"conserve","outputs":[],"params":{"expand_cells":[["household","household_is_cgt_support_copy","bool"],["household","cgt_support_copies","int64"],["household","cgt_support_copy_index","int64"]],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"cgt_support_split","stage_contract_sha256":"d91faf93fc9fc0251b2165af1c79514dc5d942373bc8f13d8d7d5454e0fd931c","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by cgt_support_split.","id":"cgt_support_split.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"household_is_cgt_support_copy","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"cgt_support_copies","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"cgt_support_copy_index","dtype":"int64","entity":"household","ownership":"produced","rows":"all"}],"params":{"materialized_expand_outputs":["household.household_is_cgt_support_copy","household.cgt_support_copies","household.cgt_support_copy_index"]},"population":"cgt_support_split","sources":[],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"cgt_support_split","citation":"","description":"Run structural UK stage cgt_incidence_clone.","id":"cgt_incidence_clone","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.cgt_incidence_clone@1","mass":"conserve","outputs":[],"params":{"expand_cells":[["household","household_is_capital_gains_clone","bool"],["person","capital_gains","float64"]],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"cgt_incidence_clone","stage_contract_sha256":"ee30278543cc0297a5366d855b7753aa04af5518971594c193c52be36bf8a7b4","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by cgt_incidence_clone.","id":"cgt_incidence_clone.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"household_is_capital_gains_clone","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"capital_gains","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"materialized_expand_outputs":["household.household_is_capital_gains_clone","person.capital_gains"]},"population":"cgt_incidence_clone","sources":[],"structural":"none","weights":null},{"base":"cgt_incidence_clone","citation":"","description":"Ownership boundary before hmrc_cgt_gains_spine rewrites.","id":"hmrc_cgt_gains_spine.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage hmrc_cgt_gains_spine.","id":"hmrc_cgt_gains_spine","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["cgt_support_copies","corporate_wealth","gross_financial_wealth","household_is_cgt_support_copy","non_residential_property_value","other_residential_property_value","region"],"entity":"household","rows":"all"},{"columns":["age","dividend_income","employment_income","miscellaneous_income","private_pension_income","property_income","savings_interest_income","self_employment_income","state_pension_reported","tax_free_savings_income"],"entity":"person","rows":"all"}],"kernel":"uk.stage.hmrc_cgt_gains_spine@1","mass":"conserve","outputs":[{"column":"capital_gains","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"hmrc_cgt_gains_spine","stage_contract_sha256":"8400624c4efaf1ab36add705318f660bafff7b73b9770080b6950e50de231bb7","time_period":"2024"},"population":"hmrc_cgt_gains_spine.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"hmrc_cgt_gains_spine.boundary","citation":"","description":"Run structural UK stage cgt_incidence_anchor.","id":"cgt_incidence_anchor","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["household_is_capital_gains_clone","region"],"entity":"household","rows":"all"},{"columns":["age","capital_gains","dividend_income","employment_income","miscellaneous_income","private_pension_income","property_income","savings_interest_income","self_employment_income","state_pension_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.cgt_incidence_anchor@1","mass":"conserve","outputs":[],"params":{"expand_cells":[],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"cgt_incidence_anchor","stage_contract_sha256":"b79ce806015de2f1e1703fa68bf4ad871c6df54b5b32633c864632ab68919a48","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"cgt_incidence_anchor","citation":"","description":"Run structural UK stage cgt_residential_split.","id":"cgt_residential_split","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.cgt_residential_split@1","mass":"conserve","outputs":[],"params":{"expand_cells":[["household","household_is_cgt_residential_clone","bool"],["household","cgt_residential_clone_index","int64"],["person","cgt_residential_probability","float64"],["person","capital_gains_residential_property","float64"]],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"cgt_residential_split","stage_contract_sha256":"e4ef9c4f94f3d5944a524e8e1e24b8ea983790c9f7ea491a75b6ae3893371a59","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by cgt_residential_split.","id":"cgt_residential_split.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"household_is_cgt_residential_clone","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"cgt_residential_clone_index","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"cgt_residential_probability","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"capital_gains_residential_property","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"materialized_expand_outputs":["household.household_is_cgt_residential_clone","household.cgt_residential_clone_index","person.cgt_residential_probability","person.capital_gains_residential_property"]},"population":"cgt_residential_split","sources":[],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage hmrc_cgt_asset_type_spine.","id":"hmrc_cgt_asset_type_spine","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["corporate_wealth","gross_financial_wealth","other_residential_property_value","region","stocks_and_shares_isa"],"entity":"household","rows":"all"},{"columns":["age","capital_gains","capital_gains_residential_property","dividend_income","property_income","reports_rent_from_other_property","self_employment_income"],"entity":"person","rows":"all"}],"kernel":"uk.stage.hmrc_cgt_asset_type_spine@1","mass":"conserve","outputs":[{"column":"capital_gains_asset_type","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"capital_gains_badr","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"hmrc_cgt_asset_type_spine","stage_contract_sha256":"52148b13d8ce5e4292991a7840d441c6b49d67a609d99497854c2a45a21adb98","time_period":"2024"},"population":"cgt_residential_split","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage salary_sacrifice.","id":"salary_sacrifice","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone","household_is_cgt_residential_clone","cgt_residential_clone_index"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains","cgt_residential_probability","capital_gains_residential_property","capital_gains_asset_type","capital_gains_badr"],"entity":"person","rows":"all"}],"kernel":"uk.stage.salary_sacrifice@1","mass":"conserve","outputs":[{"column":"pension_contributions_via_salary_sacrifice","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pension_contributions_via_bonus_sacrifice","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"employee_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"employment_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"salary_sacrifice_pre_conversion_pay","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"salary_sacrifice","stage_contract_sha256":"76c0120b5d27115d732faac38f9fe3c1a474be944a06bbecd0380a209b0a7331","time_period":"2024"},"population":"cgt_residential_split","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage student_loans.","id":"student_loans","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","age_left_full_time_education","current_education","highest_education","reports_outstanding_student_loan","salary_sacrifice_pre_conversion_pay","student_loan_repayments","student_loans"],"entity":"person","rows":"all"}],"kernel":"uk.stage.student_loans@1","mass":"conserve","outputs":[{"column":"student_loan_plan","dtype":"string","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"student_loans","stage_contract_sha256":"157d9ee607633e4246ed06eeee3aac3cdff98118e72400e18b84c11b3fd2b92b","time_period":"2024"},"population":"cgt_residential_split","sources":["frs"],"structural":"none","weights":null},{"base":"cgt_residential_split","citation":"","description":"Ownership boundary before childcare_copy_take_up rewrites.","id":"childcare_copy_take_up.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone","household_is_cgt_residential_clone","cgt_residential_clone_index"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains","cgt_residential_probability","capital_gains_residential_property","capital_gains_asset_type","capital_gains_badr","pension_contributions_via_bonus_sacrifice","salary_sacrifice_pre_conversion_pay","student_loan_plan"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage childcare_copy_take_up.","id":"childcare_copy_take_up","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_uc_childcare","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone","household_is_cgt_residential_clone","cgt_residential_clone_index"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains","cgt_residential_probability","capital_gains_residential_property","capital_gains_asset_type","capital_gains_badr","pension_contributions_via_bonus_sacrifice","salary_sacrifice_pre_conversion_pay","student_loan_plan"],"entity":"person","rows":"all"}],"kernel":"uk.stage.childcare_copy_take_up@1","mass":"conserve","outputs":[{"column":"would_claim_tfc","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"would_claim_extended_childcare","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"would_claim_universal_childcare","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"would_claim_targeted_childcare","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"maximum_extended_childcare_hours_usage","dtype":"float64","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"max_free_entitlement_hours_used","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"childcare_copy_take_up","stage_contract_sha256":"cdbb7e135b16fac7ca1bcd6c54222821e2976b4da99f10a60913efd0ba03c13c","time_period":"2024"},"population":"childcare_copy_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage private_school_attendance.","id":"private_school_attendance","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone","household_is_cgt_residential_clone","cgt_residential_clone_index"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","frs_bonus_amount","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains","cgt_residential_probability","capital_gains_residential_property","capital_gains_asset_type","capital_gains_badr","pension_contributions_via_bonus_sacrifice","salary_sacrifice_pre_conversion_pay","student_loan_plan"],"entity":"person","rows":"all"}],"kernel":"uk.stage.private_school_attendance@1","mass":"conserve","outputs":[{"column":"attends_private_school","dtype":"bool","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.162.3"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"private_school_attendance","stage_contract_sha256":"7e44379c0331fe4c9de05cd76a075c1a6aa22cf0dec6cd2f91b277e70f14a038","time_period":"2024"},"population":"childcare_copy_take_up.boundary","sources":["frs"],"structural":"none","weights":null}],"sources":[{"codec":"csv-tables","description":"Content-bound UK FRS and donor fixture/source bundle.","name":"frs"}]} diff --git a/test_support/microcosm_build/uk_calibration_run.py b/test_support/microcosm_build/uk_calibration_run.py index 713044b627..0bb9100c92 100644 --- a/test_support/microcosm_build/uk_calibration_run.py +++ b/test_support/microcosm_build/uk_calibration_run.py @@ -102,23 +102,6 @@ def _fake_cgt_projection(base_year: int = 2023, horizon_year: int = 2030): ) -@pytest.fixture(autouse=True) -def _every_seam_row_published(monkeypatch): - """Publish every row of the four-household seam fixture. - - A row's model figures leave a build only when ten distinct source - households carry it (María's rule of 2026-10-21 binds a thin row and - withholds its figures), and no row here rests on more than four, so the - fit gate would see no published row. The pipeline tests lower the count - to one to read the solve's figures; the withheld path has its own tests - in test_uk_diagnostics.py and test_uk_battery_bindings.py. - """ - - from microcosm.build.uk_runtime import diagnostics - - monkeypatch.setattr(diagnostics, "UK_DIAGNOSTIC_MIN_SOURCE_HOUSEHOLDS", 1) - - @pytest.fixture(autouse=True) def _cgt_projection(monkeypatch): """The seam reads the projection from the engine; tests supply a flat one.""" diff --git a/test_support/microcosm_build/uk_full_build_cli.py b/test_support/microcosm_build/uk_full_build_cli.py index 790db533c0..ae044786d3 100644 --- a/test_support/microcosm_build/uk_full_build_cli.py +++ b/test_support/microcosm_build/uk_full_build_cli.py @@ -332,10 +332,10 @@ def gate_payload(phase, failed=None, release_candidate=False): LADDER_TARGET = "ons.census.households@E14000001" -#: microcosm#1262: tests flip ``WITHHELD_BRMA_ROW`` to stage a Scottish BRMA -#: row whose model figures the terminal gates withhold (it rests on fewer than -#: ten source households), so the projection reads it blank. -WITHHELD_BRMA_ROW = False +#: Tests flip ``THIN_BRMA_ROW`` to stage a Scottish BRMA row that rests on +#: fewer than ten source households; it carries its model figures like any +#: other row (María's ruling of 2026-10-26). +THIN_BRMA_ROW = False BRMA_TARGET = "ons.rent.private_rent_brma@S33000001" #: The synthetic measures node's engine resolution, as the problem bindings @@ -380,7 +380,7 @@ def problem_payload() -> bytes: "source": "fixture", } ] - if WITHHELD_BRMA_ROW: + if THIN_BRMA_ROW: targets.append( Target( BRMA_TARGET, @@ -580,16 +580,17 @@ def holdout_payload_dict() -> dict: def target_rows_csv() -> bytes: - """The terminal targets table; a withheld BRMA row reads blank (#1262).""" + """The terminal targets table, with the thin BRMA row when it is staged.""" - if not WITHHELD_BRMA_ROW: + if not THIN_BRMA_ROW: return TARGET_ROWS_CSV - header, ladder = TARGET_ROWS_CSV.decode().splitlines() return ( - f"{header},model_figures_withheld\n{ladder},False\n" - f"{BRMA_TARGET}@2025,{BRMA_TARGET}@2025,1000.0,,,," - "private_rent,brma,brma,S33000001,rent/private_rent_brma,True\n" - ).encode() + TARGET_ROWS_CSV + + ( + f"{BRMA_TARGET}@2025,{BRMA_TARGET}@2025,1000.0,900.0,-0.1,0.1," + "private_rent,brma,brma,S33000001,rent/private_rent_brma\n" + ).encode() + ) SUPPORT_CSV = ( diff --git a/tools/assemble_uk_dense_release_dir.py b/tools/assemble_uk_dense_release_dir.py index 8ab823ad86..76a1de968a 100644 --- a/tools/assemble_uk_dense_release_dir.py +++ b/tools/assemble_uk_dense_release_dir.py @@ -586,8 +586,9 @@ def _area_support_block(solve: Mapping[str, object]) -> dict[str, object]: The support gate blocks release, so an area of a released file sits below a floor only under a reviewed exclusion the gate stood on, and those - entries name the areas. The areas' support figures stay in the run - directory's area-support table, which no release ships (microcosm#1301). + entries name the areas. Their support figures are in the signed gate + report's reviewed exclusions (María's ruling of 2026-10-26 dropped their + withholding, microcosm#1301). """ from microcosm.build.uk_runtime.battery_bindings import uk_area_support_floors @@ -1103,9 +1104,7 @@ def artifact(kind: str, path: str, sha256: str) -> dict[str, str]: (release_dir / "sha256sums.txt").write_text( "".join(f"{digest} {name}\n" for name, digest in sorted(sums.items())) ) - # The contract warns, without refusing, on a per-area support figure in a - # shipped document (microcosm#1301); each warning is weighed before - # publication. + # A contract warning never refuses; each is weighed before publication. contract_warnings = validate_release_dir(release_dir) for contract_warning in contract_warnings: print(f"warning: {contract_warning}", file=sys.stderr) diff --git a/tools/draft_uk_dense_signoff.py b/tools/draft_uk_dense_signoff.py index 296de62803..3b83cf88fe 100644 --- a/tools/draft_uk_dense_signoff.py +++ b/tools/draft_uk_dense_signoff.py @@ -67,10 +67,8 @@ It checks that build 2 stood on every in-line entry of the three registers at this checkout and that none was stale, dormant, premature, expired or unknown. It checks that no release-blocking gate failed and that the signed local report -passes the dense release contract (the signing key must be exported). Like the -contract, it warns, without failing, when the disclosure walk finds a per-area -support figure in that report. It fails once the assembly deadline has passed -and warns from two days before it. With +passes the dense release contract (the signing key must be exported). It fails +once the assembly deadline has passed and warns from two days before it. With ``--build-1`` it also reports whether build 2 reused build 1's solve and reproduced its per-row errors. With ``--draft-receipt`` it checks that the sign-off committed what was drafted: every added or renewed entry, no retired @@ -509,6 +507,10 @@ class BuildEvidence: #: local fit gate decides on the other rows and counts them (María's #: ruling of 2026-10-19). Nothing signs a withheld cell. local_withheld: frozenset[str] = frozenset() + #: National rows whose model figures the build withholds, which her rule + #: of 2026-10-21 extends the withholding to: ``national_errors`` lacks + #: them, and the national fit gate counts them as the local one does. + national_withheld: frozenset[str] = frozenset() def details(self, gate_id: str) -> Mapping[str, Any]: return self.outcomes.get(gate_id, {}).get("details") or {} @@ -725,31 +727,32 @@ def _check_support(frame: pd.DataFrame, embedded: object) -> None: def _split_errors( frame: pd.DataFrame, -) -> tuple[dict[str, float], dict[str, float], frozenset[str]]: - """National and local errors by gate key, and the withheld local keys.""" +) -> tuple[dict[str, float], dict[str, float], frozenset[str], frozenset[str]]: + """National and local errors by gate key, and the withheld national and + local keys (a thin national row is withheld too, by María's rule of + 2026-10-21).""" national: dict[str, float] = {} local: dict[str, float] = {} - withheld: set[str] = set() + national_withheld: set[str] = set() + local_withheld: set[str] = set() for row in frame.itertuples(index=False): if row.geography_level in LOCAL_LEVELS: key = f"{row.family.strip()}/{row.area_code.strip()}/{row.metric.strip()}" - target = local + target, withheld = local, local_withheld else: key = row.name - target = national + target, withheld = national, national_withheld if key in target or key in withheld: raise InputError(f"targets.csv repeats the gate key {key!r}.") if row.model_figures_withheld: - if target is national: - raise InputError("targets.csv withholds a national row.") withheld.add(key) continue error = float(row.relative_error) if not math.isfinite(error): raise InputError("targets.csv carries a non-finite relative error.") target[key] = error - return national, local, frozenset(withheld) + return national, local, frozenset(national_withheld), frozenset(local_withheld) def _check_fit_details( @@ -862,9 +865,11 @@ def load_build(run_dir: Path, *, allow_dev_build: bool = False) -> BuildEvidence missing = sorted(SIGNABLE_GATES - set(parameters)) if missing: raise InputError(f"the terminal report has no outcome for {missing}.") - national, local, withheld = _split_errors(targets) + national, local, national_withheld, withheld = _split_errors(targets) + # The national fit gate counts every row the build withholds (its parity + # evidence carries the surface's whole set), the local one its own cells. for gate_id, errors, hidden in ( - ("uk_target_fit", national, frozenset()), + ("uk_target_fit", national, national_withheld | withheld), ("uk_local_target_fit", local, withheld), ): outcome = outcomes[gate_id] @@ -906,6 +911,7 @@ def load_build(run_dir: Path, *, allow_dev_build: bool = False) -> BuildEvidence measure_exclusions=measure_exclusions, measure_exclusions_from=measure_exclusions_from, local_withheld=withheld, + national_withheld=national_withheld, ) below = area_support_below_floor(support, **evidence.area_floors) if "support_below_floor" in support and not np.array_equal( @@ -1862,13 +1868,13 @@ def field_of(record: object, name: str) -> str: def drafted_disclosure_failures(drafts: Mapping[str, RegisterDraft]) -> list[str]: - """The dense contract's disclosure walk over the drafted entries. + """The contract's disclosure walk over the drafted entries. - Build 2's signed local report, which a release ships, carries every entry - its gates stand on, so a drafted reason (a ``--class-note`` included) - gets the walk the release directory gets (microcosm#1301). A finding - refuses the draft, where the release contract only warns: re-drafting - costs nothing, and the entries go into the sign-off PR on a public repo. + The entries go into the sign-off PR on a public repo, so a drafted reason + (a ``--class-note`` included) must carry no per-area support figure + (microcosm#1301), although a release itself ships them since María's + ruling of 2026-10-26. A finding refuses the draft: re-drafting costs + nothing. """ from microcosm.data.contract import _uk_dense_disclosure_findings @@ -2823,15 +2829,10 @@ def verify( It also fails once the assembly deadline (:func:`assembly_deadline`, on build 2's measure exclusions and this checkout's registers) has passed, - and warns from :data:`DEADLINE_WARNING_DAYS` days before it. A per-area - support figure in the signed local report is a warning, as in the - release contract (microcosm#1301). + and warns from :data:`DEADLINE_WARNING_DAYS` days before it. """ - from microcosm.data.contract import ( - _check_uk_dense_gate_report, - _uk_dense_disclosure_findings, - ) + from microcosm.data.contract import _check_uk_dense_gate_report today = _today() if today is None else today failures: list[str] = [] @@ -2913,15 +2914,6 @@ def verify( build_2.local_report, failures=contract_failures, attempt_id=build_2.attempt_id ) failures.extend(f"contract: {line}" for line in contract_failures) - # The signed local report ships in the release, so it gets the release - # directory's disclosure walk (microcosm#1301) here, before assembly, - # and warns as the release contract does. - warnings.extend( - f"contract: {line}" - for line in _uk_dense_disclosure_findings( - "the signed local gate report", build_2.local_report - ) - ) comparison: dict[str, Any] = {} if build_1 is not None: @@ -2960,6 +2952,10 @@ def verify( ("local", key) for key in build_1.local_withheld ^ build_2.local_withheld } + | { + ("national", key) + for key in build_1.national_withheld ^ build_2.national_withheld + } ) if differing: warnings.append(f"{differing} target rows differ from build 1") diff --git a/tools/preflight_uk_local_release_candidate.py b/tools/preflight_uk_local_release_candidate.py index dcea3f811c..44a4f24ce1 100644 --- a/tools/preflight_uk_local_release_candidate.py +++ b/tools/preflight_uk_local_release_candidate.py @@ -437,67 +437,6 @@ def check_candidate_dir(candidate_dir: Path, *, today: date | None = None) -> li return failures -#: The opt-in incumbent comparison's files in a run directory, which the -#: assembler ships byte for byte when ``--incumbent-manifest`` attaches them. -INCUMBENT_COMPARISON_FILES = ( - "score_vs_incumbent.json", - "incumbent_surface_evaluation.json", -) - - -def candidate_disclosure_warnings( - candidate_dir: Path, *, incumbent_manifest: Path | None = None -) -> list[str]: - """The release's disclosure walk over a run's to-be-shipped JSON (microcosm#1301). - - The assembler ships the candidate manifest, the original diagnostics and - the signed local gate report byte for byte, and, when the incumbent - comparison is attached, the score, the surface evaluation and the - extraction manifest (``incumbent_manifest``). So a per-area support figure - in one of them, or a false match, shows here after the build rather than - first at assembly. The comparison's files are walked whenever the run - directory holds them. Each file is read and walked as the contract does - (:func:`microcosm.data.contract._uk_dense_disclosure_file_warnings`), so a - file with NaN or a nesting too deep to walk is reported rather than - skipped or crashing the pre-flight. Like the contract, it warns and never - fails. - """ - - from microcosm.data.contract import _uk_dense_disclosure_file_warnings - - manifest_path = candidate_dir / "rowwise_candidate_manifest.json" - try: - outputs = json.loads(manifest_path.read_text()).get("outputs") or {} - except (OSError, ValueError, AttributeError, RecursionError): - # check_candidate_dir reports a missing or unreadable manifest, and - # the walk below reports one it cannot walk. - outputs = {} - if not isinstance(outputs, dict): - outputs = {} - - def shipped(key: str, pattern: str) -> Path | None: - # The manifest's own output path, as the assembler reads it. - entry = outputs.get(key) - if isinstance(entry, dict) and entry.get("path"): - path = Path(str(entry["path"])) - return path if path.is_absolute() else candidate_dir / path - matches = sorted(glob.glob(str(candidate_dir / pattern))) - return Path(matches[0]) if matches else None - - paths = [ - manifest_path, - shipped("calibration_diagnostics", "*.diagnostics.json"), - shipped("local_gate_report", "*local_gates.json"), - *(candidate_dir / name for name in INCUMBENT_COMPARISON_FILES), - incumbent_manifest, - ] - warnings: list[str] = [] - for path in paths: - if path is not None and path.is_file(): - warnings += _uk_dense_disclosure_file_warnings(path) - return warnings - - def main(argv: list[str] | None = None) -> int: parser = argparse.ArgumentParser(description=__doc__.split("\n\n")[0]) parser.add_argument( @@ -514,7 +453,7 @@ def main(argv: list[str] | None = None) -> int: type=Path, help=( "with --candidate-dir, the incumbent extraction manifest assembly " - "will attach; the disclosure walk reads it too" + "will attach" ), ) parser.add_argument( @@ -524,8 +463,7 @@ def main(argv: list[str] | None = None) -> int: if args.incumbent_manifest is not None and args.candidate_dir is None: parser.error("--incumbent-manifest needs --candidate-dir") failures: list[str] = [] - # The contract's warnings (the disclosure walk, microcosm#1301) are - # printed but never fail the pre-flight. + # The contract's warnings are printed but never fail the pre-flight. warnings: list[str] = [] if args.release_dir is not None: from microcosm.data.contract import ReleaseContractError, validate_release_dir @@ -561,9 +499,6 @@ def main(argv: list[str] | None = None) -> int: and not args.incumbent_manifest.is_file() ): failures.append(f"incumbent manifest missing: {args.incumbent_manifest}") - warnings += candidate_disclosure_warnings( - args.candidate_dir, incumbent_manifest=args.incumbent_manifest - ) if not args.env and args.candidate_dir is None and args.release_dir is None: parser.error( "nothing to check: pass --env, --candidate-dir and/or --release-dir"