Skip to content

Route all analysis microdata loading through policyengine.py's managed path - #77

Merged
MaxGhenis merged 3 commits into
mainfrom
managed-microsimulation-path
Aug 2, 2026
Merged

Route all analysis microdata loading through policyengine.py's managed path#77
MaxGhenis merged 3 commits into
mainfrom
managed-microsimulation-path

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Standing rule (2026-08-01)

Analysis/population compute always goes through the latest released policyengine (>=5.0.1): pe.us.managed_microsimulation() / pe.uk.managed_microsimulation(), which return a bundle-pinned country-package Microsimulation with the same MicroSeries interface and provenance on sim.policyengine_bundle. Directly-imported country-package Microsimulation is deprecated for analysis (its default dataset can lag the certified bundle) but remains fine for engine development and tests — YAML tests, variable authoring, and household-level Simulation debugging are untouched.

What changed

The catalog rebuild (#61) already routed the core skills through the managed surface; this PR fixes the two remaining offenders, hardens the prose, and adds enforcement:

  • targets/claude/agents/dashboard/backend-builder.md — the last file teaching bare Microsimulation() for statewide impacts. Now: image installs policyengine[us]==LATEST (pins exactly-matched country model + certified bundle — verified against the 5.0.1 pins: policyengine-us==1.764.6, policyengine-core==3.30.0), run_statewide uses managed_microsimulation() and returns policyengine_bundle provenance, the snapshot function pre-caches the certified dataset in the image's HF cache, and UK microsim images get a HUGGING_FACE_TOKEN note (private dataset repo).
  • targets/claude/commands/new-tool.md — same Modal-template fixes; adds the managed-path rule for tools that need population-scale results.
  • skills/policyengine/SKILL.md — states the latest-release floor in Setup, documents sim.policyengine_bundle and the UK twin, hardens the deprecation note, clarifies that managed_microsimulation(reform=...) is how the country-package reform surface is reached in analysis.
  • targets/claude/agents/microsim-runner.md — local path pinned to latest (>=5.0.1).
  • tests/test_no_stale_references.py — new anti-rot pattern banning from policyengine_{us,uk} import ... Microsimulation across skills/targets/docs, so the deprecated pattern cannot silently return. The three deliberate deprecation notes carry <!-- stale-ok -->.

Verification

  • managed_microsimulation mechanics (keyword-only dataset=, kwargs forwarding to the country package, allow_unmanaged gate, policyengine_bundle stamping, hf_hub_download cache materialization) read from the policyengine.py 5.0.1 tag source, per the repo's verify-before-writing rule.
  • uv run pytest --ignore=tests/test_skill_examples.py — 69 passed.
  • python3 scripts/build_claude_wrapper.py smoke build — OK.

🤖 Generated with Claude Code

Round 2 — adversarial cross-review fixes

A sol (gpt-5.6-sol) adversarial review of the first round found two blockers, both fixed in the second commit:

  1. Live bare-country-package scaffolding survived round 1: skills/policyengine-tools/SKILL.md Pattern C installed policyengine-us==X.Y.Z for society-wide Modal workers, and targets/claude/agents/dashboard/dashboard-planner.md emitted policyengine_package: policyengine-us for a microsimulation endpoint (both ship in the dashboard-builder/app-development/complete bundles). Both now install policyengine[us]==X.Y.Z (>=5.0.1) and route population endpoints through pe.us.managed_microsimulation(); the planner's NJ-pattern prose stops teaching a bare policyengine-us pin.
  2. The anti-rot guard was too narrow: it only caught a same-line from policyengine_{us,uk} import ... Microsimulation. It now also catches submodule/whitespace variants, module-qualified policyengine_us.Microsimulation(...), and paren-wrapped multiline imports (whole-file pass); scans .ipynb; and a parametrized corpus (9 banned + 8 allowed spellings) pins its behavior. <!-- stale-ok --> semantics are documented (CONTRIBUTING + lint reason) to also cover explicitly-scoped engine-development examples; residual limits (aliased constructors, import *) are documented in the module docstring.

Round-2 nits fixed: new-tool's Pattern C label, backend-builder's simulation.py import-table row, microsim-runner's local-path summary, and the writing skill's installation example all name the top-level package / managed entry point. A repo-wide sweep for policyengine-{us,uk}==, uv add policyengine-{us,uk}, and pip install policyengine-{us,uk} returns nothing.

Additional verification: HUGGING_FACE_TOKEN confirmed against the policyengine 5.0.1 tag (src/policyengine/bundle.py:596 reads it with HF_TOKEN fallback; the provenance manifest reads HUGGING_FACE_TOKEN only — the note names the universally-honored variable). Tests: 86 passed. Wrapper smoke build: OK.

MaxGhenis and others added 3 commits August 1, 2026 13:41
…d path

Standing rule (2026-08-01): population/analysis compute always goes through
the latest released policyengine (>=5.0.1) — pe.us.managed_microsimulation()
/ pe.uk.managed_microsimulation() — never a directly-imported country-package
Microsimulation, whose default dataset can lag the certified bundle. Direct
country-package use remains fine for engine development and tests.

- backend-builder + new-tool Modal templates: install policyengine[us]==
  latest (pins country model + certified bundle), compute statewide impacts
  via managed_microsimulation, pre-cache the certified dataset in the image
  snapshot, surface sim.policyengine_bundle provenance; note the
  HUGGING_FACE_TOKEN requirement for UK microsim images
- policyengine skill: state the latest-release floor in Setup, document the
  policyengine_bundle provenance attribute and UK twin, harden the
  deprecation note
- microsim-runner: pin the local path to latest policyengine (>=5.0.1)
- anti-rot lint: ban `from policyengine_{us,uk} import ... Microsimulation`
  in skills/targets/docs so the deprecated pattern cannot return; deliberate
  deprecation notes carry <!-- stale-ok -->

managed_microsimulation behavior (kwargs forwarding, bundle pinning,
policyengine_bundle attribute, HF-cache materialization) verified against
the policyengine.py 5.0.1 tag source.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…m guard

Adversarial review (sol) of the first round found two blockers:

1. Live scaffolding still prescribed the bare country package for
   society-wide Modal work: the policyengine-tools skill's Pattern C
   image installed policyengine-us==X.Y.Z, and the dashboard planner
   emitted policyengine_package: policyengine-us for a microsimulation
   endpoint. Both now install the top-level policyengine[us]==X.Y.Z
   (>=5.0.1) and route population endpoints through
   pe.us.managed_microsimulation(); the planner's NJ-pattern prose stops
   teaching a bare policyengine-us pin.

2. The anti-rot guard caught only a same-line
   "from policyengine_{us,uk} import ... Microsimulation". It now also
   catches submodule/whitespace variants, module-qualified
   policyengine_us.Microsimulation(...) constructors, and paren-wrapped
   multiline imports (whole-file pass), scans .ipynb, and a parametrized
   corpus pins nine banned and eight allowed spellings. stale-ok is
   documented (CONTRIBUTING + lint reason) to also cover
   explicitly-scoped engine-development examples. Residual limits
   (aliased constructors, import *) are documented in the module
   docstring.

Nits from the same review: new-tool's Pattern C label, backend-builder's
simulation.py import table row, microsim-runner's local-path summary,
and the writing skill's installation example now all name the top-level
package / managed entry point.

Verified: HUGGING_FACE_TOKEN is read by policyengine 5.0.1
(src/policyengine/bundle.py:596, HF_TOKEN fallback; provenance manifest
reads HUGGING_FACE_TOKEN only). uv run pytest
--ignore=tests/test_skill_examples.py: 86 passed. Wrapper smoke build:
OK.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sol's round-2 verification confirmed blocker 1 closed but kept the guard
blocker open: backslash-continued imports (from policyengine_us import \
<newline> Microsimulation) evaded both the line pass and the paren pass.
The import guard now walks logical lines in a whole-file pass —
(?:[^\n\|backslash]|backslash-newline)* — so same-line and
backslash-continued forms match while a plain newline still terminates;
a word boundary after policyengine_(us|uk) keeps policyengine_us_data
and other sibling packages out. Corpus grows to 12 banned + 10 allowed
spellings (three backslash forms, a backslash-continued Simulation
import, and a policyengine_us_data boundary case). Residual limits are
re-documented: aliased constructors, import *, and dot-split qualified
constructors remain reviewer territory.

Round-2 nits: the tools skill names both MicroSeries spellings (.calc()
US / .calculate() UK); new-tool spells the extras as policyengine[us] /
policyengine[uk] instead of the invalid [us|uk]; microsim-runner's
local-path summary points at the managed pe.{us,uk} surfaces rather
than overstating managed_microsimulation (its flow uses
policyengine.core.Simulation + ensure_datasets); skills/README and the
plugin-maintenance skill now describe the broadened stale-ok semantics
and the maintenance skill's pattern summary includes the microsim
guard.

uv run pytest --ignore=tests/test_skill_examples.py: 91 passed.
Wrapper smoke build: OK.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@MaxGhenis
MaxGhenis merged commit 463ba4d into main Aug 2, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant