Repository navigation
Conversation
policyengine-us 1.764.6 was deleted from PyPI, so the hashed hosted lock can
no longer be installed: CI's hosted Python job fails at the lock install and
the Modal image, built from the same lock, cannot be rebuilt. No .py release
can restore it either, because .py 5.0.0-5.3.1 all pin the deleted version.
The hosted runtime now declares a single model dependency,
`policyengine[us]==6.4.1`. Its `us` extra pins policyengine-us 2.2.1,
policyengine-core 3.33.0 and spm-calculator 1.0.0, and the runtime derives
and enforces exactly those versions instead of pinning them directly. The
dataset moves to populace-us-2024-spm-20260915 (commit 8ab57ffc, sha256
6496cc43...), the US release that .py 6.4.1's bundle certifies. It is a
source-enrichment child of the previously reviewed Build P release: the same
tables and calibration plus `is_spm_independent_minor_role`, which
policyengine-us 2.x needs to calculate SPM thresholds. On Build P itself,
2.2.1 refuses `spm_unit_spm_threshold` ("SPM unit has no classified adult").
validate_manifests now requires the installed .py's bundle manifest to
certify the release ID, revision, dataset URI and SHA-256, manifest paths,
model version and every release file digest it records, including the
parent manifests. The release's own built-with Core (3.32.5) and build
runtime block are no longer the identity, and the build manifest's
exported-household count is checked only when the .py-certified build
records one. A dataset or tuple the pinned .py does not certify is refused.
verify_hosted_runtime.py, which also runs during the Modal image build, now
binds the spm-calculator 1.0.0 and policyengine-us 2.2.1 SPM APIs. The old
spm_calculator.forecast, spm_calculator.geoadj and spm_unit variable modules
no longer exist.
Real-data evidence comes from a local run of the hosted calculation path on
the certified H5 under this exact tuple: `spm_unit_spm_threshold` was $3.888T
weighted over 59,900 SPM units, `ca_income_tax` was $121.198B, a
national -> CA -> national sequence reproduced identical values, and peak
memory was about 1 GB. The production deploy workflow also runs a genuine
national and California calculation on the new backend before promotion.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The lookup page's catalog still listed policyengine-us 1.764.6 variables. Under the pinned .py 6.4.1 (policyengine-us 2.2.1), 22 of those names no longer exist and would be answered as unknown variables, among them `would_claim_wic`, which 2.x renamed `takes_up_wic_if_eligible`. 1,029 new variables were missing. The generator also constructed `Microsimulation()` with no dataset, which under 2.2.1 downloads the country package's default dataset rather than the reviewed one. It now requires the pinned runtime, verifies the reviewed H5's SHA-256 (downloading the certified manifests and H5 at the pinned revision, or reusing a local copy via --dataset-file), builds the catalog from a simulation over that input, and records the release and package versions it used. The regenerated catalog lists 6,167 variables, exactly the pinned model's set; a test fails when they drift apart. The only other dashboard file naming removed variables is public/model-coverage.json, a labelled snapshot of policyengine-us 1.755.1 that the coverage page attributes to that version, so it is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The root project's `microcosm` extra pinned policyengine-us 1.764.6, which is no longer on PyPI, so its environment could not be built. It also paired that model with the Build P release, which policyengine-us 2.x cannot use for SPM thresholds. The harness now declares the same single model dependency as the hosted runtime, `policyengine[us]==6.4.1`, and evaluates the release that .py certifies, populace-us-2024-spm-20260915: Build P's tables, weights and calibration diagnostics plus `is_spm_independent_minor_role`. Results report "policyengine[us]==6.4.1" as their model version. A test keeps the harness and the hosted runtime on the same .py-certified pair, and the guard test now also fails if a bare policyengine-us or policyengine-core pin reappears in pyproject.toml, or if uv.lock resolves a different tuple from the one .py pins. policyengine-us 2.2.1 requires pandas 3, so the extra's pandas bound moves from <3 to >=3,<4. uv.lock was regenerated with uv 0.12, which also writes lockfile revision 5. The full Chronicle evaluation has not been re-run on the new pair; the integration docs say so. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
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.
Fixes #221
Summary
policyengine-us==1.764.6was deleted from PyPI. Since then the hosted runtime's hashed lock and the root evaluation project'smicrocosmextra can't be installed. CI's hosted Python job fails on every PR, and the Modal backend image can't be rebuilt. No .py release can bring the old pair back, because .py 5.0.0–5.3.1 all pin the deleted version.This PR makes .py (the PyPI package
policyengine) the only declared model dependency,policyengine[us]==6.4.1, for both the hosted runtime and the root harness. Itsusextra pins policyengine-us 2.2.1, policyengine-core 3.33.0 and spm-calculator 1.0.0, and those versions are derived and enforced rather than pinned directly.Both environments move to
populace-us-2024-spm-20260915, the US release .py 6.4.1 certifies:policyengine/populace-us8ab57ffc2ca41d8af631ff62ebbce95e966299f36496cc4393d4d3c6574f76eca231de5898c803b9067645591fd5c4d3e65aee84The new release is a source-enrichment of the Build P release served until now: Build P's tables, weights and calibration diagnostics, plus
is_spm_independent_minor_role.The rule, documented in
frontend/HOSTED_RUNTIME.mdand thebackend/requirements.txtheader: upgrade by bumping .py; the dataset must be one that version of .py certifies.What changes
validate_runtime):usextra;hosted_release.json'spackagesblock and the installed versions to equal them.validate_manifests):runtimeblock.verify_hosted_runtime.pyruns during the Modal image build. Its SPM checks now bind the spm-calculator 1.0.0 and policyengine-us 2.2.1 APIs (the oldspm_calculator.forecast,.geoadjandspm_unit.*modules are gone). The new checks are:spm-rolling-2026-09-09).Microsimulation(), which under 2.2.1 downloads the country package's default dataset.would_claim_wic, which 2.x renamedtakes_up_wic_if_eligible.public/model-coverage.jsonalso names some removed variables, but it is a labelled snapshot of policyengine-us 1.755.1 that the coverage page attributes to that version, so it is unchanged.frontend/tests/test_model_dependency_pins.pyruns in CI. It fails if a barepolicyengine-us,policyengine-coreorspm-calculatorpin reappears inbackend/requirements.txtorpyproject.toml. It also asserts thepolicyengine[us]==6.4.1pin, and that both locks resolve exactly the tuple .py pins.overview.yamland the integration docs move to the same pair. Results reportpolicyengine[us]==6.4.1as their model version.microcosmextra's pandas bound moves to>=3,<4.uv.lockwas regenerated with uv 0.12, which also writes lockfile revision 5.Commits
Red runs used a venv with the .py 6.4.1 stack against the unchanged implementation. The old lock can no longer be installed, so no 1.764.6 environment exists to test against.
test_model_dependency_pins.py,test_hosted_release.py,test_modal_endpoint.pyandtest_hosted_runtime_verification.py. All failed for the intended reasons:certifying_packageand nopolicyengineentry inpackages;uv pip install --require-hashes✓,uv pip check✓,verify_hosted_runtime.py✓,pytest frontend/tests82 passed.python /root/scripts/verify_hosted_runtime.py, run locally in the image's/rootlayout with its environment variables ✓ (nothing deployed).backend/requirements.lockexists on PyPI (87/87).bun test603 pass,tsc --noEmit✓,next build✓.pytest440 passed, 1 skipped.would_claim_wicwas still listed).pytest frontend/tests86 passed,bun test603 pass,tsc✓,next build✓, rootpytest440 passed, 1 skipped.pyproject.tomlpin and theuv.locktuple.uv.lockwith all extras (uv sync --frozen --all-extras✓,uv pip check✓):pytest443 passed. The previously skippedhuggingface_hubtest now runs.pytest frontend/tests88 passed.uv.lock100/100,requirements.lock87/87.Engine-compatibility evidence
Collected locally before the commits, on the real H5s (SHA-256 verified).
policyengine-us==1.764.6andpolicyengine-core==3.26.11.spm_unit_spm_threshold, the deploy workflow's national check:SPMInputError: SPM unit has no classified adult: supply source-backed independence or household head/spouse structure.would_claim_wictake-up is silently ignored, because the variable was renamed.is_spm_independent_minor_role.ecda19d9…,f503fc88…), and its calibration diagnostics file is the same (870449b4…).single_year_simulation_dataset+Microsimulation):spm_unit_spm_threshold: $3.888T weighted over 59,900 SPM units;ca_income_tax: $121.198B over 3,876 California tax units;==3.32.5and model>=2.0.0,<2.3(a publisher claim), and its build manifest has noruntimeblock or household count. That is why the identity is .py's certification, which pins core 3.33.0.Deploy implications
mainruns CI. When CI passes,deploy.ymlruns:calibration-diagnostics-<12-character-commit>, in themainenvironment. The image installs the new lock and runsverify_hosted_runtime.pywhile it builds.spm_unit_spm_thresholdcalculation and a Californiaca_income_taxcalculation on the new backend, plus the calibration smoke checks.mainfails CI, sodeploy.ymldoesn't run.vercel rollback PREVIOUS_DEPLOYMENTkeeps working as long as c630c91's backend app is retained. The workflow doesn't delete earlier apps.Environment variables on the deploy path
backend/modal_app.py,.github/workflows/deploy.ymland.github/scripts/deploy-dashboard.shread or declare these. This PR adds no new variables. The new engine packages read none at runtime on the hosted path; the ones they read are only used by tooling and download helpers. I checked names only, never values.MODAL_TOKEN_ID,MODAL_TOKEN_SECRETenv:of the configuration check, Modal deploy and backend-URL stepsmainenvironment.MICROCOSM_MODAL_KEY,MICROCOSM_MODAL_SECRETProductionenvironment secretsenv:→ smoke-test arguments, and Vercel--envfor the candidateVERCEL_TOKENProductionenvironment secretenv:of the configuration check, the Vercel candidate build and the promotionVERCEL_AUTOMATION_BYPASS_SECRETProductionenvironment secretenv:of the configuration check and the staged smoke steps →--vercel-bypass-secretHF_RELEASE_READ_TOKENenv:of the configuration check and the Vercel candidate build → Vercel runtimeHF_TOKEN; not given to ModalTELEMETRY_GCP_WIF_PROVIDER,TELEMETRY_GCP_DEPLOY_SERVICE_ACCOUNTProductionenvironment secretsgoogle-github-actions/authinputs (id-token: write)MICROCOSM_TELEMETRY_COLLECTOR_URLProductionenvironment variableenv:→ Vercel--envPROJECT_ID,READ_SECRET_NAMEProductionenvironment variablesTELEMETRY_GCP_PROJECT_IDandTELEMETRY_READ_SECRET_NAMEenv:of the collector-secret checkMODAL_ENVIRONMENT,VERCEL_CLI_VERSION,VERCEL_ORG_ID,VERCEL_PROJECT_IDenv:SOURCE_COMMIT,CALIBRATION_MODAL_APP_NAME,MICROCOSM_CALCULATION_URL,MICROCOSM_BACKEND_SOURCE_COMMIT,GITHUB_OUTPUTenv:CALIBRATION_SOURCE_COMMIT,CALIBRATION_SOURCE_TREE_SHA256,CALIBRATION_MODAL_APP_NAME,CALIBRATION_REQUIREMENTS,PYTHONPATHImage.envat build timeverify_hosted_runtime.pystep and at runtime. The function attaches no Modal secrets.POPULACE_HF_REPO,POPULACE_HF_REVISIONHF_HOME,HF_HUB_CACHE,XDG_CACHE_HOME,HF_HUB_DISABLE_XETThe Modal backend downloads the dataset anonymously, which works because
policyengine/populace-usis public.Overlap with in-flight PRs
This PR changes none of the files changed by #220, #219 or #216, so I expect no textual conflicts. #220 changes
frontend/lib/microcosm/production-release.test.tsanduse-microcosm.ts, which readhosted_release.jsonandvariable-catalog.json. This PR keeps both files' shape:packagesis still a flat name-to-version map, and the catalog still hasvariables.Open questions
model-coverage.jsonagainst policyengine-us 2.2.1? That needs Microcosm and policyengine-us checkouts and a live release API.🤖 Generated with Claude Code