PolicyEngine / PolicyEngine/policyengine-household-api

Extricate the UK into its own Modal app family, separate from the US/country-agnostic app

Open
#1,629 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
1
Forks
3
Avg merge
6h 34m
Merged PRs (30d)
8

Description

Motivation

Today one worker app serves all five countries and loads all five models at startup (~4 GB RAM; the bulk of the Modal memory snapshot). Releases ride a single train keyed to weekly US bumps, which is how the UK /calculate path stayed broken for seven months (policyengine-uk 2.43's Simulation rewrite, fixed in the fix/uk-calculate-new-simulation-wrapper branch) without any release gate noticing. The UK also increasingly needs country-specific code (the wrapper-style Simulation builder, Scenario-based reform application, decoded-enum handling), which the API layer now isolates behind country-keyed strategy functions — deployment should follow the same seam.

Proposal

Split into two Modal app families that share the same codebase and gateway:

  • UK app: serves /uk/* only; image contains policyengine-uk but not policyengine-us. Its own current/frontier channels and release cadence.
  • Standard app: serves the remaining countries; image drops policyengine-uk. (Scope shrinks further if #1630 lands first.)

Expected wins: much smaller images and snapshots per app (a UK worker no longer carries the US model, and vice versa), faster cold start and cheaper scale-out, per-country release blast radius, and UK-first validation in the UK release gate. The exact-version routing ambiguity (current and frontier sharing a UK pin makes version: "<uk version>" first-match to current) also disappears when each country has its own channel set.

What it requires

  1. Worker: make the served-country set env-configurable (filter COUNTRIES at startup) so one codebase builds both app flavors.
  2. Manifest schema v2: country → channel → app instead of channel → app with a package_versions dict; gateway resolve_app_for_request keys on the path's country segment first (it already receives country_id).
  3. Release automation: per-country release PRs / deploy workflows; country dimension in the deploy-staged matrix; modal_release config and the modal-images.md / modal-release-prs.md skills docs updated to match.
  4. Failover: mirror the split in the Cloud Run fallback workers and failover manifest.
  5. Docker publishing: image tag scheme grows a uk-<version> family alongside us-<version>.

Sequencing

Phase the migration: manifest schema v2 first (with a compatibility reader for v1), then the env-configurable worker, then gateway routing, then release workflows. Interim decision already made: the UK pin stays at its current value (2.88.18) rather than adding a weekly UK bump bot to the combined app.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing the manifest and gateway entry point resolve_app_for_request, then inspect the COUNTRIES startup configuration and the release automation named in the issue. Review modal_release, modal-images.md, modal-release-prs.md, the Cloud Run fallback workers, and the failover manifest. Done means UK and standard app families route and release independently with compatible manifest handling.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, python
Domain
backend, cloud, devops, release
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.