diff --git a/integration/modal_app.py b/integration/modal_app.py index a91851cf..18f6cd94 100644 --- a/integration/modal_app.py +++ b/integration/modal_app.py @@ -220,8 +220,18 @@ # policyengine's bundled data-release manifest certifies an exact # country-package version; a newer policyengine-us makes every US # (and via import, UK) call raise at import time. Keep this pin in - # sync with the manifest version reported by the certification error. - "policyengine-us==1.764.6", + # sync with the manifest version reported by the certification error + # (1.764.6) and with integration/pyproject.toml. PyPI no longer hosts + # 1.764.6, so it installs from the policyengine-us commit that set + # that version; a wheel built from this archive has the same package + # files as the PyPI wheel. Tarball URL, not git+, for the same reason + # as us-hank-model below. + "policyengine-us @ https://github.com/PolicyEngine/policyengine-us/archive/92e6052d3e057c4e03b955d01a7ee4e3c2fb3131.tar.gz", + # Unpinned upstream (policyengine-us 1.764.6 declares + # spm-calculator>=0.2.0, policyengine 4.x microdf_python>=1.2.1), so a + # rebuild would take newer releases than the image has run with. + "spm-calculator==0.3.1", + "microdf-python==1.3.0", # US HANK (hank_shock / hank_summary). Installed from GitHub as a # normal wheel — no data files or repo checkout needed at runtime; # the calibration is code. Cost profile: the first hank_shock call @@ -284,6 +294,21 @@ f"pip install -e {OBR_REPO} -e {BOE_REPO} -e {FRB_REPO} " f"-e {HOME}/macro/integration" ) + # Refresh the two CA lists that the server's outbound HTTPS (Hugging Face + # microdata downloads, PolicyEngine data fetches) verifies against: + # Debian's ca-certificates, read by urllib, aiohttp and hf-xet, and certifi, + # read by requests and httpx. The pip_install layer built on 2026-08-12 + # held certifi 2026.7.22, on a debian_slim base built before Debian + # released ca-certificates 20250419~deb12u2; both lists trusted the + # compromised eMudhra root "emSign ECC Root CA - G3" + # (https://emudhra.we-have-a-problem.com). + # The pip_install layer now rebuilds (its policyengine-us requirement + # changed), which would pull the current certifi on its own; these two + # explicit steps keep the fixed minimums enforced for any later rebuild, + # whatever the layers above resolve to, and refresh the Debian package + # regardless of how old Modal's cached debian_slim base layer is. + .apt_install("ca-certificates") + .pip_install("certifi>=2026.10.19") ) app = modal.App("policyengine-macro-mcp") diff --git a/integration/pyproject.toml b/integration/pyproject.toml index d411ed2e..32f8de55 100644 --- a/integration/pyproject.toml +++ b/integration/pyproject.toml @@ -58,8 +58,18 @@ models = [ "policyengine[models]>=4,<5", # policyengine's bundled data-release manifest certifies an exact # policyengine-us version; anything newer fails certification at import - # (every pe.* call raises). Keep in sync with the manifest pin. - "policyengine-us==1.764.6", + # (every pe.* call raises). Keep in sync with the manifest pin, 1.764.6. + # PyPI no longer hosts 1.764.6, so it installs from the policyengine-us + # commit that set that version (the repository has no release tags); a + # wheel built from this archive has the same package files as the PyPI + # wheel. It satisfies the policyengine-us==1.764.6 pin in [models]. + "policyengine-us @ https://github.com/PolicyEngine/policyengine-us/archive/92e6052d3e057c4e03b955d01a7ee4e3c2fb3131.tar.gz", + # policyengine-us 1.764.6 declares spm-calculator>=0.2.0 and policyengine + # 4.x declares microdf_python>=1.2.1, so a fresh install would take + # releases newer than the ones these models were run and certified with. + # Pin the versions the deployed image holds. + "spm-calculator==0.3.1", + "microdf-python==1.3.0", ] [project.scripts]