Repository navigation
Conversation
The main deployment's beta job and the Stage 12 comparison path's staging deployment now pass promote_entrypoint: true, as production deployments do. Each staging deployment therefore moves the staging service's stable URL to the revision it tested, runs the same stable-URL checks as production, restores the previous revision if they fail, and then deletes the staging service's older revisions except the promoted one and the one it replaced. The new rule sim.deploy.staging-promotes-tested-revision requires it: a test reads every workflow, finds each job that runs the reusable deployment for staging, and fails unless it passes promote_entrypoint: true. Its proof fixtures are the beta job before and after this change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…build The beta environment does not restrict which branch a run may come from, so a manual run of either deployment workflow from a branch other than main now moves the staging stable URL to that branch's build until the next deployment from main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The prod deployment needs the whole beta deployment, which now includes the revision clean-up that runs after a staging promotion, so a failed staging clean-up also stops the production deployment. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e staging clean-up The repository README already says the prod deployment starts only after beta's revision clean-up succeeds; the entrypoint's DEPLOYMENT.md listed the beta jobs prod waits for without the clean-up job. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The v2 household functions take one household in the Public API's situation shape, with optional axes, and one to ten policies, so a baseline and its reform are calculated in one call. The request names the PolicyEngine.py bundle it expects, whether to add missing variables (as the Public API's /calculate-full route does), and an optional SPM selection whose omission is kept distinct from an empty choice. A household keeps its caller's key order through validation and transport, at the top level and in each group, because the Public API walks a household in that order and the order of its input errors, warnings and values follows it. The result carries each policy's calculated household, warnings and SPM receipt, the applied SPM selection and the bundle provenance; a failure carries a typed error whose messages and input errors match the Public API's error responses. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Schema version 2 of the v2 version manifest records, for each country a worker application serves, whether it is economy-capable (it names a single-simulation worker) and which function calculates its households, and the validation receipt names an invocation for each of those functions. The Simulation Entrypoint's comparison adapter now accepts only a country the manifest marks as economy-capable, so the report coordinator never receives a report for a country that only calculates households. Deployed and rollback revisions read schema version 1 and reject unknown fields, so the publisher writes schema version 2 under a new key and keeps writing the schema version 1 forms (with region datasets, without them, and without cache releases) under the existing keys whenever schema version 1 can describe the manifest. Current readers use the schema version 2 document while the older keys hold its schema version 1 forms, or, for a manifest schema version 1 cannot describe, unless the older keys hold a later validation; otherwise they read the older keys as before, as economy-capable countries without household functions. Code released before schema version 2 that publishes after a rollback therefore leaves no stale document behind, and the next publish starts from what it wrote. The publisher records every bundle country as economy-capable. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The v2 household functions prepare a household exactly as the Public API's household calculation does before calculating it: /calculate-full adds every missing yearly, monthly and eternal variable for the year of the first age entered for "you"; deprecated inputs are dropped, including axes that vary them, with the Public API's warning text; unknown entity groups, variables, variables on the wrong entity, axis variables and policy parameters are reported in the order the household was sent, with the Public API's error types and messages; and the requested values are the null values, or with axes every value of a known variable, in document order. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A US household's SPM selection is merged over the installed bundle's certified defaults with the Public API's rules and error codes: settings for any other country, or for a US model bundle without canonical SPM, are unsupported; a model that can run canonical SPM without a certified configuration fails closed; a forecast hash the bundle lacks is an invalid setting from a request but an unavailable configuration from a saved household; and an unknown scenario, county vintage or area is reported with the Public API's code and message. After each calculation, the country model's SPM receipt is reduced to the compact public receipt and checked against the resolved selection. SPM errors that end a calculation are recognized through wrapped causes, as the Public API recognizes them. The executor's SPM module now exposes the certified forecast it already loads once per process. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A v2 household function call is measured as one operation that covers the whole call, with nested spans for loading the country model, preparing the household, and calculating it under each policy. The stage plan lists those names so the household functions open spans only from registered stages. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
calculate_household runs one household request: it checks the request names the installed bundle, resolves the SPM selection, prepares the household once, then builds a simulation and calculates the requested values for each policy in order. It returns each policy's calculated household, warnings and SPM receipt with the applied SPM selection and bundle provenance, or a typed failure. Each step follows the Public API's household calculation: reform values are converted to each parameter's value type, values are written as its country module writes them, a value that cannot be calculated is null (one null per point, with a warning, when the household has axes), and an SPM error ends the calculation only for a chosen measurement or a configuration the build cannot certify. Failures carry the Public API's messages: an invalid household payload, unrecognized inputs, an SPM error, or an error calculating the household under a policy. Country models are loaded once per process. The tests calculate real US and UK households, including US households with axes and with every missing variable added. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… app Each function takes a household request, calculates it with the executor's household calculation and returns the result or typed failure as JSON. It continues the caller's trace through the keyword-only observability context and measures the call as one v2 household operation. The functions run in their own image: the CA store, the locked packages and the source, without the bundle's datasets or the Stage 12 cache, so neither the image build nor the functions use a secret. Each reserves 2 CPUs and 4 GiB, may use up to 16 GiB for large households with axes, times out after 900 seconds, is not retried, and runs at most 20 containers. The other v2 images keep their layers and order. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nifest After the country validation functions, release validation calls each deployed household function with a one-adult, current-law household and requires a successful calculation with the deployed bundle, reported by that function, with a number for the household's net income. The release record keeps each household invocation ID, and the manifest publisher records a country's household_callable only when the record shows its function was validated. A household function that fails validation stops the release, as a failed country validation already does. The validation household and its check live in the executor package, so the pre-merge image check can calculate the same household inside the household image. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The image check now also runs a v2 image smoke. It builds the report coordinator, UK worker and household images the v2 application deploys, and the US worker image without its last layer, the Stage 12 cache, which only a deployment can fetch: the deployment's precompute writes the cache, and the image build reads it with the deployment's Cloud Storage credential. That layer adds data files, not Python packages. In each report image the smoke imports the v2 application module, as Modal does before it runs a function, and the modules the coordinator, workers and validation functions import while handling a request. In the household image it imports the household entry points and calculates the release validation household for each country, which shows the image calculates without datasets. The smoke functions use no secret. Modal builds the smoke's images together. The job's timeout rises from 45 to 90 minutes, because after a relock both the executor smoke and the v2 smoke download certified datasets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A household's SPM receipt that the installed country model reports in a form that cannot be certified now fails with the Public API's reason, checked in its order: the forecast hash, scenario and geography kind are all required before they are compared with the selection, then the years mapping, the runtime versions and the forecast ID. The contract's receipt model words its year and metro-area errors as the Public API's model does, and a receipt that is not an object, or whose years are not a mapping, is reported the same way. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…'s codes The request's spm field now carries the caller's SPM settings as any JSON value, and the household function checks them as the Public API's routes do: settings for a country other than the US are unsupported, an explicit null for the US is invalid, and malformed settings are invalid with the Public API's message, before the bundle's certification is read. A metro selection needs an area and any other kind accepts none, judged on the settings as sent, as the Public API's model judges them. Before, a malformed selection or an explicit null failed the request's validation instead of returning a typed SPM failure. The request's documentation now says which parts of a saved household's calculation match the Public API's stored-household route (the calculated household, warnings, SPM receipt and SPM codes) and which do not (two error messages, which that route words with the household and policy IDs). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The household SPM code now loads the certified forecast with its own per-process loader instead of a wrapper added to the main path's SPM module, which returns to its state on main. The household path and the main path share no SPM code. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The household calculation module's documentation now lists each known difference from the Public API's household calculation, which were described in several places or not at all: how undefined numbers and dates are written, the UTC default year, an age given as one value under calculate-full, an explicit null axes, checking every policy's parameters first, the request routes' error wording, and requests the contract rejects. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A review asked whether a publish after code released before schema version 2 (as a deployed revert would run) could start from a stale schema version 2 document and drop what that code wrote. The schema version 2 reader already uses the document only while it is current; these tests pin that down for a publish: it keeps an application the older code redeployed without household functions, it takes the default from what the older code wrote, and older keys that a household-only schema version 2 publish left alone change nothing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A v2 worker version now returns the simulation callable of an economy-capable country, and raises LookupError for any other country. The Simulation Entrypoint's comparison backend stores that callable on the prepared report and sends it to the coordinator, instead of looking up the country's worker by matching and sending a value that schema version 2 allows to be null. The adapter already skips a country that is not economy-capable, so a prepared report always has one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… models Two real-model tests join the PR checks: a US household without a county leaves the SPM threshold uncalculated under the inherited county selection, fails with SPM_GEOGRAPHY_REQUIRED when the selection is chosen, and is calculated with a national receipt when the national kind is chosen; and the installed US and UK models calculate the household that release validation and the image check send. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A US household calculation resolved its SPM selection before the model-load span opened, and that resolution imports the US model, so a cold container's model load was measured in none of the household stages. The country model now loads first, in its own span, and the SPM selection is resolved while the household is prepared, as the Public API resolves it while preparing a calculation. A test checks both, and that a saved household's settings are resolved as saved. The module's list of differences from the Public API now says that a failure under any one policy returns one failure for the whole request. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…eholds The contract's SPM receipt model is shared with the main path, so it returns to its wording on main. The household SPM code now translates that model's year and metro-area errors into the Public API's wording when it reports a receipt it cannot certify, so household messages still match the Public API and nothing the main path runs changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… limits The tests' older-publisher documents now carry only the fields those publishers wrote: no region datasets under the keys that predate them. Two tests join them: the fixtures hold only released fields, and a publish refuses an unreadable schema version 2 document. The migration document now says what a rollback to code released before schema version 2 costs once current code publishes again: the manifest names no household functions for versions published before the rollback until each is published again, and it loses what only the schema version 2 document held. It also says that current readers do not read a publish by code released before cache releases, so a rollback that far needs the newer keys deleted first; the region dataset readers on main already behave this way. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
anth-volk
force-pushed
the
v2plan/1b-107-result-tables
branch
from
October 27, 2026 21:27
ea5272c to
2715b51
Compare
…s' into v2plan/2b-203-household-submit-poll
… into v2plan/2b-203-household-submit-poll # Conflicts: # changelog_entry.yaml # docs/generated/rules.md # projects/policyengine-simulation-entry/tests/test_deployment_assets.py
A simulation gains options: whatever else changes what it calculates, such as a household's axes, stored as a JSON object and empty unless set (revision 0005). HouseholdCalculationStore.find_or_create_simulation returns the oldest household simulation with the same country, household, policy, dynamic and options, compared by value, or creates it, so a household calculation submitted again reuses its simulation and run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A household output now keeps the calculation's warnings, in order, the complete SPM selection it applied (spm_config), its SPM receipt (spm_provenance) and the PolicyEngine.py bundle it ran with, each document null when it does not apply. They are written in the transaction that marks the run succeeded and read back unchanged; revision 0005 adds the columns. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
RunError gains an optional detail, a JSON object stored with the failure (error_detail on a simulation run, comparison_error_detail on a comparison step) for the run's reader, such as the inputs a household calculation rejected. Its message still carries no user data, and the detail is never logged. Only a failed run or step may hold one (revision 0005). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Household calls now have a result recorder. Each request names a policy by its run, so each result maps back to the run it computes: a successful outcome stores each run's calculated household with its warnings, SPM receipt, the applied SPM selection and the bundle, in the transaction that marks the runs succeeded. A typed failure, such as inputs the country model does not know, fails the runs with household_calculation_failed; its message names only the failure's code, and the household error document is the runs' error detail. A recorder's validate signals such a failure with CalculationFailedError, which run recording records instead of an invalid result. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
HouseholdCalculationStore starts or reuses a calculation's run, as RunStore does, and read_calculation returns it as its reader sees it: the run's status, timings, error and error detail, its simulation, and, once it succeeded, the computed household. An economy run reads as none. The tests include a calculation left dispatching: it is failed as abandoned after ten minutes and submitting it again starts its second attempt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
POST /v2/household-calculations records a household calculation (one
household under one policy, with its options, for a catalog version and
year) and starts its Modal call; GET /v2/household-calculations/{id}
returns its status and, once it ended, its household with its warnings, the
applied SPM selection, the SPM receipt and the bundle, or its error.
The Public API sends the household in the situation shape with its saved
SPM choice and the policy's parameter values; the database checks the
household, policy and catalog version exist. The calculation finds or
creates its simulation and reuses its run while unfinished or once it
succeeded, unless forced. The household function and bundle come from the
v2 version manifest for the calculation's PolicyEngine.py version, before
anything is written, and a pending run is dispatched by whichever
submitter claims it. A version or country without a household function, or
an unknown household, policy or catalog version, gets 400; an unreachable
manifest or database, or a service without the database or the v2 Modal
environment, gets 503.
Tests cover a successful call, a failed Modal call, and a calculation left
dispatching, which the safety check fails so it can be submitted again.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… step calculate_household_us and calculate_household_uk take the simulation runs sim started the call for as an optional second argument. Given them, the function's last step, once the calculation and its telemetry have finished, starts report_call_ended with the call ID and those runs, whether the calculation returned or raised; a pre-empted call reports nothing, since Modal runs it again under the same ID. Release validation and the image check pass no runs, and nothing is reported. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
HouseholdCalculationStore creates household reports and their runs, and read_report returns a household report with one of its report runs (the newest, unless one is named) and that run's baseline and reform runs as household calculations, each with its household once it succeeded. A report with only a baseline has no reform, a report before its first run has neither, and an economy report, or another report's run, reads as none. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…oint
POST /v2/household-reports creates a household report (the household
under a baseline and an optional reform, for a year) and starts its first
run; POST /v2/household-reports/{id}/runs starts another run of it, with the
report's own household and policies (400 otherwise); GET
/v2/household-reports/{id} returns it with its newest run and that run's two
calculations. A report run has failed when either calculation failed and
succeeded when both did.
Each report run joins a run of each simulation, reused as any calculation's
run is, and one Modal call computes the runs still pending, so a new
report's two households are calculated together. When another submitter
claimed one of them first, that submitter's call computes it, and this one
starts a call for the rest.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
After a staging deployment promotes its revision, with the v2 application deployed, the staging_household_test job submits a US household calculation to the staging stable URL, polls until it succeeds or fails within ten minutes, and reads the result back. It runs after promotion because the household function reports the call's end to the stable URL; a failure fails the deployment run, so production does not deploy. The calculation refers to rows the Public API owns, so the test reads the staging Public API's US catalog version for the deployed PolicyEngine.py version (or its current one) and stores a one-person household there; the new beta environment variable PUBLIC_API_URL names that service. The test lives in authenticated_tests and is skipped by every other run of them. The deployment guide no longer says staging does not promote its revision. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A household outcome with no result for one of its call's runs used to raise a plain ValueError inside the success transaction, which run recording took for a database failure: nothing was recorded, the report was answered as retry-later, and every safety check read the same output again until Modal no longer held it. The writer now raises CalculationFailedError, and run recording fails the runs with invalid_result, as it does for an output that does not validate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The household routes passed an explicit "spm": null to the household function as a choice, labelled as the saved household's, which the function rejects for a US household. The household functions' contract reads a saved null as no choice, so the request now leaves it out and the bundle's certified defaults apply, as when the field is omitted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Creating a household report inserted the report before starting its runs, so a catalog version the database refused answered 400 but left a stored report with no run, whose ID the caller never received. The runs now start first, and the report and its report run are created only once they exist. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
run_dispatch no longer says no route starts calls. The household modules name the v1 run_simulation code directly instead of "the main path", which modal_calls uses for the entrypoint's own run path. The calculation request says what year means (the household's calculation year, part of the run's identity, while the household's own periods decide what is calculated) and that its PolicyEngine.py version must be the catalog version's. The deployment guide says that a v2 application deployed before the household functions took run IDs refuses them until it is redeployed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The in-memory store the household tests use reused any run that had not failed, while RunStore reuses a succeeded run only if it finished within the reuse window. It now applies the same window, and a test shows a calculation that succeeded longer ago runs again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rvice The staging household test stored a household without the net income it then asked for, so the succeeded run it left, reusable for 28 days, did not match the household's own content. The stored household now asks for the same value. The test also failed on the first 503, which the household routes answer while the database or the version manifest cannot be reached; it now waits the answer's Retry-After and asks again, within its ten-minute bound. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The household routes, their request models (and so the OpenAPI schema), the household service and the entrypoint guide said a succeeded calculation is reused until forced. RunStore reuses a succeeded run only within the reuse window, so a later submission runs again under a new calculation ID; every description now says so. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The check that a report's run names the report's own household and policies compared the submitted policies with the report's simulations already paired with them, so the same rule was stated twice. It now compares the report's policy IDs, in order, with the submitted ones, and each simulation's household with the submitted household; the tests are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ehold The staging household test gave its submission and its polling a ten-minute limit each; both now share one limit from the start of the test. It builds the household it calculates from the household it stores, so the two shapes cannot drift apart, and says that a submission retried after it was partly written may leave a pending run that nothing reuses. Tests also cover a retry that would pass the limit and a reform sent for a report of the baseline alone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
anth-volk
force-pushed
the
v2plan/2b-203-household-submit-poll
branch
from
October 27, 2026 22:20
9d0e884 to
2f0406e
Compare
This branch has not been 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 #956
What this changes
The Simulation Entrypoint now calculates and stores households on v2, through the v2 Modal household functions, and checks a household calculation end to end on every staging deployment. Nothing calls these routes yet; the Public API's
/v2/household-calculations(PolicyEngine/policyengine-api#4092, a draft that waits for this) and household reports will.POST /v2/household-calculationsrecords a calculation (one stored household under one policy, with its options such as axes, for a catalog version and year) as a simulation run and starts the household function's Modal call.GET /v2/household-calculations/{calculation_id}returns its status and, once it ended, the calculated household with its warnings, the SPM selection it applied (spm_config), its SPM receipt (spm_provenance) and the bundle, or its error. The same calculation submitted again reuses its run while it is unfinished or for 28 days after it succeeded, unless forced.POST /v2/household-reportscreates a report (a baseline and an optional reform) and starts its first run;POST /v2/household-reports/{report_id}/runsstarts another run of it;GET /v2/household-reports/{report_id}returns the newest run with both calculations. One Modal call computes the runs still pending, so a new report's two simulation runs share the call. A report's runs start before the report is created, so a refused reference leaves no report behind.spm; a saved null is no choice) and each policy's parameter values. The database checks that the household, policy and catalog version exist (400 otherwise). The household function and bundle come from the v2 version manifest for the calculation's PolicyEngine.py version, before anything is written (400 when there is none, 503 when the manifest cannot be read).report_call_endedwith them, whether the calculation returned or raised; a pre-empted call reports nothing, and Modal runs it again under the same call ID. A household result recorder stores each run's household with the call's success. A household function's typed failure (such as an input the country model does not know) fails the runs withhousehold_calculation_failed, with the household error document as the runs' error detail; an outcome missing one of its runs fails them asinvalid_result. The safety check covers calls that never report and runs leftdispatching.simulations.options; the household output's warnings,spm_config,spm_provenanceand bundle; anderror_detailon failed simulation runs and comparison steps.staging_household_testjob stores a one-person US household through the staging Public API, reads its catalog version, submits a forced calculation to the staging stable URL, polls until it succeeds or fails, and reads the result back, within ten minutes. It retries a 503 after itsRetry-Afterwait within that limit. A failure fails the deployment run, so production does not deploy.Tests
Run locally on the branch head, after rebuilding the branch on the rebased #951 (now on main):
uv run --frozen pytest tests/— 1047 passed (new: household recorder, service, routes, reports, workers, staging job wiring; cases for a successful call, a failed Modal call, a typed household failure, an outcome missing a run, and a calculation leftdispatchingthat the safety check fails and a resubmission runs again);SIMULATION_TEST_DATABASE_URL=... uv run --frozen pytest tests/— 210 passed, including the migration cycle withalembic check;The staging test itself runs only in the deployed staging job.
Environment variables
New:
PUBLIC_API_URL(read by thestaging_household_testjob asSIMULATION_STAGING_TEST_PUBLIC_API_URL): a new GitHub environment variable inbeta, the staging Public API's stable URL. It reaches the job through the job'senvironment: beta; both staging callers of the reusable workflow passsecrets: inherit. Not set yet: an operator step.SIMULATION_STAGING_TEST_BASE_URLfromdeploy_entrypoint.outputs.stable_url;SIMULATION_STAGING_TEST_POLICYENGINE_VERSIONfromprepare.outputs.policyengine_version;SIMULATION_ENTRYPOINT_TEST_AUTH_ISSUERand_AUDIENCEfrom thebetasecretsSIMULATION_ENTRYPOINT_AUTH_ISSUERand_AUDIENCE;SIMULATION_ENTRYPOINT_TEST_AUTH_CLIENT_IDand_CLIENT_SECRETfrom thebetasecrets of the same names (all present, and used by the existing deployed authentication tests);SIMULATION_STAGING_HOUSEHOLD_TESTis a literal1in the job.Reused, no new runtime variable:
SIMULATION_CALL_REPORT_MODAL_ENVIRONMENT: from the workflow inputmodal_environment, written into the Cloud Run environment by the deploy script; the household routes start calls and read the v2 version manifest in that Modal environment.SIMULATION_DATABASE_URL,MODAL_TOKEN_ID,MODAL_TOKEN_SECRET: Google Secret Manager secrets mounted with--set-secrets, named by thebeta/prodvariablesSIMULATION_DATABASE_URL_SECRET_NAME,MODAL_TOKEN_ID_SECRET_NAMEandMODAL_TOKEN_SECRET_SECRET_NAME.SIMULATION_DATABASE_URL_SECRET_NAMEis not set in either environment yet (an operator step of the earlier pull requests in this chain). Without the database or the Modal environment, the household routes answer 503.SIMULATION_ENTRY_URLandMODAL_IDENTITY_TOKENinreport_call_ended: wired by the call-report change below this one; the household functions read nothing new.Not verified: that sim's Modal token can spawn the v2 household functions and read the version manifest Dict in each Modal environment; that the deployed-test Auth0 client holds
simulation:submitandsimulation:readonce permissions are enforced (SIMULATION_ENTRYPOINT_ENFORCE_PERMISSIONSis unset inbeta, so today missing permissions are only logged); and that the staging Public API writes to the same database as staging sim, which the foreign keys need.Waits for
runtime.span(...), as main did for every other use of the removedpolicyengine_simulation_observability.scopesmodule.test_deployment_assets_promotion.py, and the rules registry names them there.PUBLIC_API_URLinbeta, and the database and Modal settings of the pull requests below this one.simulationschema's one Alembic chain. Migration pull requests in this chain merge one at a time; another open revision 0005 (such as the economy path's) is renumbered onto the new head by whichever merges second.A v2 application deployed before the household functions took run IDs (for an older PolicyEngine.py version) refuses them until it is redeployed; its calls fail as worker errors, recorded by the safety check.
CI: the PR description check passed on 2f0406e; no other run had finished when this was last updated.
🤖 Generated with Claude Code