Repository navigation
Require every reported number to come from a model run - #92
Conversation
Adds a top-level rule to the policyengine skill: fiscal, distributional, poverty and household figures come from running the microsimulation for each scenario, never from scaling, interpolating or extrapolating other runs' outputs or from a side model. When there are too many scenarios, run fewer and say how many runs stand behind each figure. The policyengine-uk skill gains a verified "Macro scenarios" section: a CPI/earnings path must be a Scenario applied before the data load. The same changes passed as a reform= dict are a silent no-op (verified: no income, benefit rate, State Pension or income tax moved). policyengine-tools says data files hold model outputs only, and the review-program rubric makes a scaled or extrapolated figure critical. Releases the plugin as 4.0.3. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The rule bans figures derived from other runs' output, not arithmetic on the runs being reported (differences, sums, ratios, sampling error). - Macro + policy: two macro simulations; policies that process_parameters() reads go into the macro scenario; `+` drops applied_before_data_load; don't compare against sim.baseline. - Note the triple-lock (2034) and index (2039) horizons, that pe.uk Policy/Dynamic can't carry a macro path, and why reform= is a no-op. - reform-comparator no longer allows labelled linear scaling; the review-program rubric covers published estimates, not test values. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Macro + policy: remove the claim that merging makes later years of an uprated parameter follow a one-year change; set every reported year instead. State the before-load period keys and that a repeated path replaces the macro one. - policyengine skill: the macro Scenario is the one analysis use of policyengine_uk directly. - policyengine-uk skill: the 5.3.0 bundle's UK default is enhanced_frs_2024_25 (policyengine.py#491, 21 Aug 2026). - policyengine-tools: data files may hold arithmetic on the runs shown and labelled external comparators. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The certified bundle in policyengine 5.3.0 through 6.1.2 serves enhanced_frs_2024_25 (policyengine-uk-data 1.56.16) as the UK default, checked in both manifests on 2026-09-29. The policyengine and policyengine-data skills and the UK skill's frontmatter still called populace_uk_2023 the default; the round-3 review flagged the mismatch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keep main's dataset facts (Microcosm UK default, bundle 6.16.0 build ids) in every conflicted hunk, add this PR's scenario/uncertainty/Monte Carlo triggers to the policyengine skill, and release the bundles as 4.1.1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ite UK macro-scenario section to current code Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Merge audit (PR sweep of 2026-11-11): the sweep merged main (695b307) and fixed what the first independent review asked for (c706b6f): two stale dataset lines restored to main's wording, a false parenthetical about |
#92 edited the SKILL.md of three skills (policyengine, policyengine-tools, policyengine-uk), a reference file of a fourth, the reform-comparator agent and all eight bundles without rebuilding the manifest, so main's committed manifest no longer matched its sources. On main's corpus, main's builder and this branch's give the same 324 pairs and scores; only overlap order and 7 shared_terms lists differ. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Why
PolicyEngine is a microsimulation model; its outputs are the product. The uk-triple-lock analysis reported a 20,000-draw uncertainty range for State Pension costs that ran the model only about 30 times. Every other draw was priced as
spend × (index_TL − index_alt) / index_centralfrom one central run, and the few full runs were described as validating that shortcut. The draws also changed only the pension rate. Every other CPI- or earnings-linked parameter, and every income in the data, stayed on the central path. Nothing in the skills told an agent this is unacceptable, so this adds it where agents and reviewers look.What changes
policyengineskill: "Every reported number is a model run", a new top-level section. It lists what is banned (ratio scaling, interpolation or extrapolation between runs, elasticities or shares borrowed from one run, side models, and changing one parameter when a scenario should move the whole system). It also says what to do instead: run fewer scenarios fully and state how many runs stand behind each figure. The description gainsscenarios, uncertainty, Monte Carloso the skill loads for that work.policyengine-ukskill: "Macro scenarios", with a<!-- verify: slow -->example. A CPI or earnings path has to be aScenarioapplied before the data load. Verified on policyengine 5.3.0 / policyengine-uk 2.90.2 with +1pp CPI and earnings in 2027–33, by reading the code and running it:reform=dictThe dict form is a silent no-op. It edits
yoy_growthafterprocess_parameters(), so nothing derived from it is rebuilt. The section also covers the period-key trap ("year:2030-01-01:1", not a bare year and not thestart.stopform) and the./data/HDF5 lock when running processes in parallel.policyengine-tools: data files hold model outputs only; no scaling in the pipeline or the frontend.review-programrubric: a figure published as a PolicyEngine estimate that was derived from other runs' output, instead of a run of that scenario, is always CRITICAL, whatever validation accompanies it. Hand-calculated test values are not covered.Plugin release 4.0.3 (all bundles and the marketplace template).
Checks
uv run pytest --ignore=tests/test_skill_examples.py: 178 passedscripts/build_claude_wrapper.py: buildsenhanced_frs_2024_25) and its assertions passed.skill-examplesfails on 8 US examples unrelated to this PR: policyengine 6.0.0 (15 Sep, aftermainlast passed on 13 Sep; CI now installs 6.1.2) makespe.us.calculate_householdraiseSPMInputError: County selection has no county FIPS input. Tracked separately; this PR merges once that is fixed.Review round 1 (independent Opus review)
All eight findings addressed:
process_parameters()go into the macro scenario. It warns that+dropsapplied_before_data_loadand thatsim.baselineuses the default macro path.pe.ukPolicy/Dynamic can't carry a macro path.reform-comparatorno longer allows labelled linear scaling.reform=is a no-op.Review round 2
The reviewer confirmed F1 and F3–F7 fixed. Two things were still open:
apply_parameter_changesreloads the raw YAML, and later years uprate from the old value. That clause is gone; the skill now says to set every reported year through the after-load route, and it documents the key formats and the merge override.enhanced_frs_2024_25, and the skill's stalepopulace_uk_2023default is corrected per policyengine.py#491;policyengine_ukexemption;🤖 Generated with Claude Code