Repository navigation
Assumptions strip reads an assumptions block from the results (#14 §5) - #18
Closed
vahid-ahmadi wants to merge 4 commits into
Closed
vahid-ahmadi wants to merge 4 commits into
vahid-ahmadi wants to merge 4 commits into
Conversation
The pipeline writes `assumptions` ([{key, title, text, facts}]) from the
model's configuration and the assembled results, so the Budget impact tab's
"What these figures assume" strip changes when the model does. The population
item's wording follows pipeline.POPULATION, which the build checks against the
central run's held State Pension type counts. The dashboard renders the block
when it is valid and otherwise computes the strip as before.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…build's runs carry integer ones Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…peline constant The engine records how a run treats the population in fixed_inputs.population (weights, ages, pension types), read from what it pins and the model's ages, and the pipeline words the item from it, with #14 §3's vocabulary for ONS reweighting and cohort types; a missing record, a value without wording or a missing figure fails the build. The dashboard computes the strip only for a file with no block; a damaged block shows its valid items or nothing. The paths item's calibration, floor and shock-model wording come from the results. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… by the dataset load The dataset load (_managed) declares what it did to the survey's weights and ages (engine.LOADED_POPULATION), since a change made inside the dataset leaves nothing to compare against; population_treatment fails without a declaration and checks it against pinned weights and the model's ages. Pension types are recorded from the rule pinned_inputs follows (PENSION_TYPE_RULE), replacing a comparison that could not fail. The block fails unless the central run and every trajectory record the same treatment. Sensitivities outside the reweightings to past dynamics, and models without a short name, are worded generically; scripts/check_assumptions.py checks a pilot's results in seconds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Author
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #14 (section 5, "Dashboard strip"), #12.
What and why
The Budget impact tab's "What these figures assume" strip (#12) worded its three items in the dashboard. Max's point in #14: "Otherwise merging model-v2 would leave 'today's pensioners, held fixed' live and wrong." This PR moves the wording into the model, so the strip changes when the model does.
fixed_inputs.population, as{weights, ages, pension_types}. This comes fromengine.population_treatment._managedattachesengine.LOADED_POPULATION({"weights": "survey", "ages": "survey_year"}), and a simulation without a declaration fails."ons_projection"or"adjusted"."survey"declaration. Ages the run pins, or that the model moves between years, fail a"survey_year"declaration; ages that move between years are recorded as"aged_forward".pinned_inputsfollows (PENSION_TYPE_RULE = "survey_year"), or"model"if no types are pinned.pinned_inputsraises on a rule it does not implement, so a cohort rule (§3.3) has to add its own branch and name. The earlier pinned-versus-survey comparison could never fail, so I removed it.held_pension_typesstill checks that the model used the pinned types._managedsets: it gives today'ssurvey/survey_year/survey_year.pipeline.assumptions): builds[{key, title, text, facts}]andbuild()writes it asresults["assumptions"].MissingFigure) if a record is missing, a value has no wording, or a figure the text quotes is missing.LandingTab.jsx,dataHelpers.getAssumptions): renders the block's valid items. It computes the strip itself only for a file with noassumptionskey, such as today's.The block
population:weights,ages,pension_types,final_year,data_year, the final year'sstate_pension_age(a list) and the year it settles, andmax_age. When ages and types are both from the survey year, the build also fails if the held type counts move once the State Pension age stops changing.paths: the lowest and highest final-year gross saving across the reweightings to past dynamics (shift_dynamics*), with SEs and the highest's effective runs. Other sensitivity families, such as §4's mean-path sensitivity, are listed inother_sensitivitiesand counted in the text as left out of the range; they don't fail the build.expected_value.primary, and the floor figure comes fromTRIPLE_LOCK_FLOOR. The "in some versions" clause depends on how many reweightings include the floor.trajectories.models. A model with no short name is named by its ownlabel.benefits: the coverage year; Pension Credit claims and pension-age Housing Benefit for the survey and DWP; UK against Great Britain; and the paired sensitivity-dataset net difference (mean, SE, paths, dataset name).This is documented in
docs/RESULTS_SCHEMA.md, includingfixed_inputs.population.Wording parity: with today's population record, the block's text is byte-identical to what the dashboard computes now. I re-checked this with a one-off render, not committed.
Pilot checklist (#14 §5)
assumptions()must be on the §5 pilot checklist. RunPYTHONPATH=src python scripts/check_assumptions.py <pilot results.json>on the pilot's results: in seconds it prints each item's title, or the reason the block can't be written. That way a gap shows before the 8-16 hour rebuild, not at its end. A test covers the script.Fallback
assumptionskey (today's file): the dashboard computes the strip as it does now.Why draft
tests/test_results.py::test_not_stalefails, and only on theengine.pyandpipeline.pysource hashes.engine.pyis in the job cache key, so this lands with the model-v2 rebuild, like #16 and #17. The committeddata/results.jsonhas neither the block norfixed_inputs.population; I have not rebuilt it or edited it by hand. Until the rebuild, the dashboard shows the computed strip, which reads the same as today.The same claim elsewhere (not fixed here)
#18 alone does not remove the stale-text risk. The same "held fixed" claim is hard-coded in three other places:
METHOD_LIMITATIONSinsrc/triple_lock/pipeline.py(lines 73-75: "The survey is not aged forward … State Pension type … held at its survey-year value");dashboard/src/components/SummaryTab.jsx(lines 163-164: "survey here is not aged: ages stay at their survey values … each pensioner keeps the …");dashboard/src/components/MethodTab.jsx(line 197: "each person keeps their survey-year State Pension type").These need the same treatment, or an update in the model-v2 PR. That is a follow-up issue.
Tests
test_not_stalefails as described above.test_engine_pure.py, on stubs:aged_forward;model;pinned_inputsraises on an unimplemented type rule.test_results.py:paired_difference,trajectories.models,strataormax_age;bun run buildsucceeds.Follow-up
The strip lays its items out in three columns (
md:grid-cols-3). If model-v2 writes a fourth item, the layout will need a look.🤖 Generated with Claude Code