diff --git a/PROGRESS.md b/PROGRESS.md index c6c9f696b..e528270f7 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -1,4 +1,276 @@ -# ACS predictor release join +# F1 portable worker identity — CI crawl fix + +## State + +Complete on 2026-09-05 on `f1-portable-worker-identity`, started on +2026-09-04 at `50c9232b7597bd1f47897a3132ed08894fc11d93`. Process memoization, +real session priming, explicit live opt-outs, and all requested verification +are complete. No GitHub network, push, new branch, or stash. +Final report, exact commands, direct exits, and per-file timing tables: +`/private/tmp/microcosm-pr871-ci-crawl/out.md`. + +## Done + +- Read the guide, prior journals, worker identity/bootstrap/launch, three live + stacked binding sites, and fixture caches. Used direct source tracing and + independent agent reviews; the GitNexus skill's tools were unavailable. +- Completed both unchanged baselines before production/test behavior edits: + identity selection 77 passed, 245 deselected, exit 0, 734.406s wall; + first 200 tests 200 passed, 122 deselected, exit 0, 2033.172s wall. + Source-order collection used `-p no:randomly`, then 122 explicit deselections; + the final selected node was + `test_primary_refuses_missing_universe_receipt_before_callback`. +- Repaired only ignored `.venv/bin/pytest` after its stale interpreter shebang + produced direct exit 127. Used the supplied synced Python 3.14.4 environment, + `uv run --no-sync`, and an external writable UV cache; no dependency sync. +- Committed fail-before memo regressions: 4 failed, 7 passed, 322 deselected; + exit 1; 30.073s wall. Implemented the memo keyed by raw lock argument and + both bound fit-control environment values, with an exported/documented clear + API and shared read-only semantic graph. Execution bindings clone the graph + so artifact mutation cannot poison subsequent identities. +- Primed real session identities for stacked-spine, H5, pool-tool, and the + indirectly reached spec-bundle suite. Removed redundant stacked/H5 caches. + Identity/source/runtime/backend/environment mutation tests explicitly opt out + and clear before/after; deliberate byte edits within a test clear between calls. + Preflight/fiscal-refresh tests already stub their live-binding paths. +- Added 14 regression cases covering memo reuse/reset, both environment keys, + invalid controls and locks, lock separation, artifact-copy isolation, real + session consistency, opted-out namespace-byte changes, and generator ordering. + Memo/session checks passed: 13 passed, 322 deselected; exit 0; 64.224s wall. +- Broader call-path audit found spec generation could precede function priming. + Committed a real ordering regression before the fixture fix: 1 failed, + 25 deselected; exit 1; 129.447s wall. Ordered priming before cached generation; + the same test then passed: 1 passed, 25 deselected; exit 0; 99.303s wall. +- Same post-fix identity selection: 90 passed, 245 deselected; exit 0; + 160.517s wall, a 4.58x speedup despite 13 added selection cases. +- Full stacked-spine file: 335 passed, 2,378 warnings, no failures/skips; + exit 0; 347.905s wall (5m 47.905s), pytest 337.74s. +- Ran actual CI process expansions from `--list GROUP:PROCESS`; `--procs` + returns process names, so the prompt's literal per-file loop was not valid. + Every process ran serially with exact CI file arguments and no cacheprovider. + An external observation-only plugin saved each file's counts and wall span. +- Initial us-qs:build before bundle priming: 1,368 passed, no skips; exit 0; + 626.070s wall. Reran the affected complete process after its final fix. +- Final CI process results (all exit 0): + + | Process | Files | Passed | Skipped | Wall seconds | + |---|---:|---:|---:|---:| + | us-qs:build | 29 | 1,369 | 0 | 654.966 | + | us-qs:frame | 5 | 84 | 8 | 111.252 | + | us-am:build | 59 | 1,899 | 1 | 855.001 | + | us-am:other-shards | 48 | 1,000 | 2 | 139.672 | + +- Final groups total 4,352 passed, 11 existing skips, no failures/errors across + 141 files. Skips cover eight optional Axiom cases, one opt-in 3.7 GB SIPP + audit, and two existing live data-loader tests. No skip was added by this fix. +- Ruff packages/tools passed (exit 0, 0.066s); all six changed Python files + passed format checking (exit 0, 0.021s). Diff whitespace passed (0.036s). +- Spec proof passed: 42,154/42,154 configuration fields, 41/41 inventories; + exit 0, 81.683s wall. No spec pins moved. Protected-file and AST verification + passed (exit 0, 0.080s): the uncached identity body, existing validators, + authenticator, probe, and launch policy are unchanged. The full + `worker_execution` subtree remains excluded from inventory digests. +- Independent reviews found no actionable defects. Engine-free compatibility + was reviewed from source; no engine-free test run is claimed. Python 3.13, + GitHub/Linux runners, wheels, unrelated CI groups, and certification were + not run in this local fix lane. All command receipts are in the report. + +## Next + +No implementation or requested local verification remains. No push. + +# Historical: Astra gate round 1 journal + +> The section below records the prior lane at `50c9232b`; its results and +> next steps are historical, not the current CI-crawl fix state. + +# F1 portable worker identity — Astra gate round 1 + +## State + +Complete on 2026-09-04 on `f1-portable-worker-identity`, starting at +`32ce6f518e8847647f23b3f6f11e4a8dc060ed01`. Both peer findings have committed +fail-before regressions and fixes. All eight requested suites passed (964 +tests); Ruff, formatting, and the spec-pin proof passed. No pins moved. +No GitHub network or push. Final report: +`/private/tmp/microcosm-pr871-astra-round1/out.md`. + +## Done + +- Read `CLAUDE.md`, the prior Sol journal, the worker identity/bootstrap, + pinned QRF launcher, stacked launch/binding, and relevant test sections. +- Confirmed the assigned branch and clean starting tree. +- Read the GitNexus debugging workflow; its tools are unavailable, so trace + execution directly from source and offline tests. +- Preserved the full `worker_execution` digest exclusion and all hard-boundary + files, including the seed-attested `puf_qrf_chain.py` launcher. +- No concrete `-o` path was supplied. Asked asynchronously and wrote the + report outside the repository at the stated default path, + `/private/tmp/microcosm-pr871-astra-round1/out.md`. + +- Reproduced finding 1 before any production edit: the fresh interpreter at + the real stacked/chain launch observes Torch autoload `1` before the worker + module loads (expected `0`); one test failed, direct exit 1. +- Reproduced finding 2 before any production edit: both source-tree and + inherited-prefix valid-header stale caches execute altered code in the + production identity probe; two cases failed, direct exit 1. Control children + prove that disabling bytecode writes alone still executes those caches. +- The recovered pytest script uses an obsolete interpreter shebang. Use + `uv run --no-sync python -m pytest` with a writable `UV_CACHE_DIR`; direct + pytest script attempts exited 4 before collection. No sync was needed. +- Recorded both failing commands and observations in the external report. + +- Fixed finding 1 by passing the semantic binding's forced overrides into + the stacked launch environment before Python starts. Retained the worker + bootstrap guard and corrected its comment; the pinned chain is untouched. +- The fresh-interpreter first-Torch-import regression now passes: 1 passed + in 58.11s, direct exit 0. Its child sees `0` while the parent retains `1`. + +- Fixed finding 2 using a shared launch context that forces an empty fresh + `PYTHONPYCACHEPREFIX` and `PYTHONDONTWRITEBYTECODE=1` in both probe and stacked + worker. The execution binding records the stable `{empty_pycache_dir}` + placeholder, and traces refuse unexpected namespace/stdlib bytecode paths. +- The cache reproduction now passes in both identity-probe and worker `-m` + modes across both cache locations: 4 passed in 22.62s, direct exit 0. + Probe/refusal/exception-cleanup checks also passed (5 passed in 23.95s). +- Extended the real stacked launch regression to check child Python cache + flags, replacement of an inherited prefix, and cleanup without parent + environment mutation. Added semantic tamper coverage for both cache controls. + +- Extended only the test validation fixtures to reuse pristine real worker + identities by lock/fit controls and return independent deep copies. The + stacked mutation helper compares against an independently obtained baseline; + H5 tests mutate artifacts only. Production factories and source/cache + mutation regressions remain uncached. Focused H5 checks: 2 passed, exit 0. +- Independent read-only review found no blocking issue in the startup/cache + fixes, regressions, hard boundaries, or fixture mutation separation. +- Final repository Ruff passed; changed-file format check passed (5 files). + Required release-preflight (42), fiscal-refresh (224), and source-blindness + (497) suites passed with direct exit 0 each. + +- Extended the same test-only reuse to the 11-case tail-control matrix: it + mutates parent constants, while the fresh worker's installed source and + startup environment stay identical. Independent review confirmed the real + resource extraction and digest comparison remain active. +- Interrupted the earlier focused worker run after discovering that matrix's + 22 redundant identities: direct exit 130, 58 passes before interruption; + this is not final evidence. Restarted the complete requested worker selector. +- Launch/binding integration passed (2 tests, exit 0). Required H5 (98), + inventory (15), coverage-tool (7), and imputation (4) suites passed, exit 0 + each. Ruff and changed-file formatting passed after the last test edit. +- Verified every forbidden path, docs/tools, and uv.lock is unchanged from + `32ce6f51`. + +- Standalone spec proof passed, direct exit 0: 42,154/42,154 configuration + fields and 41/41 inventory checks. No pins moved; the unchanged spec SHA is + `9db29b4d33424fbb21a83c63927c7de55ba9a333d631f6323935f67a496eee46`. +- The focused worker rerun completed with direct exit 0: 77 passed, 244 + deselected, 141 warnings in 866.48s. The real transfer-bank integration also + passed. All eight required suites total 964 passes, with no failures or skips. +- Finished the external report with both fail-before commands/observations, + fix SHAs (`b131afb7`, `4a575d7d`), cache-isolation rationale, exact final + verification commands/counts, no-pin proof, and deliberate scope exclusions. + +## Next + +- Local review of the committed fixes and external report. No implementation + or verification work remains for these two findings; no push was performed. + +# Historical: Sol gate round 1 journal + +> The section below is the prior round's handoff at `32ce6f51`. Its pending +> state and verification claims are preserved as historical evidence. + +# F1 portable worker identity — Sol gate round 1 + +## State + +In progress on 2026-09-04 on `f1-portable-worker-identity`, starting from +`b26708a1`. All four Sol findings have fail-before reproductions. The schema-9 +envelope, Torch backend-autoload, loaded-runtime/stdlib, and real-resource +fixes are implemented and focused green. Pin proof and full verification remain. + +## Done + +- Read `CLAUDE.md` and the F1 PR body/progress brief. +- Confirmed the requested branch and clean starting tree at `b26708a1`. +- Read the GitNexus debugging workflow. This workspace exposes no GitNexus + query/resource tools, so call-path analysis is being performed directly from + source and tests. +- Recorded the hard boundaries: keep the complete `worker_execution` subtree + out of spec-engine digests; do not edit graph interface/acceptance lock files; + refuse before side effects; keep tests offline; commit each coherent step. +- Recorded the required focused and final verification suites and the + requirement to report only commands actually run in `out.md`. +- Synced the locked all-package US/UK environment after directing uv's cache to + a sandbox-writable path; the unmodified command's two environment-specific + refusals and the successful command are recorded in `out.md`. +- Added fail-before coverage proving that schema 9 accepts missing/wrong + pipelines and routes other missing envelope sections around the common + validator; the focused result was 1 passed and 1 failed, exit 1. +- Added fail-before identity coverage proving that loaded-runtime and stdlib + mutations are unbound, a synthetic unapproved `torch.backends` provider is + accepted, and the real SOI interest-components resource is absent. The four + focused nodes failed as intended, exit 1. +- Added a fail-before launcher regression proving that an inherited/caller + `TORCH_DEVICE_BACKEND_AUTOLOAD=1` reaches the child unchanged. The focused + node failed as intended, exit 1. +- Replaced the prior unrelated `out.md` with the current round's reproduction + report; fix/pin/final-verification sections remain explicitly pending. +- Fixed the schema-9 bypass: schema 9 now has an explicit complete stacked + field set, traverses the same envelope classifier as schema 10, and does so + before any compatibility attestation is read or authenticated. +- The valid schema-9 metadata-restoration case and the seven-case malformed + envelope regression pass together (2 passed, exit 0). +- Forced `TORCH_DEVICE_BACKEND_AUTOLOAD=0` in both the authenticated semantic + environment and the worker module bootstrap, before its QRF/Torch import. +- Enumerated and bound selected `torch.backends` entry-point metadata, refused + provider distributions outside the installed-code closure before clean + worker import, and refused duplicate canonical distribution identities so a + colliding provider cannot evade RECORD hashing. +- Focused provider-refusal, duplicate-provider, launch-override, semantic + tamper, and legacy relocated-worker acceptance checks pass (exit 0 each). +- Replaced the two-file resource list with a fresh worker-import audit trace + using the same inherited startup search path as the real worker. The semantic + transitive-import digest now includes every opened + Microcosm namespace file, with bytecode canonicalized to source, portable + locators only, and ambiguous duplicate locators refused. +- The trace freezes and revalidates namespace roots, captures transient import + origins and successful pre-open file paths, refuses disappeared namespace + files, and rejects an empty or displaced worker trace. Its opened stdlib + paths supplement final `sys.modules` so transient stdlib imports stay bound. +- Resolved the loaded Python image through platform mapping with static and + sysconfig fallbacks, and bound its kind and byte digest without serializing + its path. The interpreter identity also binds the clean import's file-backed + stdlib source and extension bytes while excluding site packages. +- The mocked runtime-byte and stdlib-source mutation tests pass together; the + real SOI interest-components resource is observed and changes the resource + closure digest; and a real full identity constructs and validates with the + mapped `libpython3.14.dylib` (all exit 0). +- Kept worker identity schema v1 because it is the still-unreleased exact + schema introduced by this branch. Bumping it would churn authored spec + templates despite the requirement that spec-engine pins remain fixed; + structural validation now requires the added v1 fields. +- Restored `puf_qrf_chain.py` byte-for-byte after the first pin run proved that + editing its operational launcher also moves the QRF seed-kernel source + attestation. The worker bootstrap now owns the override, keeping the existing + seed protocol and compiled seed-map pins intact without re-pinning. +- Added bound-environment-keyed, deep-copied caches only to the stacked-spine + and H5 canonical test fixtures so parameterized/tiny-pool cases do not rebuild + one identical production identity apiece; production identity generation + remains uncached. The interrupted pre-cache final run had 9 passes before + exit 130 and is not treated as final evidence. +- Added the same narrowly scoped reuse to the inventory and coverage-tool test + modules: each module constructs one real binding and deep-copies it for + repeated report builds whose digests deliberately strip `worker_execution`. + This does not cache the production resolver or replace its first real check. + +## Next + +- Prove spec-engine pins remain fixed, run the complete requested verification + block, and finish `out.md` with exact commands, counts, and exit codes. + +# Historical: ACS predictor release join > **Historical note (2026-08-28).** This journal describes the > `acs-predictor-release-join` lane as of 2026-08-27. The branch has since diff --git a/changelog.d/f1-portable-worker-identity.fixed.md b/changelog.d/f1-portable-worker-identity.fixed.md new file mode 100644 index 000000000..7f681f40d --- /dev/null +++ b/changelog.d/f1-portable-worker-identity.fixed.md @@ -0,0 +1 @@ +Authenticate primary-QRF workers with a versioned semantic identity covering launcher and loaded-Python-runtime bytes, imported stdlib source/extensions, canonical virtual-environment fields, the static and clean-import-observed Microcosm closure, the exact lock and installed RECORD environment, disabled and authenticated Torch backend autoloading, canonical arguments, and fit controls, while retaining absolute launcher paths only as audit aliases so byte-identical worktrees can relocate safely. Legacy schema-9 gate-failed artifacts may relocate only through the scoring-only loader after the complete stacked manifest envelope validates and with an explicit plan-authorized attestation binding the sealed artifacts, published `b8819b3f` campaign token, environment/code identity, and exact two-field alias mismatch; simulation-ready and release loaders remain closed, and the candidate-26 deny-list remains independently enforced. Manifests and downstream receipts now surface the worker schemas, semantic digest, audit aliases, and attestation digest and purpose when applicable. diff --git a/docs/evidence/spec-engine/us-f0-coverage.json b/docs/evidence/spec-engine/us-f0-coverage.json index 5365a086a..3adf1102e 100644 --- a/docs/evidence/spec-engine/us-f0-coverage.json +++ b/docs/evidence/spec-engine/us-f0-coverage.json @@ -1321,7 +1321,7 @@ "expected": "complete execution-row and transition-authority object", "failures": [], "observed": { - "sha256": "503428f6e9d98f19ed3a6ada5bc9883ae44c1b5dc27f09e60b7ac98895a99bc0" + "sha256": "9a09b49855b3dc4c37ac86c3b91293b6944a50f4448354701b18db8f659ae121" }, "status": "covered" }, @@ -1338,12 +1338,12 @@ ], "expected": { "nodes": 38, - "sha256": "271a7bb8d0b3f97ff344e0b7e68184fa74738a6585c24fc8781793db669f388b" + "sha256": "40cd51ffdfe2e9d9d08d48c08e8ded9de1e4b134783bab05c4abc6ad5c72ca1e" }, "failures": [], "observed": { "nodes": 38, - "sha256": "271a7bb8d0b3f97ff344e0b7e68184fa74738a6585c24fc8781793db669f388b" + "sha256": "40cd51ffdfe2e9d9d08d48c08e8ded9de1e4b134783bab05c4abc6ad5c72ca1e" }, "status": "covered" }, @@ -1361,12 +1361,12 @@ ], "expected": { "producer_count": 38, - "sha256": "afebb6725373abf5b8dd4fdb77bf2814cb6fcc569cb606c0c30963a8f65c0bab" + "sha256": "b2b7dbd64db211088e85c94ad6ca1b942cb5e45683eb8c34ba9b664b5de64624" }, "failures": [], "observed": { "producer_count": 38, - "sha256": "afebb6725373abf5b8dd4fdb77bf2814cb6fcc569cb606c0c30963a8f65c0bab" + "sha256": "b2b7dbd64db211088e85c94ad6ca1b942cb5e45683eb8c34ba9b664b5de64624" }, "status": "covered" }, @@ -1840,11 +1840,11 @@ "legacy_adapter.stacked_checkpoint_static_components" ], "expected": { - "sha256": "e660a8ce42b69a39d29c5f0ec37264bc69d61b03f27adc386336ec8889531bb2" + "sha256": "9d4a9672a0f03039b1fe874b9fe21ed575be0d29f14afc396d03cdf5c809bdd2" }, "failures": [], "observed": { - "sha256": "e660a8ce42b69a39d29c5f0ec37264bc69d61b03f27adc386336ec8889531bb2" + "sha256": "9d4a9672a0f03039b1fe874b9fe21ed575be0d29f14afc396d03cdf5c809bdd2" }, "status": "covered" }, @@ -1887,7 +1887,7 @@ "alpha", "zeta" ], - "sha256": "b88f2d9c0f6f92c6cd81eb14d6b126afe59577b8bb392b394b2c6fbbafd195c5" + "sha256": "7176664c34039def5f43281a7735f792fe43de4ef0a6e7ca18f53d812b412d15" }, "failures": [], "observed": { @@ -1911,7 +1911,7 @@ "alpha", "zeta" ], - "sha256": "b88f2d9c0f6f92c6cd81eb14d6b126afe59577b8bb392b394b2c6fbbafd195c5" + "sha256": "7176664c34039def5f43281a7735f792fe43de4ef0a6e7ca18f53d812b412d15" }, "status": "covered" }, @@ -1975,7 +1975,7 @@ "take_up_contract", "us_qbi_reconciliation_contract" ], - "sha256": "04899daa491e8f089899c9df64cdb2ed44d61d11da2b4c733db6f20f38a1668a" + "sha256": "f22487c266bd24aba91ed526eed29d612875e4e78f7b4bdd93e10c9888801ecf" }, "status": "covered" }, @@ -2599,7 +2599,7 @@ "country": "us", "schema_id": "country_spec", "schema_version": 1, - "spec_sha256": "a6bc79878eb6f64637b9f3eceeea6cc2b050c0e5b8f9aca446179258940c44f2" + "spec_sha256": "9db29b4d33424fbb21a83c63927c7de55ba9a333d631f6323935f67a496eee46" } }, "report_schema_version": 3, @@ -2609,7 +2609,7 @@ "country": "us", "schema_id": "country_spec", "schema_version": 1, - "spec_sha256": "a6bc79878eb6f64637b9f3eceeea6cc2b050c0e5b8f9aca446179258940c44f2" + "spec_sha256": "9db29b4d33424fbb21a83c63927c7de55ba9a333d631f6323935f67a496eee46" }, "status": "pass" } diff --git a/docs/f1-portable-worker-identity/PROGRESS.md b/docs/f1-portable-worker-identity/PROGRESS.md new file mode 100644 index 000000000..e6f397a0f --- /dev/null +++ b/docs/f1-portable-worker-identity/PROGRESS.md @@ -0,0 +1,111 @@ +# F1 portable worker identity progress + +## State + +The portable worker identity, authenticated H5/scoring boundary, typed +specification mirrors, and downstream identity pins are implemented and +focused green; documentation and full verification are in progress on +`f1-portable-worker-identity` from base +`09abf2ad78e9af3c5314a4b303d42a75e30d49c4`. + +## Done + +- Read `CLAUDE.md`, the reproduced refusal in `_inputs/STOP.md`, and the F1 + specification in `_inputs/FIX-PLAN.md`. +- Confirmed that runner-owned root journals and task inputs will remain + untouched. +- Traced both authenticated late-DAG validations, every public scoring and + release loader, the deny-list layers, generated-spec mirrors, and downstream + release/scoring receipt propagation. +- Specified fail-before coverage for portable semantic equality, semantic + tamper refusal, the sealed STOP alias mismatch, and the explicit legacy + scoring-only attestation boundary. The focused portable-identity nodes fail + against the base implementation with two missing semantic identities and one + missing legacy mismatch helper (3 failed). +- Mapped the required version cascade: worker identity 1, primary config 5, + primary-QRF sidecar 2, resource semantics 2, registry 17, producer receipt + 4, transition authority 2, stacked authority 12, checkpoint materializer 13, + and pool manifest 10. +- Added a closed, versioned worker identity that binds interpreter bytes, + implementation/version/ABI/cache tag, canonical semantic `pyvenv.cfg`, the + exact approved lock, transitive source imports, verified installed RECORD + contents, canonical argv, and fit/predict controls. Absolute executable, + prefix, and raw argv aliases are retained separately for audit. +- Switched current primary-QRF resource authentication and checkpoint-resume + comparison to semantic projections while preserving full audit aliases in + receipts. Bumped the primary config, checkpoint sidecar, late registry, + producer receipt, transition authority, and stacked authority sources. +- Green evidence: Ruff passed for the three implementation files and the three + committed portable-identity regressions passed (`3 passed`). +- Added the explicit schema-9, gate-failed, scoring-only compatibility path. + Its plan-bound attestation seals the manifest and H5 digests, the exact + plan-published campaign identifier and campaign lock, the installed + transitive environment/code identity, recorded worker, semantic worker, and + the exact two legacy alias mismatches. Neither readiness/release loader has + an attestation parameter. +- Threaded the authenticated legacy context through both late-DAG validation + passes and reconstructed the frozen schema-4/config, registry-16, + receipt-3, transition-1, and authority-11 identities without weakening the + current validators. +- Published current worker-authentication evidence in manifests, diagnostics, + authenticated H5 capabilities, release receipts, and head-to-head scorer + identity/loader receipts. Added the candidate-only scorer CLI attestation + argument and direct propagation coverage. +- Kept deny-list refusal intact and made compatibility provenance impossible + to release-launder: schema 9, private legacy provenance, scoring-only receipt + fields, a changed returned manifest payload, and mismatched current receipts + each fail closed. +- Hardened the semantic identity implementation so source discovery follows + the worker module actually resolved by the interpreter, every source and + installed RECORD byte is re-read at authentication time, direct external + imports must resolve into the hashed RECORD, package initializers are part of + the transitive closure, and worker-startup package resources are hashed. +- Extended the regression surface with the 18-field semantic matrix, every + post-`argv[0]` position, exact legacy attestation/mismatch matrices, + release-laundering cases, scorer propagation/receipts, and the exact + non-mutating 12-household origin battery. +- Latest green evidence: four source/resource/scorer unit cases passed; four + end-to-end current/legacy H5 authentication and release cases passed; the + 12-case legacy attestation/laundering subset passed. Ruff check passed on the + edited Python boundary files. +- Replaced both constants-era worker templates with the closed portable + resolver algebra, made the typed projector resolve the alias-free semantic + receipt, and retained semantic worker fields in inventory identity while + excluding only `audit_aliases`. +- Updated the imputation and spine JSON schemas and checked-in US YAML mirrors + to primary config 5, registry/schedule 17, producer receipt 4, transition + authority 2, resource semantics 2, stacked authority 12, and checkpoint + materializer 13. JSON parsing, Ruff, bundle loading, and all four imputation + projector tests pass. +- Refreshed the schedule, stacked-authority, resource-semantics, checkpoint, + graph, and country-spec identity pins, plus their exact version assertions. + Regenerated coverage evidence is green at `42154/42154` configuration fields + and `41/41` inventory checks; its deterministic `--check` is also green. +- Green evidence for the refreshed spec identity contracts: `18 passed, 21 + skipped`, exit 0. The constants-era bundle generator was also attempted with + both `--check` and `--check --skip-validation`; each exits 1 before byte + comparison because this environment lacks the optional `policyengine-us` + distribution metadata. +- Documented the semantic/audit identity split, the explicit plan-authorized + schema-9 scoring exception, receipt fields, version cascade, independent + release deny-list, and the exact limits of the plan-defined authorization + tuple. Added the F1 changelog fragment. +- Closed the exact-k release-receipt propagation gap found in adversarial + review: the authenticated pool's worker schema/digest/audit receipt is now + required in `exact_k_ladder.pool` and therefore survives into both build and + release manifests. +- Corrected installed-wheel source discovery so only the `microcosm` namespace + roots are treated as internal code; neighboring site-packages remain in the + installed RECORD closure. The source and external-import closure now come + from one read rather than two potentially different filesystem snapshots. +- Preserved the nested release-verdict regression beneath the new authenticated + manifest-payload guard by rebinding only its synthetic capability; both + parameterized cases pass while real mutated manifests still fail earlier. +- Enforced absolute `sys_executable` and `sys_prefix` audit aliases while + retaining the unmodified raw `argv_template[0]` audit value. +- Recorded the F1 threat-model boundary: inherited Python startup/path hooks + remain trusted and are not added to the two specified semantic fit controls. + +## Next + +- Run focused, CI-group, and required repository checks. diff --git a/docs/us-multispine-operator-ordering.md b/docs/us-multispine-operator-ordering.md index 9a0054b80..8db0ba8b3 100644 --- a/docs/us-multispine-operator-ordering.md +++ b/docs/us-multispine-operator-ordering.md @@ -245,14 +245,16 @@ by_origin_battery The authority versions distinguish the two contracts. The primary-QRF root and target checkpoint schema remains version 6. The capital-gains tail manifest uses schema version 2 and binds its support contract and receipt. - The canonical stacked authority is version 11, the outer stacked checkpoint - materializer uses version 12, and the stacked pool stage checkpoint + The canonical stacked authority is version 12, the outer stacked checkpoint + materializer uses version 13, and the stacked pool stage checkpoint materializer uses version 7. The outer base identity binds primary-QRF version 6, the ACS universe and QBI reconciliation contracts, the tail schema and support contract, and - late-producer registry schema version 16, including the signed static and - derivation-mode semantics of every virtual DAG resource. The companion pool - manifest uses schema version 9. + late-producer registry schema version 17, including execution-receipt + contract 4, transition authority 2, and resource-semantics receipt 2. The + primary execution config is version 5, its portable worker identity is + version 1, and its checkpoint input sidecar is version 2. The companion pool + manifest uses schema version 10. Older outer authority or materializer payloads are stale; primary-QRF version 6 remains current. @@ -552,6 +554,63 @@ manifest; resume refuses a missing or different sidecar, including a same-row-count donor with changed bytes. This closes stale-bank reuse under a newly claimed outer route. +#### Portable primary-QRF `worker_execution` identity + +Worker identity schema v1 separates semantic authentication from launcher +aliases. `semantic_identity` binds the interpreter-launcher bytes, the exact +loaded Python runtime library (or the executable for a static build), and a +digest of the source and extension bytes for stdlib modules observed during or +present after a clean worker import. It also binds implementation, version and +ABI, cache tag, +canonical `pyvenv.cfg` fields, worker-module source, the statically resolved +Python closure plus every Microcosm namespace file opened by that clean import, +the exact approved `uv.lock`, installed-distribution/RECORD and combined +transitive environment/code digests, arguments after `argv[0]` with `argv[0]` +replaced by `{python_interpreter}`, and configured/resolved fit-job and +prediction-worker controls. `TORCH_DEVICE_BACKEND_AUTOLOAD=0` is a forced, +bound worker-bootstrap override applied before the QRF runtime can import +Torch. Before the clean import, identity construction enumerates +all installed `torch.backends` entry-point declarations, refuses duplicate +distribution identities or providers outside the selected RECORD closure, and +binds declarations belonging to selected distributions. Authentication +compares that payload and its +`semantic_identity_sha256`, so byte-identical interpreters reached through +different worktrees remain the same worker. `audit_aliases` records absolute +`sys_executable`, `sys_prefix`, and raw `argv_template_0`, but those aliases are +never compared for authentication. + +A schema-9 gate-failed pool receives no implicit alias exception. Its only +relocation path is the scoring-only loader with an operator-supplied +compatibility-attestation JSON binding the sealed manifest and H5 SHA-256s, the +exact plan-published campaign-tree token `b8819b3f`, campaign `uv.lock` SHA-256 +`27f47e385cfa35e2644a37410d1804b361ad9aee123577551c8421547bda65ee`, +installed transitive environment/code digest, recorded worker binding, +semantic identity, exact permitted mismatch set +`["argv_template[0]", "interpreter.executable"]`, and +`purpose: scoring_only`. Every semantic field must still equal the live +worker. The attestation's `plan_signature` is an exact plan-defined +authorization tuple (`gate`, `plan_sha256`, `prompt_sha256`, +`checklist_sha256`, and `evidence_sha256`) checked as data; this boundary does +not claim public-key or cryptographic signature verification. + +Current manifests, diagnostics, `release_manifest.json`, and scoring receipts +surface `worker_execution_authentication`: manifest, execution-config, and +worker schema versions, `semantic_identity_sha256`, and audit aliases. +Attested legacy scoring additionally surfaces +`compatibility_attestation_sha256` and `purpose: scoring_only`. Schema-9 or +scoring-only compatibility evidence cannot enter a simulation-ready or release +receipt. The scoring loader may authenticate a deny-listed pool for +diagnostics, but candidate-26 remains denied for release independently of this +relocation check. + +This F1 identity still assumes the interpreter's broader inherited startup path +is trusted. It now closes Torch backend autoloading, loaded-runtime and imported +stdlib bytes, and observed Microcosm import-time files, but does not additionally +authenticate `PYTHONPATH`, executable `.pth` startup hooks, or +`sitecustomize`/`usercustomize`. Hardening those remaining interpreter-startup +mechanisms would change the worker launch contract and is outside this +portability repair. + Every one of the 16 source producers consumes the following 16-requirement wrapper bundle `W`. It is added to the operator-specific kernel inventory in the table below, even where a kernel requirement names the same physical @@ -879,20 +938,20 @@ The lexically canonical waves have sizes `(1, 1, 17, 14, 3, 2)`: 5. Education; adult-care transfer; WIC transfer. 6. `source_finalizer` and education transfer. -Registry schema version 13 and execution-receipt schema version 3 bind the +Registry schema version 17 and execution-receipt contract version 4 bind the canonical input declarations, outputs, edges, waves, exact kind-specific virtual-resource bindings, content-hashed execution-row schema, and immutable -transition authority. The schedule SHA-256 is -`dbae9f945966a58592915780be78137e011d060271af6c933870a55db297baab`; +transition authority version 2. The schedule SHA-256 is +`e59c019d3d454eac99ac0ac209b6c5b6faaf9bdfcaeee18c36a25be19bf7da2f`; the full payload SHA-256 is -`95ee19cd1b4d1cf321a32910c234ebc460aa47f9cc30e03fa8560ea6ae5e2eb8`. +`7be038d34f228d66c12b53558fc5f30c93f1b376f1058c5e4fd7e7563a88d67f`. Reversing registry iteration produces those same bytes. The virtual-resource payload ledger is independently versioned: ACS-universe -config v2, primary execution config v3, source execution config v3, source +config v2, primary execution config v5, source execution config v3, source finalizer config v2, and transfer model config v3. Donor content, primary-checkpoint routing, source callback receipts, and transfer-bank routing -remain v1. The outer all-producer resource-semantics receipt is v1 and binds +remain v1. The outer all-producer resource-semantics receipt is v2 and binds both these static schemas and every dynamic derivation mode. ### Downstream hard-completeness audit @@ -911,7 +970,7 @@ and valid. Neither receipt authorizes an upstream null. | PUF raw predictor sources | Every filing-status, count, and income component is observed in its declared source universe. Raw WAGP/SEMP authority is present and agrees with mapped leaves; a cross-grain source collision is rejected. A null on any eligible member fails before coercion. | Structure supplies status/count; ACS-native or ASEC-carried earnings supply earnings; early transfer supplies interest, dividends, and gains. | No. ACS under-15 WAGP/SEMP blanks are an exact source-universe state, not transfer starvation; all other source nulls fail. | | PUF tax-unit features | Every clone-1 recipient has a finite feature vector. Post-aggregation NaN, `+inf`, and `-inf` are counted by named predictor and rejected before fitting; none is coerced or snapped to zero. | Universe-aware person sums plus tax-unit structural inputs. | No. Eligible member values must be complete; the only special case is an all-child unit whose numeric-zero predictor is explicitly owned and counted by the named universe-zero rule. | | Primary QRF banks and chain | Donor/recipient banks are immutable; target order and RNG prefix are contiguous; all targets complete; live recipient identity, source-universe receipt, and feature digest match before finalization. | The processed full PUF donor and strict recipient checkpoint initialized above. | No. Mutation or missing receipt invalidates the bank; it cannot resume under legacy semantics. | -| Outer pool checkpoint identity and resume | Primary-QRF schema v6, tail-manifest schema v2, late-registry schema v14/receipt schema v3, outer stacked materializer v10/authority v9, stacked pool-stage materializer v5, pool manifest schema v7, and the ACS-universe, QBI-mutation, tail-support, late-DAG, and signed virtual-resource-semantics identities must match exactly before any cached stage is discovered. The retiring legacy envelope remains manifest schema v4/materializer v3. | Fresh input pins, live stack receipt, scale controls, code identity, and all semantic contract identities. | No. An older stacked materializer or authority payload is stale; a self-consistent old receipt cannot reopen a checkpoint. Primary-QRF v6 remains current. | +| Outer pool checkpoint identity and resume | Primary-QRF schema v6, primary execution config v5, portable worker identity v1, tail-manifest schema v2, late-registry schema v17/receipt contract v4, outer stacked materializer v13/authority v12, stacked pool-stage materializer v7, pool manifest schema v10, and the ACS-universe, QBI-mutation, tail-support, late-DAG, and signed virtual-resource-semantics identities must match exactly before any cached stage is discovered. The retiring legacy envelope remains manifest schema v4/materializer v3. | Fresh input pins, live stack receipt, scale controls, code identity, and all semantic contract identities. | No. An older stacked materializer or authority payload is stale; a self-consistent old receipt cannot reopen a checkpoint. Primary-QRF v6 remains current. | | Clone-2 capital-gains tail | Each filing status requires as many eligible recipient households as selected q99.5 donors. Eligibility requires unique single-tax-unit PUF-detail lineage and half-weight capacity for the global maximum assigned donor weight. An adequate status assigns every selected donor once; a thin status skips as a whole with a named, counted `insufficient_support` receipt. | Completed clone-1 QRF output and full PUF tail donors. At 1%, `SINGLE` and `HEAD_OF_HOUSEHOLD` attach, `JOINT` and `SEPARATE` skip, and zero-requirement `SURVIVING_SPOUSE` is `not_applicable`. | No widening or partial attachment is permitted. All 22 AGI bands provide nearest-first fallback only inside a status. Universe-aware PUF recipients remain eligible, including explicitly receipted empty-universe tax units. | | Late producer DAG | Before any callback, all declared inputs are filled on their required scopes or carry an input-specific counted absence receipt; numeric inputs are finite. The exact derived order, readiness rows, once-only source finalizer, and bounded transfer receipts must validate. | ACS earnings-universe materialization, primary PUF/tail, 16 source producers, and 19 bounded transfer groups execute in six derived waves. | No. The refusing producer names the unfilled input and its declared producing stage. A cycle fails at import with its path. | | Late transfer completion | Every declared PUF-clone or ASEC source-producer cell is nonnull; all complementary recipients are filled; the allowed count for both unmodeled and residual rows is zero. | Forty-three PUF and 29 source targets, with two overlaps, supply the 70-target late surface. | No. A missing producer or recipient value is terminal at this boundary. | diff --git a/out.md b/out.md index a727ccd79..9d88868ec 100644 --- a/out.md +++ b/out.md @@ -1,119 +1,117 @@ -# Armenia country package final report (#814) - -Date: 2026-08-28 - -Branch: `armenia-country-package-814` - -## Outcome - -The Armenia package is complete as a schema-valid, spec-only, engine-free -greenfield contract. It is not represented as an executable build: the exact -`populace-us` artifact, Armenian facts, generated cell bindings, community -distribution, gate policy, and shared runtime kernels remain explicit -prerequisites. - -The closed `am/` inventory mirrors Belgium's six typed resources and five -generation-zero JSON projections. It declares: - -- a two-stage load of a to-be-authenticated public `populace-us` artifact and - target-derived marz assignment; every record remains a US donor support - record and is never described as Armenian microdata; -- a 2022-census-vintage community spine constrained to the assigned marz, with - 10 marzes plus Yerevan and 71 consolidated communities documented but no - invented code roster; -- eight Ledger-only, count/indicator calibration authoring contracts spanning - demography, household structure, consumption, labour, earnings, pensions, - and family benefits; -- real-resolver refusal of unexpanded multi-cell tables: Chronicle must generate - cell-pinned Ledger references and direct/pre-built candidate bindings before - runtime activation; -- wage/payment, raw-income diagnostic, and national-accounts facts outside the - solver manifest until their validation role or AMD-compatible pre-built bridge - is enforceable; -- greenfield aggregate-admin, per-family-fit, target-coverage, macro-realism, - support, weight-audit, ESS, and ratio gate declarations, plus active - release-blocking reference-coverage/support/output checks; and -- a public 2024 release contract for `populace_am_{year}.h5`, with ArmStat open - dissemination stated and exact ArmStat/donor licence text left as a mandatory - verification item. - -`HARVEST.md` has exactly one solver worklist row per live target-reference key, -plus separate deferred validation/amount, geography, source-authentication, and -external-oracle worklists. `NOTES.md` records the Belgium solver lessons, -permanent survey tax-benefit holdouts, the amount/currency boundary, -`populace#263/#265`, and the future Axiom-backed `rulespec-am` boundary. - -Package identity after review: - -- CountrySpec fingerprint: - `64f50fa39e68e9ba6c451e3a47a2f2adeaba5a5ccb147cb80297f942de433ca8` -- Typed spec SHA-256: - `659b6baf5ebbd71fb7786ec4c4d49df565b2bddabeb868a9385ed226c56880f9` - -## Verification - -All commands ran offline. The package-wide command used the exact lock-required -`policyengine-us==1.819.0` already present in the local uv cache, so the two -engine-only test files ran inside the same aggregate rather than failing for a -missing optional dependency. - -Exact requested package-wide command: +# F1 portable worker identity — Sol gate round 1 report + +Date: 2026-09-04 + +Branch: `f1-portable-worker-identity` + +## State + +Implementation is in progress. The four findings have been reproduced with +new regression tests on the `b26708a1` implementation. The only preceding +branch change was the committed progress-journal initialization. + +## Environment preparation + +- `uv sync --all-packages --locked --extra us --extra uk` exited 2 because the + runner exports `UV_FROZEN`, which `uv` rejects together with `--locked`. +- `env -u UV_FROZEN uv sync --all-packages --locked --extra us --extra uk` + exited 2 because the sandbox does not permit uv to initialize its default + cache under `/Users/maxghenis/.cache/uv`. +- `env -u UV_FROZEN UV_CACHE_DIR=/private/tmp/microcosm-uv-cache uv sync + --all-packages --locked --extra us --extra uk` exited 0: 125 packages + resolved and 103 packages checked. +- All pytest commands below likewise set the writable `UV_CACHE_DIR` and use + the required `uv run --no-sync` mode. + +## Finding 1 — schema-9 stacked-envelope bypass + +Reproduction test: +`test_scoring_loader_requires_complete_schema_nine_stacked_envelope`. + +Command: + +```sh +UV_CACHE_DIR=/private/tmp/microcosm-uv-cache uv run --no-sync pytest -q packages/microcosm-build/tests/test_us_multispine_pool_h5_io.py::test_scoring_loader_accepts_legacy_worker_alias_relocation_only packages/microcosm-build/tests/test_us_multispine_pool_h5_io.py::test_scoring_loader_requires_complete_schema_nine_stacked_envelope +``` + +Result: exit 1; 1 passed and 1 failed. The new regression showed that missing +and wrong `pipeline` values were accepted. Omitting `operator_order`, +`sampling`, `stack_manifest`, `geography_assignment`, or `stage_receipts` +reached later validators instead of the common stacked-envelope refusal. The +existing valid schema-9 path passed and restored both stacked frame-metadata +anchors. + +Fix: pending. + +Commit SHA: pending. + +## Finding 2 — unbound loaded runtime and stdlib + +Reproduction tests: +`test_primary_qrf_worker_identity_binds_loaded_runtime_bytes` and +`test_primary_qrf_worker_identity_binds_imported_stdlib_source`. + +The four identity/resource reproduction nodes were run together: + +```sh +UV_CACHE_DIR=/private/tmp/microcosm-uv-cache uv run --no-sync pytest -q packages/microcosm-build/tests/test_us_stacked_spine.py::test_primary_qrf_worker_identity_binds_loaded_runtime_bytes packages/microcosm-build/tests/test_us_stacked_spine.py::test_primary_qrf_worker_identity_binds_imported_stdlib_source packages/microcosm-build/tests/test_us_stacked_spine.py::test_worker_identity_refuses_unapproved_torch_backend_provider_before_import packages/microcosm-build/tests/test_us_stacked_spine.py::test_worker_transitive_source_identity_binds_actual_imported_package_resource +``` + +Result: exit 1; 4 failed. For finding 2, changing the temporary runtime +library left both absent `runtime_binary` fields equal (`None == None`), and +changing the temporary imported `argparse.py` left both absent +`stdlib_imports_sha256` fields equal. + +Fix: pending. + +Commit SHA: pending. + +## Finding 3 — Torch backend entry-point autoload + +Reproduction tests: +`test_worker_identity_refuses_unapproved_torch_backend_provider_before_import` +and `test_primary_qrf_worker_launch_forces_torch_backend_autoload_off`. + +The first ran in the four-node command above and failed because a synthetic, +unapproved distribution declaring a `torch.backends` entry point was accepted +(`DID NOT RAISE RuntimeError`). The launcher test ran separately: ```sh -UV_NO_SYNC=1 UV_PROJECT_ENVIRONMENT=/tmp/armenia-uv-env.ME3TCl UV_CACHE_DIR=/tmp/uv-cache-armenia-814 PYTHONPATH=packages/microcosm-build/src:packages/microcosm-calibrate/src:packages/microcosm-frame/src:packages/microcosm-fit/src:packages/microcosm-data/src:/Users/maxghenis/.cache/uv/archive-v0/ewqqbcYNhWejPQ-OfsFxl:/tmp/armenia-no-engine-site.vZ5Kv8:/Users/maxghenis/PolicyEngine/chronicle/.venv/lib/python3.14/site-packages uv run pytest packages/microcosm-build +UV_CACHE_DIR=/private/tmp/microcosm-uv-cache uv run --no-sync pytest -q packages/microcosm-build/tests/test_puf_qrf_chain.py::test_primary_qrf_worker_launch_forces_torch_backend_autoload_off ``` -Result: **6,556 passed, 45 skipped, 2,351 warnings, 0 failed** in 3,671.74 -seconds (1:01:11). The warnings are existing numerical, pandas copy/fragmentation, -and PolicyEngine-US runtime warnings; none is Armenia-specific. - -Additional checks: - -- Focused package/golden/compiler suite: - `uv run pytest packages/microcosm-build/tests/test_spec_only_country_packages.py packages/microcosm-build/tests/test_country_spec.py packages/microcosm-build/tests/test_spec_engine_country_bundles.py -p no:cacheprovider` - — **101 passed** in 29.82 seconds. -- Authoritative `shared-spec` CI group: - `python3 tools/ci_test_groups.py --list shared-spec | xargs uv run pytest -p no:cacheprovider` - — **1,334 passed, 42 skipped, 1 warning** in 418.20 seconds. -- `ruff check .` — **passed**. -- `python3 tools/ci_test_groups.py --verify` — **verification=ok**, 313 test - files tracked. -- `git diff --check` — **passed**. - -## Deviations from Belgium and why - -1. Armenia consumes a pre-built public US donor pool instead of native, - restricted SILC. No `support_spine.json` is present because the current - vocabulary describes raw ASEC pool construction, not an existing artifact. -2. Armenia is engine-free. No target, gate, or release file requires - `rulespec-am`; any later rules leg must use Frame's `RulesEngine` protocol - through the Axiom adapter. -3. Marz is target-assigned before community cloning. The clone factor is the - compile-safe minimum of one, not Belgium's 20: collision-avoiding fanout must - wait for the 71-to-11 roster and within-marz support evidence. -4. There is no incumbent, so parity/export/target-surface gates are absent. - National accounts back a deferred macro-realism band; CEQ and World Bank - estimates remain documentation-only band candidates until harvested. -5. The live solver manifest contains eight count/indicator series contracts, - not guessed scalar cells or AMD amount targets. Those series will expand to - the reviewed cell-level profile after Chronicle harvest; the eventual - 10–16-margin selection is not fabricated in this package. - -## Top five maintainer questions - -1. Which immutable `populace-us` revision/file, hash, licence, and column - inventory certify the donor input? -2. Which exact Statbank, ILCS, LFS, SRC, pension, and benefit tables/cells define - the 2024 profile, and what generated cell-reference/binding artifact owns - their fanout? -3. Which scale-free indicator or reviewed AMD-compatible pre-built bridge makes - donor consumption bands and any future amount rows conceptually comparable? -4. What ex-ante Armenia aggregate-fit, family-fit, macro-realism, ESS, and - weight-ratio thresholds—and which shared evaluators—activate the deferred - gate declarations? -5. What is the authoritative 2022 marz/community roster and assignment table, - and when will the shared geography/source-coverage runtimes land under - `populace#263/#265`? - -No network fetch, push, PR, artifact build, release, or publication was -performed. The repository-root `PROGRESS.md` was not touched. +Result: exit 1; 1 failed. With both the inherited and caller-supplied value set +to `1`, the child environment retained `TORCH_DEVICE_BACKEND_AUTOLOAD=1` +instead of forcing `0`. + +Fix: pending. + +Commit SHA: pending. + +## Finding 4 — incomplete import-time resource closure + +Reproduction test: +`test_worker_transitive_source_identity_binds_actual_imported_package_resource`. + +It ran in the four-node identity command above. Result: exit 1 as part of the +4-failure run. The manual two-file closure contained no row for +`soi_table_2_1_interest_components_ty2015.json` (`len(target_rows) == 0`). A +separate read-only audit-hook probe of a clean worker import found 24 Microcosm +non-code resources, including that asset. + +Fix: pending. + +Commit SHA: pending. + +## Pins moved + +Pending implementation and verification. + +## Final verification + +Pending. No final verification result is claimed yet. + +## Deliberately not done + +- No network access, push, branch creation, stash, artifact build, release, + publication, or graph-interface/acceptance-lock edit was performed. diff --git a/packages/microcosm-build/src/microcosm/build/spec_engine/imputation_semantics.py b/packages/microcosm-build/src/microcosm/build/spec_engine/imputation_semantics.py index ef6bbf106..0763a37ba 100644 --- a/packages/microcosm-build/src/microcosm/build/spec_engine/imputation_semantics.py +++ b/packages/microcosm-build/src/microcosm/build/spec_engine/imputation_semantics.py @@ -10,11 +10,8 @@ import hashlib import json -import os -import sys from collections.abc import Mapping, Sequence from copy import deepcopy -from pathlib import Path from .seeds import LEGACY_V1_PROTOCOL from .typed_closure import compile_producer_outputs @@ -265,59 +262,14 @@ def _worker_execution_template() -> dict[str, object]: "surface": "execution_profile", "resolve_as": "worker_execution", "template": { - "module": "microcosm.build.us_runtime.puf_qrf_worker", - "argv_template": [ - {"resolver_op": "sys_executable"}, - "-m", - "microcosm.build.us_runtime.puf_qrf_worker", - "--checkpoint-dir", - "{checkpoint_dir}", - "--target-index", - "{target_index}", - ], - "interpreter": { - "executable": {"resolver_op": "sys_executable"}, - "resolved_executable": {"resolver_op": "resolved_sys_executable"}, - "implementation": {"resolver_op": "python_implementation"}, - "cache_tag": {"resolver_op": "python_cache_tag"}, - "version": {"resolver_op": "python_version_triplet"}, + "schema_version": 1, + "semantic_identity": { + "resolver_op": "primary_qrf_worker_semantic_identity" }, - "environment": { - "policy": "inherit_parent_environment_with_bound_fit_controls", - "overrides": {}, - "semantic_controls": { - "POPULACE_FIT_N_JOBS": { - "configured": { - "resolver_op": "environment_value", - "name": "POPULACE_FIT_N_JOBS", - }, - "resolved": { - "resolver_op": "env_canonical_positive_int_or_default", - "name": "POPULACE_FIT_N_JOBS", - "default": -1, - }, - }, - "POPULACE_FIT_PREDICT_WORKERS": { - "configured": { - "resolver_op": "environment_value", - "name": "POPULACE_FIT_PREDICT_WORKERS", - }, - "resolved": { - "resolver_op": "env_positive_int_or_cpu_count", - "name": "POPULACE_FIT_PREDICT_WORKERS", - "fallback_minimum": 1, - }, - "resolution": { - "resolver_op": "env_or_cpu_count_resolution_label", - "name": "POPULACE_FIT_PREDICT_WORKERS", - }, - }, - }, - "bound_names": [ - "POPULACE_FIT_N_JOBS", - "POPULACE_FIT_PREDICT_WORKERS", - ], + "semantic_identity_sha256": { + "resolver_op": "primary_qrf_worker_semantic_identity_sha256" }, + "audit_aliases": {"resolver_op": "primary_qrf_worker_audit_aliases"}, }, } @@ -330,80 +282,21 @@ def _resolve_worker_execution(value: Mapping[str, object]) -> dict[str, object]: raise RuntimeError( "Primary-QRF worker template differs from the closed reviewed resolver." ) - fit_jobs_raw = os.environ.get("POPULACE_FIT_N_JOBS") - if fit_jobs_raw is None: - fit_jobs = -1 - else: - try: - fit_jobs = int(fit_jobs_raw) - except ValueError as error: - raise ValueError( - "POPULACE_FIT_N_JOBS must be a positive integer for the " - "primary-QRF worker binding." - ) from error - if fit_jobs < 1 or str(fit_jobs) != fit_jobs_raw: - raise ValueError( - "POPULACE_FIT_N_JOBS must be a canonical positive integer for " - "the primary-QRF worker binding." - ) - predict_workers_raw = os.environ.get("POPULACE_FIT_PREDICT_WORKERS") - if predict_workers_raw is None or not predict_workers_raw.strip(): - predict_workers = os.cpu_count() or 1 - predict_workers_source = "os_cpu_count_fallback" - else: - try: - predict_workers = int(predict_workers_raw) - except ValueError as error: - raise ValueError( - "POPULACE_FIT_PREDICT_WORKERS must be a positive integer for the " - "primary-QRF worker binding." - ) from error - if predict_workers < 1: - raise ValueError( - "POPULACE_FIT_PREDICT_WORKERS must be positive for the " - "primary-QRF worker binding." - ) - predict_workers_source = "environment_override" - executable = Path(sys.executable) - module = "microcosm.build.us_runtime.puf_qrf_worker" - return { - "module": module, - "argv_template": [ - str(executable), - "-m", - module, - "--checkpoint-dir", - "{checkpoint_dir}", - "--target-index", - "{target_index}", - ], - "interpreter": { - "executable": str(executable), - "resolved_executable": str(executable.resolve()), - "implementation": sys.implementation.name, - "cache_tag": sys.implementation.cache_tag, - "version": list(sys.version_info[:3]), - }, - "environment": { - "policy": "inherit_parent_environment_with_bound_fit_controls", - "overrides": {}, - "semantic_controls": { - "POPULACE_FIT_N_JOBS": { - "configured": fit_jobs_raw, - "resolved": fit_jobs, - }, - "POPULACE_FIT_PREDICT_WORKERS": { - "configured": predict_workers_raw, - "resolved": predict_workers, - "resolution": predict_workers_source, - }, - }, - "bound_names": [ - "POPULACE_FIT_N_JOBS", - "POPULACE_FIT_PREDICT_WORKERS", - ], - }, - } + from microcosm.build.us_runtime.worker_identity import ( + PRIMARY_QRF_WORKER_MODULE, + primary_qrf_worker_execution_binding, + primary_qrf_worker_semantic_projection, + ) + + resolved = primary_qrf_worker_semantic_projection( + primary_qrf_worker_execution_binding(), + boundary="typed primary-QRF worker resolution", + ) + if resolved["semantic_identity"]["worker_module"]["name"] != ( + PRIMARY_QRF_WORKER_MODULE + ): + raise RuntimeError("Primary-QRF worker module resolution drifted.") + return resolved def _compile_node_outputs( diff --git a/packages/microcosm-build/src/microcosm/build/spec_engine/inventory_coverage.py b/packages/microcosm-build/src/microcosm/build/spec_engine/inventory_coverage.py index 1c38f8357..a158ccfb5 100644 --- a/packages/microcosm-build/src/microcosm/build/spec_engine/inventory_coverage.py +++ b/packages/microcosm-build/src/microcosm/build/spec_engine/inventory_coverage.py @@ -348,14 +348,14 @@ EXPECTED_HASHES = { "acs_group_predictors": "a927bb7ecf3e84f54c93583ab79318654514ac546aefafba67da5285615fbd60", "acs_person_predictors": "878c788a6f037d7aca12b3586ea034eff04f3034ffa11935a736493042551f25", - "authority": "e660a8ce42b69a39d29c5f0ec37264bc69d61b03f27adc386336ec8889531bb2", + "authority": "9d4a9672a0f03039b1fe874b9fe21ed575be0d29f14afc396d03cdf5c809bdd2", "early_families": "4aa9f736fd76e83955477ad1667e58f48f264783f05bdc7f0102cd32d61323bd", - "full_checkpoint": "b88f2d9c0f6f92c6cd81eb14d6b126afe59577b8bb392b394b2c6fbbafd195c5", + "full_checkpoint": "7176664c34039def5f43281a7735f792fe43de4ef0a6e7ca18f53d812b412d15", "gap_fill_schedule": "1c31f9868f7884347cc19cf1ff65da43f950b9114941a715bab168246db414a7", - "graph_nodes": "271a7bb8d0b3f97ff344e0b7e68184fa74738a6585c24fc8781793db669f388b", + "graph_nodes": "40cd51ffdfe2e9d9d08d48c08e8ded9de1e4b134783bab05c4abc6ad5c72ca1e", "geography_assignment": "f49425ca8734ac559c73cf44f6458d86d3162a48956b98a27e6e758959361585", "late_families": "d91f9ff0eb52f43e7b6eed3d5c58c37abe1620c3a11021da15dae9c10e16d382", - "late_resource_semantics": "afebb6725373abf5b8dd4fdb77bf2814cb6fcc569cb606c0c30963a8f65c0bab", + "late_resource_semantics": "b2b7dbd64db211088e85c94ad6ca1b942cb5e45683eb8c34ba9b664b5de64624", "late_schedule": "e59c019d3d454eac99ac0ac209b6c5b6faaf9bdfcaeee18c36a25be19bf7da2f", "ownership": "5f64f0aac49e2313177564f71876bffc8c81b3ded4df701e70930e60e9c98356", "primary_tuples": "987b501c695e31f45521c4a178528f75ab3df22c09bc407b182213b2de99ee57", @@ -473,16 +473,23 @@ def _wire(value: FrozenValue) -> object: return thaw_json(value) +#: Subtrees that describe the machine a build ran on, never the spec. +_OPERATIONAL_KEYS = frozenset({"worker_execution", "audit_aliases"}) + + def _without_operational_bindings(value: object) -> object: - """Strip execution-profile subtrees before semantic digesting. - - ``worker_execution`` embeds the invoking interpreter path verbatim - (``sys.executable``), which spells itself differently between a script - (``.venv/bin/python``) and the pytest console script - (``.venv/bin/python3``) for the same interpreter. Execution profile is a - receipted operational surface, never semantic evidence, so inventory - digests are computed over the receipt with those subtrees removed. The - live generation-0 receipt itself is unchanged. + """Strip execution-profile subtrees before semantic inventory digesting. + + ``worker_execution`` is the primary-QRF worker's execution binding: its + semantic identity hashes the interpreter binary, ABI, ``pyvenv.cfg``, + the installed distributions' RECORD files, and the resolved fit + controls (CPU count included), and its audit aliases spell the + interpreter path. All of that authenticates an environment for replay + and legitimately differs between macOS and the Linux CI runners; none + of it is spec evidence. Inventory digests are therefore computed over + the receipt with the whole subtree removed, as they were before the + binding became portable, so the pinned digests hold on every platform. + The live generation-0 receipt itself is unchanged. """ if isinstance(value, Mapping): @@ -490,7 +497,7 @@ def _without_operational_bindings(value: object) -> object: return { key: _without_operational_bindings(item) for key, item in value.items() - if key != "worker_execution" and not (drop_self_hash and key == "sha256") + if key not in _OPERATIONAL_KEYS and not (drop_self_hash and key == "sha256") } if isinstance(value, list): return [_without_operational_bindings(item) for item in value] @@ -1695,9 +1702,7 @@ def add( "sha256": _operational_free_sha256(geography_assignment), "authority_roles": sorted(geography_authorities), "target_vintage": _mapping( - geography_authorities.get( - "congressional_district_vintage_crosswalk" - ), + geography_authorities.get("congressional_district_vintage_crosswalk"), "checkpoint geography crosswalk authority", ).get("target_vintage"), }, diff --git a/packages/microcosm-build/src/microcosm/build/spec_engine/schema/imputation.schema.json b/packages/microcosm-build/src/microcosm/build/spec_engine/schema/imputation.schema.json index 4a4a09a5a..be210f265 100644 --- a/packages/microcosm-build/src/microcosm/build/spec_engine/schema/imputation.schema.json +++ b/packages/microcosm-build/src/microcosm/build/spec_engine/schema/imputation.schema.json @@ -3280,264 +3280,60 @@ "additionalProperties": false, "properties": { "resolve_as": { - "type": "string" + "const": "worker_execution" }, "surface": { - "type": "string" + "const": "execution_profile" }, "template": { "type": "object", "additionalProperties": false, "properties": { - "argv_template": { - "type": "array", - "items": { - "anyOf": [ - { - "type": "object", - "additionalProperties": false, - "properties": { - "resolver_op": { - "const": "sys_executable" - } - }, - "required": [ - "resolver_op" - ] - }, - { - "type": "string" - } - ] - } + "schema_version": { + "const": 1 }, - "environment": { + "semantic_identity": { "type": "object", "additionalProperties": false, "properties": { - "bound_names": { - "type": "array", - "items": { - "type": "string" - } - }, - "overrides": { - "type": "object", - "additionalProperties": false, - "properties": {} - }, - "policy": { - "type": "string" - }, - "semantic_controls": { - "type": "object", - "additionalProperties": false, - "properties": { - "POPULACE_FIT_N_JOBS": { - "type": "object", - "additionalProperties": false, - "properties": { - "configured": { - "type": "object", - "additionalProperties": false, - "properties": { - "name": { - "const": "POPULACE_FIT_N_JOBS" - }, - "resolver_op": { - "const": "environment_value" - } - }, - "required": [ - "name", - "resolver_op" - ] - }, - "resolved": { - "type": "object", - "additionalProperties": false, - "properties": { - "default": { - "type": "integer" - }, - "name": { - "const": "POPULACE_FIT_N_JOBS" - }, - "resolver_op": { - "const": "env_canonical_positive_int_or_default" - } - }, - "required": [ - "default", - "name", - "resolver_op" - ] - } - }, - "required": [ - "configured", - "resolved" - ] - }, - "POPULACE_FIT_PREDICT_WORKERS": { - "type": "object", - "additionalProperties": false, - "properties": { - "configured": { - "type": "object", - "additionalProperties": false, - "properties": { - "name": { - "const": "POPULACE_FIT_PREDICT_WORKERS" - }, - "resolver_op": { - "const": "environment_value" - } - }, - "required": [ - "name", - "resolver_op" - ] - }, - "resolution": { - "type": "object", - "additionalProperties": false, - "properties": { - "name": { - "const": "POPULACE_FIT_PREDICT_WORKERS" - }, - "resolver_op": { - "const": "env_or_cpu_count_resolution_label" - } - }, - "required": [ - "name", - "resolver_op" - ] - }, - "resolved": { - "type": "object", - "additionalProperties": false, - "properties": { - "fallback_minimum": { - "type": "integer" - }, - "name": { - "const": "POPULACE_FIT_PREDICT_WORKERS" - }, - "resolver_op": { - "const": "env_positive_int_or_cpu_count" - } - }, - "required": [ - "fallback_minimum", - "name", - "resolver_op" - ] - } - }, - "required": [ - "configured", - "resolution", - "resolved" - ] - } - }, - "required": [ - "POPULACE_FIT_N_JOBS", - "POPULACE_FIT_PREDICT_WORKERS" - ] + "resolver_op": { + "const": "primary_qrf_worker_semantic_identity" } }, "required": [ - "bound_names", - "overrides", - "policy", - "semantic_controls" + "resolver_op" ] }, - "interpreter": { + "semantic_identity_sha256": { "type": "object", "additionalProperties": false, "properties": { - "cache_tag": { - "type": "object", - "additionalProperties": false, - "properties": { - "resolver_op": { - "const": "python_cache_tag" - } - }, - "required": [ - "resolver_op" - ] - }, - "executable": { - "type": "object", - "additionalProperties": false, - "properties": { - "resolver_op": { - "const": "sys_executable" - } - }, - "required": [ - "resolver_op" - ] - }, - "implementation": { - "type": "object", - "additionalProperties": false, - "properties": { - "resolver_op": { - "const": "python_implementation" - } - }, - "required": [ - "resolver_op" - ] - }, - "resolved_executable": { - "type": "object", - "additionalProperties": false, - "properties": { - "resolver_op": { - "const": "resolved_sys_executable" - } - }, - "required": [ - "resolver_op" - ] - }, - "version": { - "type": "object", - "additionalProperties": false, - "properties": { - "resolver_op": { - "const": "python_version_triplet" - } - }, - "required": [ - "resolver_op" - ] + "resolver_op": { + "const": "primary_qrf_worker_semantic_identity_sha256" } }, "required": [ - "cache_tag", - "executable", - "implementation", - "resolved_executable", - "version" + "resolver_op" ] }, - "module": { - "type": "string" + "audit_aliases": { + "type": "object", + "additionalProperties": false, + "properties": { + "resolver_op": { + "const": "primary_qrf_worker_audit_aliases" + } + }, + "required": [ + "resolver_op" + ] } }, "required": [ - "argv_template", - "environment", - "interpreter", - "module" + "schema_version", + "semantic_identity", + "semantic_identity_sha256", + "audit_aliases" ] } }, diff --git a/packages/microcosm-build/src/microcosm/build/spec_engine/schema/spine.schema.json b/packages/microcosm-build/src/microcosm/build/spec_engine/schema/spine.schema.json index dc4c7955d..251360cf9 100644 --- a/packages/microcosm-build/src/microcosm/build/spec_engine/schema/spine.schema.json +++ b/packages/microcosm-build/src/microcosm/build/spec_engine/schema/spine.schema.json @@ -288,7 +288,7 @@ "const": "populace_us_stacked_pool_checkpoint_identity" }, "schema_version": {"const": 1}, - "materializer_version": {"const": 12}, + "materializer_version": {"const": 13}, "pipeline": {"const": "us-stacked-pool"} } }, diff --git a/packages/microcosm-build/src/microcosm/build/us/spec/battery.yaml b/packages/microcosm-build/src/microcosm/build/us/spec/battery.yaml index d8472fe01..ecfe34a68 100644 --- a/packages/microcosm-build/src/microcosm/build/us/spec/battery.yaml +++ b/packages/microcosm-build/src/microcosm/build/us/spec/battery.yaml @@ -838,4 +838,4 @@ metric_contracts: threshold: categorical_total_variation authority_binding: authority_id: us_stacked_spine_authority - version: 11 + version: 12 diff --git a/packages/microcosm-build/src/microcosm/build/us/spec/imputation.yaml b/packages/microcosm-build/src/microcosm/build/us/spec/imputation.yaml index 16ae791a1..e0f34cef4 100644 --- a/packages/microcosm-build/src/microcosm/build/us/spec/imputation.yaml +++ b/packages/microcosm-build/src/microcosm/build/us/spec/imputation.yaml @@ -2776,7 +2776,7 @@ families: output_coverage_scope: whole_pool producer_graph: graph_schema_version: 2 - schedule_payload_schema_version: 16 + schedule_payload_schema_version: 17 external_stages: - post_clone_input_surface scope_coverage: @@ -4397,7 +4397,7 @@ producer_graph: resolution: static_exact binding: resource_kind: primary_puf_execution_config - schema_version: 4 + schema_version: 5 qrf: invocation_mode: predictors: canonical_default @@ -4409,52 +4409,13 @@ producer_graph: surface: execution_profile resolve_as: worker_execution template: - module: microcosm.build.us_runtime.puf_qrf_worker - argv_template: - - resolver_op: sys_executable - - -m - - microcosm.build.us_runtime.puf_qrf_worker - - --checkpoint-dir - - '{checkpoint_dir}' - - --target-index - - '{target_index}' - interpreter: - executable: - resolver_op: sys_executable - resolved_executable: - resolver_op: resolved_sys_executable - implementation: - resolver_op: python_implementation - cache_tag: - resolver_op: python_cache_tag - version: - resolver_op: python_version_triplet - environment: - policy: inherit_parent_environment_with_bound_fit_controls - overrides: {} - semantic_controls: - POPULACE_FIT_N_JOBS: - configured: - resolver_op: environment_value - name: POPULACE_FIT_N_JOBS - resolved: - resolver_op: env_canonical_positive_int_or_default - name: POPULACE_FIT_N_JOBS - default: -1 - POPULACE_FIT_PREDICT_WORKERS: - configured: - resolver_op: environment_value - name: POPULACE_FIT_PREDICT_WORKERS - resolved: - resolver_op: env_positive_int_or_cpu_count - name: POPULACE_FIT_PREDICT_WORKERS - fallback_minimum: 1 - resolution: - resolver_op: env_or_cpu_count_resolution_label - name: POPULACE_FIT_PREDICT_WORKERS - bound_names: - - POPULACE_FIT_N_JOBS - - POPULACE_FIT_PREDICT_WORKERS + schema_version: 1 + semantic_identity: + resolver_op: primary_qrf_worker_semantic_identity + semantic_identity_sha256: + resolver_op: primary_qrf_worker_semantic_identity_sha256 + audit_aliases: + resolver_op: primary_qrf_worker_audit_aliases doctrines: require_complete_recipient_predictors: true absent_cells: preserve_nulls @@ -33375,14 +33336,14 @@ producer_graph: - first_home_mortgage_origination_year - health_savings_account_ald execution_receipt_contract: - version: 3 + version: 4 row_binding: declared_globally_reconciled_input_and_scope_exact_output_source_and_primary_callback_resource_receipt_and_previous_execution_sha256 virtual_resource_binding: exact_kind_specific_semantic_payload_and_sha256 top_binding: entry_and_output_frame_sha256_execution_chain_source_completion_and_nineteen_transfer_groups transition_authority: authority_id: us_stacked_late_producer_transition metadata_key: us_late_producer_transition_authority - version: 1 + version: 2 independent_digest_required: true ownership_contract: artifact_kind: microcosm_us_late_overlap_ownership @@ -33684,7 +33645,7 @@ producer_graph: action: producer_masked_byte_exact_noop resource_semantics: artifact_kind: populace_us_stacked_late_producer_resource_semantics - schema_version: 1 + schema_version: 2 resolution: clone_attachment_ref: domain: spine diff --git a/packages/microcosm-build/src/microcosm/build/us/spec/spine.yaml b/packages/microcosm-build/src/microcosm/build/us/spec/spine.yaml index e932429a6..1ffcd4643 100644 --- a/packages/microcosm-build/src/microcosm/build/us/spec/spine.yaml +++ b/packages/microcosm-build/src/microcosm/build/us/spec/spine.yaml @@ -3,7 +3,7 @@ pipeline_contract: artifact_protocol: artifact_kind: populace_us_stacked_pool_checkpoint_identity schema_version: 1 - materializer_version: 12 + materializer_version: 13 pipeline: us-stacked-pool stacked_operator_order: - assemble_stacked_spine diff --git a/packages/microcosm-build/src/microcosm/build/us_runtime/h5_io.py b/packages/microcosm-build/src/microcosm/build/us_runtime/h5_io.py index d8427a124..48b87cb2b 100644 --- a/packages/microcosm-build/src/microcosm/build/us_runtime/h5_io.py +++ b/packages/microcosm-build/src/microcosm/build/us_runtime/h5_io.py @@ -27,6 +27,7 @@ canonicalize_frame_string_dtypes, canonicalize_table_string_dtypes, ) +from microcosm.build.us_runtime import worker_identity as worker_identity_runtime from microcosm.build.us_runtime.congressional_district_geography import ( CONGRESSIONAL_DISTRICT_GEOID_COLUMN, ) @@ -92,6 +93,7 @@ US_MULTISPINE_AGREEMENT_DIAGNOSTICS_ARTIFACT_KIND = ( "populace_us_multispine_agreement_diagnostics" ) +# 10 binds the portable authenticated primary-QRF worker identity. # 9 binds the post-assembly household-geography assignment receipt and its # authenticated release-vintage authorities. # 8 binds the nullable-boolean-capable physical H5 materializer in both the @@ -102,10 +104,11 @@ # authority and restores its immutable Frame-metadata anchor on H5 load. # Schema 5 can authenticate the DAG receipt's structure, but cannot prove that # the published receipt is the one authorized by the generating transition. -US_MULTISPINE_POOL_MANIFEST_SCHEMA_VERSION = 9 +US_MULTISPINE_POOL_MANIFEST_SCHEMA_VERSION = 10 US_MULTISPINE_POOL_H5_MATERIALIZER_VERSION = 3 """Version 3 atomically binds release CD provenance attrs; v2 added BooleanDtype.""" _LEGACY_MULTISPINE_POOL_MANIFEST_SCHEMA_VERSION = 4 +_LEGACY_PORTABLE_WORKER_MANIFEST_SCHEMA_VERSION = 9 _METADATA_KEY = "_populace_staging_metadata" _TIME_PERIOD_KEY = "_time_period" _LOWERCASE_SHA256 = re.compile(r"[0-9a-f]{64}") @@ -158,9 +161,10 @@ "late_producer_transition_authority_sha256", "stack_manifest", "terminal_gates", + "worker_execution_authentication", } ) -_REQUIRED_STACKED_MANIFEST_FIELDS = frozenset( +_REQUIRED_SCHEMA_NINE_STACKED_MANIFEST_FIELDS = frozenset( { "pipeline", "operator_order", @@ -170,6 +174,9 @@ "stage_receipts", } ) +_REQUIRED_CURRENT_STACKED_MANIFEST_FIELDS = ( + _REQUIRED_SCHEMA_NINE_STACKED_MANIFEST_FIELDS | {"worker_execution_authentication"} +) def _stacked_manifest_markers(manifest: Mapping[str, object]) -> set[str]: @@ -259,8 +266,16 @@ def _validated_pool_manifest_envelope( schema_version = manifest.get("schema_version") markers = _stacked_manifest_markers(manifest) - if schema_version == US_MULTISPINE_POOL_MANIFEST_SCHEMA_VERSION: - missing = _REQUIRED_STACKED_MANIFEST_FIELDS - set(manifest) + if schema_version in { + _LEGACY_PORTABLE_WORKER_MANIFEST_SCHEMA_VERSION, + US_MULTISPINE_POOL_MANIFEST_SCHEMA_VERSION, + }: + required = ( + _REQUIRED_SCHEMA_NINE_STACKED_MANIFEST_FIELDS + if schema_version == _LEGACY_PORTABLE_WORKER_MANIFEST_SCHEMA_VERSION + else _REQUIRED_CURRENT_STACKED_MANIFEST_FIELDS + ) + missing = required - set(manifest) if manifest.get("pipeline") != _STACKED_PIPELINE or missing: raise ValueError( f"US multispine pool manifest {manifest_path} has an " @@ -434,6 +449,17 @@ def _file_sha256_stream(path: str | Path) -> str: return digest.hexdigest() +def _canonical_json_sha256(value: object) -> str: + raw = json.dumps( + value, + allow_nan=False, + ensure_ascii=False, + separators=(",", ":"), + sort_keys=True, + ).encode("utf-8") + return hashlib.sha256(raw).hexdigest() + + #: Version of the packaging-independent content identity. Version 2 hashes the #: sorted multiset of household weights with the household count: no ids, no #: optional columns, no row order, so relabelling ids or dropping provenance @@ -563,7 +589,12 @@ class AuthenticatedPoolH5: size_bytes: int publication_run_id: str manifest_sha256: str + manifest_payload_sha256: str | None = None content_identity_sha256: str | None = None + worker_execution_authentication: Mapping[str, object] | None = None + _legacy_worker_authentication: ( + worker_identity_runtime.LegacyWorkerIdentityAuthentication | None + ) = None def verified_digest(self, *, consumer: str) -> str: """Re-verify the pathname and return only the authenticated digest.""" @@ -703,6 +734,47 @@ def us_multispine_pool_release_receipt( ) -> dict[str, object]: """Build self-contained release evidence from an authenticated pool.""" + if authenticated_pool_h5.manifest_payload_sha256 != _canonical_json_sha256( + manifest + ): + raise ValueError( + "Authenticated pool manifest payload changed before release receipt " + "construction." + ) + worker_authentication = authenticated_pool_h5.worker_execution_authentication + manifest_schema_version = manifest.get("schema_version") + if ( + manifest_schema_version == _LEGACY_PORTABLE_WORKER_MANIFEST_SCHEMA_VERSION + or authenticated_pool_h5._legacy_worker_authentication is not None + or ( + worker_authentication is not None + and ( + worker_authentication.get("purpose") == "scoring_only" + or "compatibility_attestation_sha256" in worker_authentication + ) + ) + ): + raise ValueError( + "Scoring-only worker identity compatibility evidence cannot become " + "a release receipt." + ) + manifest_worker_authentication = manifest.get("worker_execution_authentication") + if manifest_schema_version == US_MULTISPINE_POOL_MANIFEST_SCHEMA_VERSION: + if ( + worker_authentication is None + or manifest_worker_authentication != worker_authentication + ): + raise ValueError( + "Authenticated current worker identity evidence changed before " + "release receipt construction." + ) + elif ( + manifest_worker_authentication is not None or worker_authentication is not None + ): + raise ValueError( + "A non-current pool manifest carries unsupported worker identity evidence." + ) + # The scoring-only loader may authenticate a denied publication; nothing # it returns may become release evidence. for denied_run_id, denied_publication in DENIED_POOL_PUBLICATIONS.items(): @@ -817,7 +889,7 @@ def us_multispine_pool_release_receipt( "valid SHA-256." ) - return { + receipt = { "artifact_kind": US_MULTISPINE_POOL_H5_ARTIFACT_KIND, "status": status, "simulation_ready": simulation_ready, @@ -836,6 +908,11 @@ def us_multispine_pool_release_receipt( "verdict": dict(agreement_gate), }, } + if worker_authentication is not None: + receipt["worker_execution_authentication"] = deepcopy( + dict(worker_authentication) + ) + return receipt def load_legacy_calibrated_us_h5(path: str | Path) -> Frame: @@ -901,12 +978,89 @@ def load_simulation_ready_us_multispine_pool_manifest( return manifest +def _stacked_primary_execution_config( + manifest: Mapping[str, object], + *, + manifest_path: Path, +) -> tuple[Mapping[str, object], object]: + """Return the signed primary execution config and nested worker binding.""" + + stage_receipts = _mapping( + manifest.get("stage_receipts"), + label=f"US stacked pool manifest {manifest_path}.stage_receipts", + ) + impute = _mapping( + stage_receipts.get("impute"), + label=f"US stacked pool manifest {manifest_path}.stage_receipts.impute", + ) + dag = _mapping( + impute.get("stacked_late_producer_dag"), + label=f"US stacked pool manifest {manifest_path} late-producer DAG", + ) + execution = dag.get("execution") + if not isinstance(execution, list): + raise ValueError( + f"US stacked pool manifest {manifest_path} has no execution rows." + ) + primary_rows = [ + row + for row in execution + if isinstance(row, Mapping) and row.get("producer") == "primary_puf_qrf" + ] + if len(primary_rows) != 1: + raise ValueError( + f"US stacked pool manifest {manifest_path} must carry exactly one " + "primary-QRF execution row." + ) + available = _mapping( + primary_rows[0].get("available_input_receipts"), + label=f"US stacked pool manifest {manifest_path} primary resources", + ) + receipt = _mapping( + available.get("tax_unit.@primary_puf_execution_config"), + label=f"US stacked pool manifest {manifest_path} primary config receipt", + ) + config = _mapping( + receipt.get("binding"), + label=f"US stacked pool manifest {manifest_path} primary execution config", + ) + qrf = _mapping( + config.get("qrf"), + label=f"US stacked pool manifest {manifest_path} primary QRF config", + ) + return config, qrf.get("worker_execution") + + +def _current_worker_execution_authentication( + manifest: Mapping[str, object], + *, + manifest_path: Path, +) -> dict[str, object]: + """Derive current authentication evidence from the signed nested worker.""" + + config, worker = _stacked_primary_execution_config( + manifest, manifest_path=manifest_path + ) + if config.get("schema_version") != 5: + raise ValueError( + f"US stacked pool manifest {manifest_path} primary execution-config " + "version changed." + ) + return worker_identity_runtime.current_worker_execution_authentication_receipt( + worker, + manifest_schema_version=US_MULTISPINE_POOL_MANIFEST_SCHEMA_VERSION, + execution_config_schema_version=5, + boundary=f"US stacked pool manifest {manifest_path} primary-QRF worker", + ) + + def _load_authenticated_us_multispine_pool_manifest( path: str | Path, *, expected_manifest_sha256: str | None = None, allow_terminal_gate_failure: bool = False, scoring_only: bool = False, + worker_identity_attestation: str | Path | None = None, ) -> tuple[dict[str, object], AuthenticatedPoolH5]: """Return a validated manifest and its authenticated pool-H5 identity. @@ -965,16 +1119,74 @@ def _load_authenticated_us_multispine_pool_manifest( raise ValueError( f"US multispine pool manifest {manifest_path} is not simulation-ready." ) - envelope = _validated_pool_manifest_envelope( - manifest, - manifest_path=manifest_path, - ) + legacy_worker_authentication = None + if ( + manifest.get("schema_version") + == _LEGACY_PORTABLE_WORKER_MANIFEST_SCHEMA_VERSION + ): + envelope = _validated_pool_manifest_envelope( + manifest, + manifest_path=manifest_path, + ) + if not scoring_only or not is_terminal_gate_failure: + raise ValueError( + f"US multispine pool manifest {manifest_path} has an " + "unsupported artifact binding." + ) + if "worker_execution_authentication" in manifest: + raise ValueError( + f"US legacy pool manifest {manifest_path} carries an " + "unauthenticated worker receipt." + ) + if worker_identity_attestation is None: + raise ValueError( + f"US multispine pool manifest {manifest_path} requires an " + "explicit compatibility attestation for legacy worker relocation." + ) + config, recorded_worker = _stacked_primary_execution_config( + manifest, manifest_path=manifest_path + ) + if config.get("schema_version") != 4: + raise ValueError( + f"US multispine pool manifest {manifest_path} legacy primary " + "execution-config version changed." + ) + declared_pool = _mapping( + manifest.get("pool_h5"), + label=f"US multispine pool manifest {manifest_path}.pool_h5", + ) + legacy_worker_authentication = ( + worker_identity_runtime.authenticate_legacy_worker_identity_attestation( + worker_identity_attestation, + sealed_manifest_sha256=manifest_sha256, + sealed_pool_h5_sha256=declared_pool.get("sha256"), + recorded_worker_execution=recorded_worker, + boundary=( + f"US multispine pool manifest {manifest_path} compatibility " + "attestation" + ), + ) + ) + else: + if worker_identity_attestation is not None: + raise ValueError( + f"US multispine pool manifest {manifest_path} does not permit a " + "worker identity compatibility attestation." + ) + envelope = _validated_pool_manifest_envelope( + manifest, + manifest_path=manifest_path, + ) _validated_stacked_sampling_manifest_binding( manifest, manifest_path=manifest_path, ) expected_schema_version = ( - US_MULTISPINE_POOL_MANIFEST_SCHEMA_VERSION + ( + _LEGACY_PORTABLE_WORKER_MANIFEST_SCHEMA_VERSION + if legacy_worker_authentication is not None + else US_MULTISPINE_POOL_MANIFEST_SCHEMA_VERSION + ) if envelope == "stacked" else _LEGACY_MULTISPINE_POOL_MANIFEST_SCHEMA_VERSION ) @@ -987,7 +1199,24 @@ def _load_authenticated_us_multispine_pool_manifest( _validate_stacked_late_dag_manifest_binding( manifest, manifest_path=manifest_path, + legacy_worker_authentication=legacy_worker_authentication, ) + if legacy_worker_authentication is not None: + worker_execution_authentication = legacy_worker_authentication.receipt() + elif envelope == "stacked": + worker_execution_authentication = _current_worker_execution_authentication( + manifest, + manifest_path=manifest_path, + ) + if manifest.get("worker_execution_authentication") != ( + worker_execution_authentication + ): + raise ValueError( + f"US stacked pool manifest {manifest_path} worker execution " + "authentication receipt changed." + ) + else: + worker_execution_authentication = None checkpoint_provenance = _mapping( manifest.get("stage_checkpoints"), label=f"US multispine pool manifest {manifest_path}.stage_checkpoints", @@ -1124,6 +1353,21 @@ def _load_authenticated_us_multispine_pool_manifest( f"US multispine pool diagnostics {diagnostics_path} do not match " "the authenticated manifest publication." ) + if envelope == "stacked": + diagnostics_worker_authentication = diagnostics.get( + "worker_execution_authentication" + ) + if legacy_worker_authentication is not None: + if diagnostics_worker_authentication is not None: + raise ValueError( + f"US legacy pool diagnostics {diagnostics_path} carry an " + "unauthenticated worker receipt." + ) + elif diagnostics_worker_authentication != worker_execution_authentication: + raise ValueError( + f"US stacked pool diagnostics {diagnostics_path} worker " + "authentication differs from its manifest." + ) manifest_agreement_gate = _mapping( manifest.get("agreement_gate"), label=f"US multispine pool manifest {manifest_path}.agreement_gate", @@ -1152,13 +1396,22 @@ def _load_authenticated_us_multispine_pool_manifest( consumer="authenticated US multispine pool manifest", how="authenticated H5", ) - return manifest, AuthenticatedPoolH5( + returned_manifest = manifest + if legacy_worker_authentication is not None: + returned_manifest = deepcopy(manifest) + returned_manifest["worker_execution_authentication"] = ( + worker_execution_authentication + ) + return returned_manifest, AuthenticatedPoolH5( path=pool_path.resolve(), sha256=pool_sha256, size_bytes=pool_size_bytes, publication_run_id=publication_run_id, manifest_sha256=manifest_sha256, + manifest_payload_sha256=_canonical_json_sha256(returned_manifest), content_identity_sha256=content_identity, + worker_execution_authentication=worker_execution_authentication, + _legacy_worker_authentication=legacy_worker_authentication, ) @@ -1166,8 +1419,11 @@ def _validate_stacked_late_dag_manifest_binding( manifest: Mapping[str, object], *, manifest_path: Path, + legacy_worker_authentication: ( + worker_identity_runtime.LegacyWorkerIdentityAuthentication | None + ) = None, ) -> None: - """Make schema-9 consumers authenticate geography and late-DAG proofs.""" + """Make stacked consumers authenticate geography and late-DAG proofs.""" if manifest.get("pipeline") != "us-stacked-pool": return @@ -1199,10 +1455,12 @@ def _validate_stacked_late_dag_manifest_binding( validate_stacked_late_producer_receipt( dag, boundary=f"US stacked pool manifest {manifest_path}", + legacy_worker_authentication=legacy_worker_authentication, ) _stacked_late_transition_binding( manifest, manifest_path=manifest_path, + legacy_worker_authentication=legacy_worker_authentication, ) transfer_alias = impute.get("stacked_post_puf_transfer") source_chain = impute.get("source_operator_chain") @@ -1752,6 +2010,9 @@ def _stacked_late_transition_binding( manifest: Mapping[str, object], *, manifest_path: Path, + legacy_worker_authentication: ( + worker_identity_runtime.LegacyWorkerIdentityAuthentication | None + ) = None, ) -> tuple[Mapping[str, object], Mapping[str, object], str] | None: """Return the signed DAG, derived authority, and independent authority SHA.""" @@ -1821,6 +2082,7 @@ def load_authenticated_us_multispine_pool_for_scoring( path: str | Path, *, expected_manifest_sha256: str | None = None, + worker_identity_attestation: str | Path | None = None, ) -> tuple[Frame, dict[str, object], AuthenticatedPoolH5]: """Load authenticated pool evidence without promoting failed gates. @@ -1838,6 +2100,7 @@ def load_authenticated_us_multispine_pool_for_scoring( expected_manifest_sha256=expected_manifest_sha256, require_simulation_ready=False, scoring_only=True, + worker_identity_attestation=worker_identity_attestation, ) @@ -1874,6 +2137,7 @@ def _load_us_multispine_pool( expected_manifest_sha256: str | None, require_simulation_ready: bool, scoring_only: bool = False, + worker_identity_attestation: str | Path | None = None, ) -> tuple[Frame, dict[str, object], AuthenticatedPoolH5]: """Shared authenticated H5 reconstruction for readiness and scoring.""" @@ -1883,6 +2147,7 @@ def _load_us_multispine_pool( expected_manifest_sha256=expected_manifest_sha256, allow_terminal_gate_failure=not require_simulation_ready, scoring_only=scoring_only, + worker_identity_attestation=worker_identity_attestation, ) agreement_gate = _mapping( manifest.get("agreement_gate"), @@ -1952,6 +2217,9 @@ def _load_us_multispine_pool( late_transition = _stacked_late_transition_binding( manifest, manifest_path=manifest_path, + legacy_worker_authentication=( + authenticated_pool_h5._legacy_worker_authentication + ), ) frame_metadata: dict[str, object] = {} stack_manifest = _validated_stacked_sampling_manifest_binding( @@ -1993,6 +2261,9 @@ def _load_us_multispine_pool( dag, boundary=f"US stacked pool H5 {pool_path}", expected_transition_authority_sha256=transition_authority_sha256, + legacy_worker_authentication=( + authenticated_pool_h5._legacy_worker_authentication + ), ) provenance_counts = _mapping( diff --git a/packages/microcosm-build/src/microcosm/build/us_runtime/puf_qrf_worker.py b/packages/microcosm-build/src/microcosm/build/us_runtime/puf_qrf_worker.py index c181fdbca..24d3b6a76 100644 --- a/packages/microcosm-build/src/microcosm/build/us_runtime/puf_qrf_worker.py +++ b/packages/microcosm-build/src/microcosm/build/us_runtime/puf_qrf_worker.py @@ -3,9 +3,18 @@ from __future__ import annotations import argparse +import os from pathlib import Path -from microcosm.build.us_runtime.puf_qrf_chain import run_primary_puf_qrf_target +_TORCH_BACKEND_AUTOLOAD_ENVIRONMENT = "TORCH_DEVICE_BACKEND_AUTOLOAD" +# The authenticated launcher sets this before interpreter startup because +# parent-package imports can load Torch before this module. Keep the bootstrap +# override as defense in depth for subsequent imports. +os.environ[_TORCH_BACKEND_AUTOLOAD_ENVIRONMENT] = "0" + +from microcosm.build.us_runtime.puf_qrf_chain import ( # noqa: E402 + run_primary_puf_qrf_target, +) def main(argv: list[str] | None = None) -> None: diff --git a/packages/microcosm-build/src/microcosm/build/us_runtime/stacked_spine.py b/packages/microcosm-build/src/microcosm/build/us_runtime/stacked_spine.py index ae762b467..d71320311 100644 --- a/packages/microcosm-build/src/microcosm/build/us_runtime/stacked_spine.py +++ b/packages/microcosm-build/src/microcosm/build/us_runtime/stacked_spine.py @@ -83,6 +83,7 @@ from microcosm.build.us_runtime import ( post_transfer_calibration as post_transfer_calibration_runtime, ) +from microcosm.build.us_runtime import worker_identity as worker_identity_runtime from microcosm.build.us_runtime.acs_income_universe import ( ACS_PUMS_EARNINGS_SOURCE_COLUMNS, AcsPumsEarningsUniverseApplication, @@ -215,6 +216,7 @@ US_LATE_SOURCE_FINALIZER_STAGE, US_LATE_TRANSFER_MODEL_CONFIG_INPUT, US_LATE_TRANSFER_TARGET_BANK_INPUT, + legacy_us_late_producer_schedule_receipt, us_late_producer_schedule_receipt, ) from microcosm.fit import Regime @@ -1700,11 +1702,12 @@ def thaw(item: object) -> object: _GAP_FILL_ASEC_HOUSING_TO_ACS = "asec_housing_to_acs" _GAP_FILL_HOUSING_FAMILY = "housing" _STACKED_AUTHORITY_ID = "us_stacked_spine_authority" -# v11 binds the post-transfer two-part calibration policy. v10 bound the +# v12 binds the portable primary-QRF worker identity. v11 binds the +# post-transfer two-part calibration policy. v10 bound the # primary-PUF whole-pool output-universe declaration. v9 bound the # content-hashed execution/transition-authority schema in addition to the # import-validated producer/input DAG. -_STACKED_AUTHORITY_VERSION = 11 +_STACKED_AUTHORITY_VERSION = 12 _CANONICAL_AUTHORITY_FORM = "CANONICAL" _NONCANONICAL_AUTHORITY_FORM = "NON-CANONICAL" _PRE_CLONE_PREPARATION_STAGE = "prepare_multispine_source_inputs_for_clone" @@ -3405,6 +3408,7 @@ def _authority_receipt( authority: _StackedAuthority, *, _canonical_authority: _StackedAuthority = _CANONICAL_STACKED_AUTHORITY, + _expected_version: int = _STACKED_AUTHORITY_VERSION, ) -> dict[str, object]: """Receipt live content, claimed digests, identity, and component counts.""" @@ -3419,7 +3423,7 @@ def _authority_receipt( canonical_identity = authority is _canonical_authority canonical_content = ( authority.authority_id == _STACKED_AUTHORITY_ID - and authority.version == _STACKED_AUTHORITY_VERSION + and authority.version == _expected_version and live_components == dict(_canonical_authority.declared_component_sha256) and live_bundle == _canonical_authority.declared_sha256 ) @@ -3535,6 +3539,34 @@ def _authority_receipt( } +def _legacy_stacked_authority_receipt() -> dict[str, object]: + """Reconstruct the canonical v11 authority for attested schema-9 scoring.""" + + authority = _make_stacked_authority( + authority_id=_STACKED_AUTHORITY_ID, + version=11, + gap_fill_plan=_CANONICAL_STACKED_GAP_FILL_PLAN_ANCHOR, + post_puf_transfer_surface=(_CANONICAL_STACKED_POST_PUF_TRANSFER_SURFACE_ANCHOR), + post_puf_puf_producer_surface=( + _CANONICAL_STACKED_POST_PUF_PUF_PRODUCER_SURFACE_ANCHOR + ), + post_puf_source_producer_surface=( + _CANONICAL_STACKED_POST_PUF_SOURCE_PRODUCER_SURFACE_ANCHOR + ), + declared_surface=_CANONICAL_STACKED_DECLARED_SURFACE_ANCHOR, + metric_registry=_CANONICAL_ORIGIN_BATTERY_METRIC_REGISTRY_ANCHOR, + joint_metric_registry=_CANONICAL_ORIGIN_BATTERY_JOINT_METRIC_REGISTRY_ANCHOR, + support_profile=_CANONICAL_ORIGIN_BATTERY_SUPPORT_PROFILE_ANCHOR, + late_producer_schedule=legacy_us_late_producer_schedule_receipt(), + declared_form=_CANONICAL_AUTHORITY_FORM, + ) + return _authority_receipt( + authority, + _canonical_authority=authority, + _expected_version=11, + ) + + def _authority_validation_failures( authority: _StackedAuthority, *, @@ -4220,7 +4252,9 @@ def _validate_pregnancy_structural_receipt( or structural.get("status") != "verified" ): raise ValueError(f"{boundary}: pregnancy structural policy is invalid.") - counts = {field: structural.get(field) for field in _PREGNANCY_STRUCTURAL_COUNT_FIELDS} + counts = { + field: structural.get(field) for field in _PREGNANCY_STRUCTURAL_COUNT_FIELDS + } if any( not isinstance(value, int) or isinstance(value, bool) or value < 0 for value in counts.values() @@ -4250,9 +4284,7 @@ def _validate_pregnancy_structural_receipt( != row_counts["imputed_rows"] ) ): - raise ValueError( - f"{boundary}: pregnancy structural accounting is invalid." - ) + raise ValueError(f"{boundary}: pregnancy structural accounting is invalid.") def _acs_imputed_pattern_evidence(record: AcsImputedInput) -> dict[str, object]: @@ -4745,6 +4777,9 @@ def validate_stacked_post_puf_transfer_receipt( *, boundary: str, frame: Frame | None = None, + legacy_worker_authentication: ( + worker_identity_runtime.LegacyWorkerIdentityAuthentication | None + ) = None, ) -> None: """Reject a late-transfer receipt unless its full DAG proof is canonical.""" @@ -4756,7 +4791,13 @@ def validate_stacked_post_puf_transfer_receipt( f"{boundary}: stacked post-PUF transfer receipt has no authority; " "production manifest emission is forbidden." ) - _validate_production_authority_receipt(authority, boundary=boundary) + if legacy_worker_authentication is None: + _validate_production_authority_receipt(authority, boundary=boundary) + expected_schedule = _json_ready(us_late_producer_schedule_receipt()) + else: + if dict(authority) != _legacy_stacked_authority_receipt(): + raise ValueError(f"{boundary}: attested legacy stacked authority changed.") + expected_schedule = _json_ready(legacy_us_late_producer_schedule_receipt()) expected_policy_sha256 = str( _CANONICAL_STACKED_AUTHORITY.post_transfer_calibration["sha256"] ) @@ -4771,7 +4812,6 @@ def validate_stacked_post_puf_transfer_receipt( (spec.entity, spec.target): spec for spec in late_calibration_specs.values() } schedule = receipt.get("producer_schedule") - expected_schedule = _json_ready(us_late_producer_schedule_receipt()) if not isinstance(schedule, Mapping) or _json_ready(schedule) != expected_schedule: raise ValueError( f"{boundary}: stacked post-PUF transfer receipt has no canonical " @@ -5354,17 +5394,29 @@ def _late_virtual_resource_kind(column: str) -> str: ) from exc -def _late_resource_binding_schema_version(column: str) -> int: +def _late_resource_binding_schema_version( + column: str, + *, + legacy_worker_authentication: ( + worker_identity_runtime.LegacyWorkerIdentityAuthentication | None + ) = None, +) -> int: """Return the independently versioned payload schema for one resource.""" kind = _late_virtual_resource_kind(column) - return { + versions = { "acs_pums_earnings_universe_execution_config": 2, - "primary_puf_execution_config": 4, + "primary_puf_execution_config": 5, "post_clone_source_execution_config": 3, "source_finalizer_execution_config": 2, "late_transfer_model_config": 3, - }.get(kind, 1) + } + if ( + kind == "primary_puf_execution_config" + and legacy_worker_authentication is not None + ): + return 4 + return versions.get(kind, 1) def _late_contract_available_input_keys( @@ -5390,6 +5442,9 @@ def _validate_late_resource_binding( entity: str, column: str, boundary: str, + legacy_worker_authentication: ( + worker_identity_runtime.LegacyWorkerIdentityAuthentication | None + ) = None, ) -> None: """Reject hash-consistent resource claims with incomplete semantics.""" @@ -5589,10 +5644,30 @@ def require_positive_integer(value: object, *, label: str) -> int: puf_tax_detail_tail_bound_quantiles_identity() ): raise ValueError(f"{boundary}: late primary-QRF tail bounds changed.") - if qrf.get("worker_execution") != ( - _late_primary_qrf_worker_execution_binding() - ): - raise ValueError(f"{boundary}: late primary-QRF worker binding changed.") + recorded_worker = qrf.get("worker_execution") + if legacy_worker_authentication is not None: + if ( + recorded_worker + != legacy_worker_authentication.recorded_worker_execution + ): + raise ValueError( + f"{boundary}: attested legacy primary-QRF worker changed." + ) + else: + try: + semantically_equal = worker_identity_runtime.primary_qrf_worker_bindings_semantically_equal( + recorded_worker, + _late_primary_qrf_worker_execution_binding(), + boundary=f"{boundary}: late primary-QRF worker", + ) + except ValueError as exc: + raise ValueError( + f"{boundary}: late primary-QRF worker binding is malformed." + ) from exc + if not semantically_equal: + raise ValueError( + f"{boundary}: late primary-QRF semantic worker identity changed." + ) if doctrines != { "require_complete_recipient_predictors": True, "absent_cells": PUF_ABSENT_CELLS_PRESERVE_NULLS, @@ -5796,6 +5871,9 @@ def _validate_late_available_input_receipt( entity: str, column: str, boundary: str, + legacy_worker_authentication: ( + worker_identity_runtime.LegacyWorkerIdentityAuthentication | None + ) = None, ) -> None: """Validate one virtual input receipt without trusting a row count alone.""" @@ -5834,7 +5912,10 @@ def _validate_late_available_input_receipt( ) binding = receipt.get("binding") expected_kind = _late_virtual_resource_kind(column) - expected_schema_version = _late_resource_binding_schema_version(column) + expected_schema_version = _late_resource_binding_schema_version( + column, + legacy_worker_authentication=legacy_worker_authentication, + ) if ( not isinstance(binding, Mapping) or binding.get("resource_kind") != expected_kind @@ -5860,6 +5941,7 @@ def _validate_late_available_input_receipt( entity=entity, column=column, boundary=boundary, + legacy_worker_authentication=legacy_worker_authentication, ) @@ -5904,7 +5986,7 @@ def _late_string_sequence( ) -def _late_primary_qrf_worker_execution_binding() -> dict[str, object]: +def _legacy_primary_qrf_worker_execution_binding() -> dict[str, object]: """Bind the interpreter and reviewed inherited environment controls.""" fit_jobs_raw = os.environ.get("POPULACE_FIT_N_JOBS") @@ -5979,6 +6061,17 @@ def _late_primary_qrf_worker_execution_binding() -> dict[str, object]: } +def _late_primary_qrf_worker_execution_binding() -> dict[str, object]: + """Bind portable semantics and retain absolute launch paths for audit.""" + + return worker_identity_runtime.primary_qrf_worker_execution_binding() + + +_legacy_worker_execution_mismatch_paths = ( + worker_identity_runtime._legacy_worker_execution_mismatch_paths +) + + def _late_primary_execution_config_binding( *, clone_attachment_fraction: float, @@ -6017,7 +6110,7 @@ def _late_primary_execution_config_binding( ) return { "resource_kind": "primary_puf_execution_config", - "schema_version": 4, + "schema_version": 5, "clone_attachment": { "fraction": float(clone_attachment_fraction), "seed": clone_attachment_seed, @@ -6228,7 +6321,7 @@ def _validate_stacked_late_primary_checkpoint_input_binding( raise ValueError(f"{boundary}: primary-QRF input binding schema drifted.") if ( binding.get("artifact_kind") != _LATE_PRIMARY_QRF_INPUT_BINDING_ARTIFACT_KIND - or binding.get("schema_version") != 1 + or binding.get("schema_version") != 2 ): raise ValueError(f"{boundary}: primary-QRF input binding identity changed.") resources = binding.get("primary_resource_receipts") @@ -6266,7 +6359,7 @@ def stacked_late_primary_checkpoint_input_binding( } payload: dict[str, object] = { "artifact_kind": _LATE_PRIMARY_QRF_INPUT_BINDING_ARTIFACT_KIND, - "schema_version": 1, + "schema_version": 2, "primary_resource_receipts": resources, } payload["sha256"] = _canonical_sha256(payload) @@ -6277,6 +6370,76 @@ def stacked_late_primary_checkpoint_input_binding( return payload +def _late_primary_resource_receipts_semantic_projection( + resources: Mapping[str, object], + *, + boundary: str, +) -> dict[str, object]: + """Normalize only primary-worker audit aliases out of authentication.""" + + normalized = _json_ready(resources) + if not isinstance(normalized, dict): # pragma: no cover - Mapping normalized + raise TypeError(f"{boundary}: primary resources are not an object.") + key = f"tax_unit.{US_LATE_PRIMARY_EXECUTION_CONFIG_INPUT}" + receipt = normalized.get(key) + if not isinstance(receipt, dict): + raise ValueError(f"{boundary}: primary execution-config receipt is absent.") + binding = receipt.get("binding") + if not isinstance(binding, dict): + raise ValueError(f"{boundary}: primary execution config is absent.") + qrf = binding.get("qrf") + if not isinstance(qrf, dict): + raise ValueError(f"{boundary}: primary QRF config is absent.") + qrf["worker_execution"] = ( + worker_identity_runtime.primary_qrf_worker_semantic_projection( + qrf.get("worker_execution"), + boundary=f"{boundary}: primary-QRF worker", + ) + ) + receipt["binding_sha256"] = _canonical_sha256(binding) + return normalized + + +def _late_primary_resource_receipts_semantically_equal( + left: Mapping[str, object], + right: Mapping[str, object], + *, + boundary: str, +) -> bool: + """Compare checkpoint resources without authenticating launcher aliases.""" + + return _late_primary_resource_receipts_semantic_projection( + left, boundary=f"{boundary} recorded" + ) == _late_primary_resource_receipts_semantic_projection( + right, boundary=f"{boundary} live" + ) + + +def _late_primary_checkpoint_input_bindings_semantically_equal( + left: Mapping[str, object], + right: Mapping[str, object], + *, + boundary: str, +) -> bool: + """Compare validated sidecars while retaining their original audit bytes.""" + + _validate_stacked_late_primary_checkpoint_input_binding( + left, boundary=f"{boundary} recorded" + ) + _validate_stacked_late_primary_checkpoint_input_binding( + right, boundary=f"{boundary} live" + ) + return ( + left.get("artifact_kind") == right.get("artifact_kind") + and left.get("schema_version") == right.get("schema_version") + and _late_primary_resource_receipts_semantically_equal( + left["primary_resource_receipts"], + right["primary_resource_receipts"], + boundary=boundary, + ) + ) + + _SOURCE_MANIFEST_STAGE_BY_OPERATOR: Mapping[str, str] = MappingProxyType( { "with_us_prior_year_income_inputs": "prior_year_income", @@ -6838,6 +7001,24 @@ def stacked_late_producer_resource_semantics_receipt( } } elif contract.kind == "primary_puf": + primary_execution_config = _late_primary_execution_config_binding( + clone_attachment_fraction=clone_attachment_fraction, + clone_attachment_seed=clone_attachment_seed, + seed=primary_seed, + n_estimators=primary_n_estimators, + predictors=None, + person_outputs=None, + tax_unit_outputs=None, + fit_records_enabled=True, + tail_bound_diagnostics_enabled=True, + ) + worker_binding = primary_execution_config["qrf"]["worker_execution"] + primary_execution_config["qrf"]["worker_execution"] = ( + worker_identity_runtime.primary_qrf_worker_semantic_projection( + worker_binding, + boundary="US late resource-semantics primary-QRF worker", + ) + ) resources = { "tax_unit.@puf_donor_tax_units": { "resolution": "runtime_content_bound", @@ -6855,17 +7036,7 @@ def stacked_late_producer_resource_semantics_receipt( }, f"tax_unit.{US_LATE_PRIMARY_EXECUTION_CONFIG_INPUT}": { "resolution": "static_exact", - "binding": _late_primary_execution_config_binding( - clone_attachment_fraction=clone_attachment_fraction, - clone_attachment_seed=clone_attachment_seed, - seed=primary_seed, - n_estimators=primary_n_estimators, - predictors=None, - person_outputs=None, - tax_unit_outputs=None, - fit_records_enabled=True, - tail_bound_diagnostics_enabled=True, - ), + "binding": primary_execution_config, }, } elif contract.kind == "post_clone_source": @@ -6960,7 +7131,7 @@ def stacked_late_producer_resource_semantics_receipt( ) payload: dict[str, object] = { "artifact_kind": _LATE_RESOURCE_SEMANTICS_ARTIFACT_KIND, - "schema_version": 1, + "schema_version": 2, "producer_schedule_sha256": schedule_receipt["schedule_sha256"], "producer_schedule_payload_sha256": schedule_receipt["payload_sha256"], "producer_count": len(producer_rows), @@ -7330,9 +7501,13 @@ def _late_producer_transition_authority_receipt( schedule = receipt["producer_schedule"] assert isinstance(schedule, Mapping) + receipt_version = receipt.get("version") + authority_version = ( + 1 if receipt_version == 3 else US_LATE_PRODUCER_TRANSITION_AUTHORITY_VERSION + ) authority: dict[str, object] = { "authority_id": US_LATE_PRODUCER_TRANSITION_AUTHORITY_ID, - "version": US_LATE_PRODUCER_TRANSITION_AUTHORITY_VERSION, + "version": authority_version, "receipt_sha256": receipt["sha256"], "producer_schedule_sha256": schedule["payload_sha256"], "input_frame_sha256": receipt["input_frame_sha256"], @@ -7396,6 +7571,9 @@ def _validate_late_execution_row( execution_index: int, expected_previous_sha256: str, boundary: str, + legacy_worker_authentication: ( + worker_identity_runtime.LegacyWorkerIdentityAuthentication | None + ) = None, ) -> str: """Re-run one persisted readiness proof without invoking its callback.""" @@ -7836,6 +8014,7 @@ def _validate_late_execution_row( entity=entity, column=column, boundary=f"{boundary} late producer {contract.name!r}", + legacy_worker_authentication=legacy_worker_authentication, ) if evidenced_available_sha256.get(key) != _canonical_sha256( _json_ready(receipt) @@ -8007,10 +8186,11 @@ def _late_execution_genesis_sha256( *, producer_schedule_sha256: object, input_frame_sha256: object, + receipt_schema_version: int = US_LATE_PRODUCER_RECEIPT_SCHEMA_VERSION, ) -> str: return _canonical_sha256( { - "receipt_schema_version": US_LATE_PRODUCER_RECEIPT_SCHEMA_VERSION, + "receipt_schema_version": receipt_schema_version, "producer_schedule_sha256": producer_schedule_sha256, "input_frame_sha256": input_frame_sha256, } @@ -8063,10 +8243,17 @@ def validate_stacked_late_producer_transition_authority( *, boundary: str, expected_transition_authority_sha256: str, + legacy_worker_authentication: ( + worker_identity_runtime.LegacyWorkerIdentityAuthentication | None + ) = None, ) -> None: """Validate the anchor after declared downstream operators have run.""" - validate_stacked_late_producer_receipt(receipt, boundary=boundary) + validate_stacked_late_producer_receipt( + receipt, + boundary=boundary, + legacy_worker_authentication=legacy_worker_authentication, + ) _validate_late_transition_authority( frame, receipt, @@ -8082,6 +8269,9 @@ def validate_stacked_late_producer_receipt( boundary: str, frame: Frame | None = None, expected_transition_authority_sha256: str | None = None, + legacy_worker_authentication: ( + worker_identity_runtime.LegacyWorkerIdentityAuthentication | None + ) = None, ) -> None: """Authenticate the complete derived execution and source/transfer proof.""" @@ -8104,11 +8294,20 @@ def validate_stacked_late_producer_receipt( f"missing={sorted(expected_keys - set(receipt))}, " f"extra={sorted(set(receipt) - expected_keys)}." ) - if receipt.get("version") != US_LATE_PRODUCER_RECEIPT_SCHEMA_VERSION: + expected_receipt_version = ( + 3 + if legacy_worker_authentication is not None + else US_LATE_PRODUCER_RECEIPT_SCHEMA_VERSION + ) + if receipt.get("version") != expected_receipt_version: raise ValueError( f"{boundary}: stacked late-producer DAG receipt version changed." ) - expected_schedule = _json_ready(us_late_producer_schedule_receipt()) + expected_schedule = _json_ready( + legacy_us_late_producer_schedule_receipt() + if legacy_worker_authentication is not None + else us_late_producer_schedule_receipt() + ) schedule = receipt.get("producer_schedule") if not isinstance(schedule, Mapping) or _json_ready(schedule) != expected_schedule: raise ValueError( @@ -8133,6 +8332,7 @@ def validate_stacked_late_producer_receipt( previous_sha256 = _late_execution_genesis_sha256( producer_schedule_sha256=schedule["payload_sha256"], input_frame_sha256=receipt["input_frame_sha256"], + receipt_schema_version=expected_receipt_version, ) execution_by_name: dict[str, Mapping[str, object]] = {} for index, producer_name in enumerate(expected_order): @@ -8143,6 +8343,7 @@ def validate_stacked_late_producer_receipt( execution_index=index, expected_previous_sha256=previous_sha256, boundary=boundary, + legacy_worker_authentication=legacy_worker_authentication, ) assert isinstance(raw_row, Mapping) execution_by_name[producer_name] = raw_row @@ -8274,6 +8475,7 @@ def validate_stacked_late_producer_receipt( transfer, boundary=boundary, frame=frame, + legacy_worker_authentication=legacy_worker_authentication, ) groups = transfer["groups"] assert isinstance(groups, Mapping) @@ -11836,7 +12038,11 @@ def _run_stacked_puf_pass_evaluate( capital_gains_tail_spec=tail_spec, capital_gains_tail_agi_bands=tail_agi_bands, ) - if _json_ready(actual_resources) != _json_ready(bound_resources): + if not _late_primary_resource_receipts_semantically_equal( + bound_resources, + actual_resources, + boundary="stacked primary-QRF callback invocation", + ): raise ValueError( "Stacked primary-QRF callback invocation disagrees with its " "declared late-producer donor/config resources." @@ -11863,13 +12069,22 @@ def _run_stacked_puf_pass_evaluate( observed_input_binding, boundary="stacked primary-QRF checkpoint resume", ) - if observed_input_binding != normalized_input_binding: + if not _late_primary_checkpoint_input_bindings_semantically_equal( + observed_input_binding, + normalized_input_binding, + boundary="stacked primary-QRF checkpoint resume", + ): raise ValueError( "Stacked primary QRF checkpoint input binding differs from " "the live late-producer donor/config resources; refusing " "stale predictions." ) resume_status = "resumed" + # The sidecar's bytes are retained on resume, so the receipt must + # carry the sidecar's own authenticated self-digest: the live + # binding's digest hashes the current audit aliases, which may + # differ from the relocated sidecar's without changing meaning. + reported_input_binding_sha256 = observed_input_binding["sha256"] else: if checkpoint_dir.exists() and any(checkpoint_dir.iterdir()): raise ValueError( @@ -11898,10 +12113,14 @@ def _run_stacked_puf_pass_evaluate( temporary_binding_path.write_bytes(input_binding_bytes) temporary_binding_path.replace(input_binding_path) resume_status = "initialized" + reported_input_binding_sha256 = normalized_input_binding["sha256"] predictor_universe_receipt = ( primary_puf_qrf_recipient_predictor_universe_receipt(checkpoint_dir) ) - run_primary_puf_qrf_chain(checkpoint_dir, environment={}) + with ( + worker_identity_runtime.primary_qrf_worker_launch_environment() as environment + ): + run_primary_puf_qrf_chain(checkpoint_dir, environment=environment) imputed, weight_kind = finalize_primary_puf_qrf_chain( cloned, checkpoint_dir, @@ -11914,7 +12133,7 @@ def _run_stacked_puf_pass_evaluate( "mode": "checkpoint_chain", "resume_status": resume_status, "checkpoint_manifest": str(manifest_path.resolve()), - "input_binding_sha256": normalized_input_binding["sha256"], + "input_binding_sha256": reported_input_binding_sha256, "recipient_predictor_universe": predictor_universe_receipt, } diff --git a/packages/microcosm-build/src/microcosm/build/us_runtime/us_late_producer_registry.py b/packages/microcosm-build/src/microcosm/build/us_runtime/us_late_producer_registry.py index 4b8206fa6..134ec403e 100644 --- a/packages/microcosm-build/src/microcosm/build/us_runtime/us_late_producer_registry.py +++ b/packages/microcosm-build/src/microcosm/build/us_runtime/us_late_producer_registry.py @@ -95,6 +95,7 @@ "US_LATE_TRANSFER_TARGET_BANK_INPUT", "source_producer_name", "transfer_producer_name", + "legacy_us_late_producer_schedule_receipt", "us_late_producer_schedule_payload", "us_late_producer_schedule_receipt", ] @@ -122,10 +123,12 @@ # implicit. Receipt v3 reconciles repeated physical evidence and scope # cardinalities across each execution row, binds source-receipt outputs to the # callback receipt, and requires the primary callback to report the exact -# resources it consumed. Receipt v2 introduced exact virtual-resource payloads. -US_LATE_PRODUCER_REGISTRY_SCHEMA_VERSION = 16 -US_LATE_PRODUCER_RECEIPT_SCHEMA_VERSION = 3 -US_LATE_PRODUCER_TRANSITION_AUTHORITY_VERSION = 1 +# resources it consumed. Receipt v4 and registry v17 bind the portable worker +# identity; transition authority v2 encloses that receipt. Receipt v2 +# introduced exact virtual-resource payloads. +US_LATE_PRODUCER_REGISTRY_SCHEMA_VERSION = 17 +US_LATE_PRODUCER_RECEIPT_SCHEMA_VERSION = 4 +US_LATE_PRODUCER_TRANSITION_AUTHORITY_VERSION = 2 US_LATE_PRODUCER_TRANSITION_AUTHORITY_KEY = "us_late_producer_transition_authority" US_LATE_PRODUCER_TRANSITION_AUTHORITY_ID = "us_stacked_late_producer_transition" US_LATE_PRIMARY_PUF_STAGE = "primary_puf_qrf" @@ -2139,3 +2142,34 @@ def us_late_producer_schedule_receipt() -> Mapping[str, object]: "status": "derived_and_import_validated", } ) + + +def legacy_us_late_producer_schedule_receipt() -> Mapping[str, object]: + """Reconstruct the exact schema-16 schedule for attested legacy scoring.""" + + receipt = json.loads(json.dumps(dict(us_late_producer_schedule_receipt()))) + receipt["schema_version"] = 16 + contract = receipt["execution_receipt_contract"] + contract["version"] = 3 + contract["transition_authority"]["version"] = 1 + payload = { + key: value + for key, value in receipt.items() + if key + not in { + "payload_sha256", + "producer_count", + "source_producer_count", + "transfer_group_count", + "transfer_target_count", + "status", + } + } + canonical = json.dumps( + payload, + sort_keys=True, + separators=(",", ":"), + allow_nan=False, + ).encode("utf-8") + receipt["payload_sha256"] = hashlib.sha256(canonical).hexdigest() + return MappingProxyType(receipt) diff --git a/packages/microcosm-build/src/microcosm/build/us_runtime/worker_identity.py b/packages/microcosm-build/src/microcosm/build/us_runtime/worker_identity.py new file mode 100644 index 000000000..1df039486 --- /dev/null +++ b/packages/microcosm-build/src/microcosm/build/us_runtime/worker_identity.py @@ -0,0 +1,1921 @@ +"""Portable authenticated identity for the primary PUF QRF worker.""" + +from __future__ import annotations + +import ast +import base64 +import ctypes +import ctypes.util +import hashlib +import importlib.machinery +import importlib.util +import json +import os +import subprocess +import sys +import sysconfig +from collections.abc import Iterator, Mapping, Sequence +from contextlib import contextmanager +from dataclasses import dataclass +from importlib import metadata +from pathlib import Path, PurePosixPath +from tempfile import TemporaryDirectory + +from packaging.requirements import InvalidRequirement, Requirement +from packaging.utils import canonicalize_name + +PRIMARY_QRF_WORKER_IDENTITY_SCHEMA_VERSION = 1 +PRIMARY_QRF_WORKER_MODULE = "microcosm.build.us_runtime.puf_qrf_worker" +PRIMARY_QRF_INTERPRETER_PLACEHOLDER = "{python_interpreter}" +APPROVED_UV_LOCK_SHA256 = ( + "1c1444045960e111433b064abeeb40eebbf55984b7132931d9987697a6f4b606" +) +LEGACY_CAMPAIGN_UV_LOCK_SHA256 = ( + "27f47e385cfa35e2644a37410d1804b361ad9aee123577551c8421547bda65ee" +) +# The plan and reproduced STOP record expose this exact, unambiguous campaign +# identifier. Do not accept arbitrary suffixes under the approved prefix. +LEGACY_CAMPAIGN_TREE_SHA = "b8819b3f" +LEGACY_WORKER_ATTESTATION_ARTIFACT_KIND = ( + "populace_us_worker_identity_compatibility_attestation" +) +LEGACY_WORKER_ATTESTATION_SCHEMA_VERSION = 1 +LEGACY_WORKER_PERMITTED_MISMATCHES = ( + "argv_template[0]", + "interpreter.executable", +) + +_PLAN_SIGNATURE = { + "gate": "owner-authorization:c27-root-cause:2026-09-03", + "plan_sha256": ("0a3409cfe1560d56a78ecc9acf012abaeb32621af278d745b674ebf1bee32cf6"), + "prompt_sha256": ( + "9c1e4508f24d0915c1f3a2942723d3c219c990679227c7d0a315295d5e76efa2" + ), + "checklist_sha256": ( + "5ee1f5fb40387cb690c2e85b32b6bd5abed78200f367c253e517a3917c417238" + ), + "evidence_sha256": ( + "85345eae623d0081354d746a118c9dc5ddaa89a641238e546d8c8e9f7aabbb44" + ), +} +_SEMANTIC_ENVIRONMENT_NAMES = ( + "POPULACE_FIT_N_JOBS", + "POPULACE_FIT_PREDICT_WORKERS", +) +_TORCH_BACKEND_ENTRY_POINT_GROUP = "torch.backends" +_WORKER_ENVIRONMENT_OVERRIDES = { + "TORCH_DEVICE_BACKEND_AUTOLOAD": "0", + "PYTHONDONTWRITEBYTECODE": "1", + "PYTHONPYCACHEPREFIX": "{empty_pycache_dir}", +} +_BOUND_ENVIRONMENT_NAMES = ( + *_SEMANTIC_ENVIRONMENT_NAMES, + *_WORKER_ENVIRONMENT_OVERRIDES, +) +_CLEAN_WORKER_IMPORT_TRACE_MARKER = "MICROCOSM_WORKER_IMPORT_TRACE=" +_CLEAN_WORKER_IMPORT_TRACE_SCRIPT = r""" +import importlib.util +import os +import sys + +namespace_spec = importlib.util.find_spec("microcosm") +if namespace_spec is None or namespace_spec.submodule_search_locations is None: + raise RuntimeError("cannot resolve microcosm namespace before worker import") +namespace_roots = tuple( + os.path.abspath(os.fspath(path)) + for path in namespace_spec.submodule_search_locations +) +opened_files = set() +observed_module_origins = {} + + +def record_worker_event(event, arguments): + if not arguments: + return + if event == "import" and len(arguments) > 1: + module_name, origin = arguments[:2] + if isinstance(module_name, str) and isinstance(origin, str): + observed_module_origins.setdefault(module_name, origin) + return + if event != "open": + return + raw_path = arguments[0] + if not isinstance(raw_path, (str, bytes)): + return + try: + path = os.path.abspath(os.fsdecode(raw_path)) + if os.path.isfile(path): + opened_files.add(path) + except (OSError, TypeError, ValueError): + return + + +sys.addaudithook(record_worker_event) +__import__("microcosm.build.us_runtime.puf_qrf_worker", fromlist=("*",)) +module_origins = dict(observed_module_origins) +for module_name, module in sorted(sys.modules.items()): + spec = getattr(module, "__spec__", None) + origin = getattr(spec, "origin", None) or getattr(module, "__file__", None) + if isinstance(origin, str): + module_origins[module_name] = origin +namespace = sys.modules.get("microcosm") +imported_namespace_roots = tuple( + os.path.abspath(os.fspath(path)) + for path in getattr(namespace, "__path__", ()) +) +if imported_namespace_roots != namespace_roots: + raise RuntimeError("microcosm namespace roots changed during worker import") +print( + "MICROCOSM_WORKER_IMPORT_TRACE=" + + repr( + { + "module_origins": module_origins, + "opened_files": tuple(sorted(opened_files)), + "namespace_roots": namespace_roots, + } + ), + flush=True, +) +""" +_ATTESTATION_KEYS = { + "artifact_kind", + "schema_version", + "plan_signature", + "purpose", + "sealed_manifest_sha256", + "sealed_pool_h5_sha256", + "campaign_tree_sha", + "uv_lock_sha256", + "installed_transitive_environment_code_sha256", + "recorded_worker_execution", + "semantic_identity", + "semantic_identity_sha256", + "permitted_mismatches", +} +_SHA256_ALPHABET = frozenset("0123456789abcdef") +_PRIMARY_QRF_WORKER_IDENTITY_CACHE: dict[ + tuple[str | None, str | None, str | None], dict[str, object] +] = {} + + +@dataclass(frozen=True) +class LegacyWorkerIdentityAuthentication: + """Validated scoring-only authority for one sealed legacy worker binding.""" + + attestation_sha256: str + campaign_tree_sha: str + recorded_worker_execution: Mapping[str, object] + semantic_identity: Mapping[str, object] + semantic_identity_sha256: str + + def receipt(self) -> dict[str, object]: + """Return the portable authentication evidence exposed to consumers.""" + + interpreter = self.recorded_worker_execution["interpreter"] + argv = self.recorded_worker_execution["argv_template"] + assert isinstance(interpreter, Mapping) + assert isinstance(argv, list) + return { + "manifest_schema_version": 9, + "execution_config_schema_version": 4, + "worker_execution_schema_version": 0, + "semantic_identity_sha256": self.semantic_identity_sha256, + "audit_aliases": { + "sys_executable": interpreter["executable"], + "argv_template_0": argv[0], + }, + "compatibility_attestation_sha256": self.attestation_sha256, + "purpose": "scoring_only", + } + + +def _canonical_sha256(value: object) -> str: + payload = json.dumps( + value, + allow_nan=False, + ensure_ascii=False, + separators=(",", ":"), + sort_keys=True, + ).encode("utf-8") + return hashlib.sha256(payload).hexdigest() + + +def _json_clone(value: object) -> object: + return json.loads( + json.dumps( + value, + allow_nan=False, + ensure_ascii=False, + separators=(",", ":"), + sort_keys=True, + ) + ) + + +def _require_sha256(value: object, *, boundary: str) -> str: + if ( + not isinstance(value, str) + or len(value) != 64 + or any(character not in _SHA256_ALPHABET for character in value) + ): + raise ValueError(f"{boundary} must be a lowercase SHA-256 digest.") + return value + + +def _require_exact_keys( + value: object, + expected: set[str], + *, + boundary: str, +) -> Mapping[str, object]: + if not isinstance(value, Mapping) or set(value) != expected: + actual = set(value) if isinstance(value, Mapping) else set() + raise ValueError( + f"{boundary} schema drifted; missing={sorted(expected - actual)}, " + f"extra={sorted(actual - expected)}." + ) + return value + + +def _require_string(value: object, *, boundary: str, allow_empty: bool = False) -> str: + if not isinstance(value, str) or (not allow_empty and not value): + raise ValueError(f"{boundary} must be a string.") + return value + + +def _repository_root() -> Path | None: + spec = importlib.util.find_spec(PRIMARY_QRF_WORKER_MODULE) + if spec is None or spec.origin is None: + raise RuntimeError( + f"Cannot resolve primary-QRF worker module {PRIMARY_QRF_WORKER_MODULE!r}." + ) + worker_source = Path(spec.origin).resolve() + if not worker_source.is_file(): + raise RuntimeError( + f"Primary-QRF worker source is not a readable file: {worker_source}." + ) + candidates = [worker_source.parent, *worker_source.parents] + for candidate in candidates: + if (candidate / "uv.lock").is_file() and (candidate / "packages").is_dir(): + return candidate + return None + + +def _approved_uv_lock_sha256() -> str: + root = _repository_root() + if root is None: + return APPROVED_UV_LOCK_SHA256 + observed = hashlib.sha256((root / "uv.lock").read_bytes()).hexdigest() + if observed != APPROVED_UV_LOCK_SHA256: + raise RuntimeError( + "Primary-QRF worker identity found an unapproved uv.lock digest: " + f"expected {APPROVED_UV_LOCK_SHA256}, got {observed}." + ) + return observed + + +def _module_source_index() -> dict[str, Path]: + namespace = importlib.util.find_spec("microcosm") + if namespace is None or namespace.submodule_search_locations is None: + raise RuntimeError("Cannot locate installed microcosm source packages.") + # These are the namespace roots the running interpreter will actually use, + # in import order; a convenient checkout found via CWD must never + # substitute different code. A later root may shadow an earlier one only + # with byte-identical source (an installed wheel next to its own checkout, + # or ``lib64`` beside ``lib``); differing shadowed source is refused. + namespace_roots: list[Path] = [] + for location in namespace.submodule_search_locations: + resolved = Path(location).resolve() + if resolved not in namespace_roots: + namespace_roots.append(resolved) + result: dict[str, Path] = {} + for namespace_root in namespace_roots: + for source in sorted(namespace_root.rglob("*.py")): + relative = source.relative_to(namespace_root) + parts = ["microcosm", *relative.with_suffix("").parts] + if parts[-1] == "__init__": + parts.pop() + if not parts: + continue + module_name = ".".join(parts) + previous = result.setdefault(module_name, source) + if previous == source: + continue + if previous.read_bytes() != source.read_bytes(): + raise RuntimeError( + f"Duplicate source modules for worker identity: {module_name!r} " + f"differs between {previous} and {source}." + ) + return result + + +def _source_imports( + module_name: str, + source: Path, + raw: bytes, + *, + index: Mapping[str, Path], +) -> tuple[set[str], set[str]]: + try: + tree = ast.parse(raw, filename=str(source)) + except SyntaxError as error: + raise RuntimeError( + f"Cannot parse worker dependency source {module_name!r}." + ) from error + package = ( + module_name if source.name == "__init__.py" else module_name.rpartition(".")[0] + ) + internal: set[str] = set() + external_roots: set[str] = set() + for node in ast.walk(tree): + imported: list[str] + if isinstance(node, ast.Import): + imported = [alias.name for alias in node.names] + elif isinstance(node, ast.ImportFrom): + if node.level: + relative = "." * node.level + (node.module or "") + try: + base = importlib.util.resolve_name(relative, package) + except (ImportError, ValueError) as error: + raise RuntimeError( + f"Cannot resolve worker dependency import {relative!r} in " + f"{module_name!r}." + ) from error + else: + base = node.module or "" + imported = [base] + imported.extend( + f"{base}.{alias.name}" if base else alias.name for alias in node.names + ) + else: + continue + for name in imported: + if name in index: + internal.add(name) + elif name.startswith("microcosm"): + prefixes = name.split(".") + for length in range(len(prefixes), 0, -1): + candidate = ".".join(prefixes[:length]) + if candidate in index: + internal.add(candidate) + break + else: + root = name.partition(".")[0] + if root and root not in sys.stdlib_module_names: + external_roots.add(root) + return internal, external_roots + + +def _with_package_initializers( + module_names: set[str], + *, + index: Mapping[str, Path], +) -> set[str]: + """Include package initializers Python executes before imported modules.""" + + result = set(module_names) + for module_name in tuple(module_names): + parts = module_name.split(".") + for length in range(1, len(parts)): + package = ".".join(parts[:length]) + source = index.get(package) + if source is not None and source.name == "__init__.py": + result.add(package) + return result + + +def _validated_worker_import_trace(trace: object) -> dict[str, object]: + """Validate the private path-bearing result returned by the clean child.""" + + if not isinstance(trace, Mapping) or set(trace) != { + "module_origins", + "opened_files", + "namespace_roots", + }: + raise RuntimeError("Primary-QRF clean worker import trace schema drifted.") + raw_origins = trace["module_origins"] + if not isinstance(raw_origins, Mapping) or any( + not isinstance(name, str) + or not name + or not isinstance(origin, str) + or not origin + for name, origin in raw_origins.items() + ): + raise RuntimeError("Primary-QRF clean worker module origins are malformed.") + + def absolute_paths(field: str) -> tuple[str, ...]: + raw_paths = trace[field] + if isinstance(raw_paths, (str, bytes)) or not isinstance(raw_paths, Sequence): + raise RuntimeError( + f"Primary-QRF clean worker {field.replace('_', ' ')} are malformed." + ) + paths: list[str] = [] + for raw_path in raw_paths: + if not isinstance(raw_path, str) or not Path(raw_path).is_absolute(): + raise RuntimeError( + f"Primary-QRF clean worker {field.replace('_', ' ')} " + "must contain absolute paths." + ) + paths.append(raw_path) + return tuple(paths) + + opened_files = absolute_paths("opened_files") + namespace_roots = absolute_paths("namespace_roots") + if not namespace_roots or any(not Path(root).is_dir() for root in namespace_roots): + raise RuntimeError( + "Primary-QRF clean worker trace has no readable namespace roots." + ) + worker_origin = raw_origins.get(PRIMARY_QRF_WORKER_MODULE) + if not isinstance(worker_origin, str) or not Path(worker_origin).is_absolute(): + raise RuntimeError( + "Primary-QRF clean worker trace lacks its absolute worker origin." + ) + resolved_worker = Path(worker_origin).resolve() + if not resolved_worker.is_file() or not any( + resolved_worker.is_relative_to(Path(root).resolve()) for root in namespace_roots + ): + raise RuntimeError( + "Primary-QRF clean worker origin is outside its namespace roots." + ) + return { + "module_origins": dict(raw_origins), + "opened_files": opened_files, + "namespace_roots": namespace_roots, + } + + +@contextmanager +def primary_qrf_worker_launch_environment() -> Iterator[dict[str, str]]: + """Provide forced startup controls shared by the probe and actual worker. + + Disabling writes alone still allows Python to execute existing bytecode. + A fresh, empty cache prefix prevents source-tree or inherited-prefix caches + from being read, while the semantic identity binds only its placeholder. + """ + + with TemporaryDirectory(prefix="microcosm-qrf-pycache-") as cache_prefix: + yield { + **_WORKER_ENVIRONMENT_OVERRIDES, + "PYTHONPYCACHEPREFIX": str(Path(cache_prefix).absolute()), + } + + +def _clean_worker_import_trace() -> dict[str, object]: + """Import the worker in an isolated child and return its file-use trace.""" + + try: + with primary_qrf_worker_launch_environment() as overrides: + completed = subprocess.run( + [sys.executable, "-c", _CLEAN_WORKER_IMPORT_TRACE_SCRIPT], + env={**os.environ, **overrides}, + check=False, + capture_output=True, + text=True, + encoding="utf-8", + errors="replace", + timeout=300, + ) + except (OSError, subprocess.TimeoutExpired) as error: + raise RuntimeError("Primary-QRF clean worker import could not run.") from error + if completed.returncode != 0: + detail = completed.stderr.strip()[-2000:] + raise RuntimeError( + "Primary-QRF clean worker import failed with exit code " + f"{completed.returncode}: {detail}" + ) + payload_lines = [ + line.removeprefix(_CLEAN_WORKER_IMPORT_TRACE_MARKER) + for line in completed.stdout.splitlines() + if line.startswith(_CLEAN_WORKER_IMPORT_TRACE_MARKER) + ] + if len(payload_lines) != 1: + raise RuntimeError( + "Primary-QRF clean worker import did not return one trace payload." + ) + try: + trace = ast.literal_eval(payload_lines[0]) + except (SyntaxError, ValueError) as error: + raise RuntimeError( + "Primary-QRF clean worker import returned a malformed trace payload." + ) from error + return _validated_worker_import_trace(trace) + + +def _require_uncached_import_path(path: Path, *, boundary: str) -> Path: + """Refuse bytecode traces whose executable contents cannot be authenticated.""" + + if path.suffix in {".pyc", ".pyo"}: + raise RuntimeError( + f"{boundary} unexpectedly read bytecode despite cache isolation." + ) + return path + + +def _worker_package_resource_rows( + trace: Mapping[str, object] | None = None, +) -> list[dict[str, str]]: + """Hash every namespace file opened by a clean worker import.""" + + validated = _validated_worker_import_trace( + _clean_worker_import_trace() if trace is None else trace + ) + roots = tuple(Path(path) for path in validated["namespace_roots"]) + resolved_roots = tuple(root.resolve() for root in roots) + + def namespace_relative(path: Path) -> Path | None: + for root in roots: + try: + return path.relative_to(root) + except ValueError: + continue + resolved_path = path.resolve() + for root in resolved_roots: + try: + return resolved_path.relative_to(root) + except ValueError: + continue + return None + + rows_by_resource: dict[str, dict[str, str]] = {} + for raw_path in validated["opened_files"]: + path = Path(raw_path) + if namespace_relative(path) is None: + continue + if not path.is_file(): + raise RuntimeError( + "Primary-QRF clean worker namespace file disappeared after import: " + f"{path}." + ) + path = _require_uncached_import_path( + path, + boundary="Primary-QRF clean worker namespace import", + ) + relative = namespace_relative(path) + if relative is None: + raise RuntimeError( + "Primary-QRF clean worker file escaped its namespace root." + ) + if not relative.parts: + continue + resource = f"microcosm/{relative.as_posix()}" + try: + raw = path.read_bytes() + except OSError as error: + raise RuntimeError( + f"Cannot read primary-QRF clean worker namespace file {resource}." + ) from error + row = { + "resource": resource, + "sha256": hashlib.sha256(raw).hexdigest(), + } + previous = rows_by_resource.setdefault(resource, row) + if previous != row: + raise RuntimeError( + "Primary-QRF clean worker namespace file resolution is ambiguous: " + f"{resource}." + ) + return [rows_by_resource[key] for key in sorted(rows_by_resource)] + + +def _worker_source_identity() -> tuple[str, str, tuple[str, ...]]: + index = _module_source_index() + try: + worker_source = index[PRIMARY_QRF_WORKER_MODULE] + except KeyError as error: + raise RuntimeError( + f"Cannot locate primary-QRF worker module {PRIMARY_QRF_WORKER_MODULE!r}." + ) from error + try: + worker_raw = worker_source.read_bytes() + except OSError as error: + raise RuntimeError("Cannot read primary-QRF worker source.") from error + worker_sha256 = hashlib.sha256(worker_raw).hexdigest() + pending, external_roots = _source_imports( + PRIMARY_QRF_WORKER_MODULE, + worker_source, + worker_raw, + index=index, + ) + pending = _with_package_initializers( + pending | {PRIMARY_QRF_WORKER_MODULE}, + index=index, + ) + visited: set[str] = set() + rows: list[dict[str, str]] = [] + while pending: + module_name = min(pending) + pending.remove(module_name) + if module_name in visited or module_name == PRIMARY_QRF_WORKER_MODULE: + continue + visited.add(module_name) + source = index[module_name] + try: + raw = source.read_bytes() + except OSError as error: + raise RuntimeError( + f"Cannot read worker dependency source {module_name!r}." + ) from error + rows.append( + { + "module": module_name, + "sha256": hashlib.sha256(raw).hexdigest(), + } + ) + imported, external = _source_imports( + module_name, + source, + raw, + index=index, + ) + pending.update(_with_package_initializers(imported, index=index) - visited) + external_roots.update(external) + return worker_sha256, _canonical_sha256(rows), tuple(sorted(external_roots)) + + +def _portable_record_path(path: PurePosixPath) -> bool: + if path.is_absolute() or ".." in path.parts: + return False + if path.suffix in {".pth", ".pyc"} or "__pycache__" in path.parts: + return False + return not any(part.endswith((".dist-info", ".egg-info")) for part in path.parts) + + +def _record_hash_hex(value: str, *, boundary: str) -> str: + try: + decoded = base64.urlsafe_b64decode(value + "=" * (-len(value) % 4)) + except (ValueError, TypeError) as error: + raise RuntimeError(f"{boundary} has malformed base64url content.") from error + if len(decoded) != hashlib.sha256().digest_size: + raise RuntimeError(f"{boundary} is not a SHA-256 digest.") + return decoded.hex() + + +def _installed_distributions_record_sha256( + external_roots: Sequence[str], +) -> str: + by_name: dict[str, metadata.Distribution] = {} + package_to_distributions = metadata.packages_distributions() + torch_backend_entry_points: dict[str, list[dict[str, str]]] = {} + distributions_snapshot = tuple(metadata.distributions()) + for distribution in distributions_snapshot: + raw_name = distribution.metadata.get("Name") + if raw_name: + name = canonicalize_name(raw_name) + if name in by_name: + raise RuntimeError( + "Primary-QRF worker found duplicate installed distribution " + f"identity: {name}." + ) + by_name[name] = distribution + else: + name = None + for entry_point in distribution.entry_points: + if entry_point.group != _TORCH_BACKEND_ENTRY_POINT_GROUP: + continue + if name is None: + raise RuntimeError( + "Primary-QRF worker found a torch.backends entry-point " + "provider without an installed distribution name." + ) + torch_backend_entry_points.setdefault(name, []).append( + { + "distribution": name, + "name": entry_point.name, + "value": entry_point.value, + } + ) + + pending: set[str] = set() + unavailable_roots: list[str] = [] + resolved_roots: list[tuple[str, tuple[str, ...], tuple[Path, ...]]] = [] + for root in external_roots: + names = package_to_distributions.get(root) + spec = importlib.util.find_spec(root) + if spec is None: + unavailable_roots.append(root) + continue + if not names: + raise RuntimeError( + "Primary-QRF worker import resolves outside installed " + f"distribution metadata: {root!r}." + ) + locations: list[Path] = [] + if spec.origin is not None: + locations.append(Path(spec.origin).resolve()) + if spec.submodule_search_locations is not None: + locations.extend( + Path(location).resolve() for location in spec.submodule_search_locations + ) + if not locations: + raise RuntimeError( + f"Primary-QRF worker import {root!r} has no resolved location." + ) + canonical_names = tuple(sorted(canonicalize_name(name) for name in names)) + resolved_roots.append((root, canonical_names, tuple(sorted(set(locations))))) + pending.update(canonical_names) + + selected: set[str] = set() + while pending: + name = min(pending) + pending.remove(name) + if name in selected: + continue + try: + distribution = by_name[name] + except KeyError as error: + raise RuntimeError( + f"Primary-QRF worker dependency is not installed: {name}." + ) from error + selected.add(name) + for raw_requirement in distribution.requires or (): + try: + requirement = Requirement(raw_requirement) + except InvalidRequirement as error: + raise RuntimeError( + f"Primary-QRF worker dependency {name!r} has malformed metadata." + ) from error + if requirement.marker is not None and not requirement.marker.evaluate( + {"extra": ""} + ): + continue + dependency = canonicalize_name(requirement.name) + if dependency not in selected: + pending.add(dependency) + + unapproved_backend_providers = sorted(set(torch_backend_entry_points) - selected) + if unapproved_backend_providers: + raise RuntimeError( + "Primary-QRF worker found unapproved torch.backends entry-point " + "provider distribution(s) outside its installed-code closure: " + f"{unapproved_backend_providers}." + ) + + distributions: list[dict[str, object]] = [] + portable_paths_by_distribution: dict[str, set[Path]] = {} + for name in sorted(selected): + distribution = by_name[name] + files = distribution.files + if files is None: + raise RuntimeError( + f"Primary-QRF worker distribution has no RECORD: {name}." + ) + record_rows: list[dict[str, object]] = [] + portable_paths: set[Path] = set() + for entry in files: + path = PurePosixPath(str(entry)) + if not _portable_record_path(path): + continue + file_hash = entry.hash + if file_hash is None or file_hash.mode != "sha256": + raise RuntimeError( + f"Primary-QRF worker RECORD lacks SHA-256 for {name}:{path}." + ) + expected_hex = _record_hash_hex( + file_hash.value, + boundary=f"Primary-QRF worker RECORD {name}:{path}", + ) + installed_path = Path(entry.locate()) + try: + raw = installed_path.read_bytes() + except OSError as error: + raise RuntimeError( + f"Primary-QRF worker cannot read installed file {name}:{path}." + ) from error + observed_hex = hashlib.sha256(raw).hexdigest() + if observed_hex != expected_hex: + raise RuntimeError( + f"Primary-QRF worker installed file differs from RECORD: " + f"{name}:{path}." + ) + if entry.size is not None and len(raw) != entry.size: + raise RuntimeError( + f"Primary-QRF worker installed file size differs from RECORD: " + f"{name}:{path}." + ) + portable_paths.add(installed_path.resolve()) + record_rows.append( + { + "path": path.as_posix(), + "sha256": expected_hex, + "size": entry.size, + } + ) + portable_paths_by_distribution[name] = portable_paths + distributions.append( + { + "name": name, + "version": distribution.version, + "record_rows": record_rows, + } + ) + for root, names, locations in resolved_roots: + recorded_paths = set().union( + *(portable_paths_by_distribution.get(name, set()) for name in names) + ) + for location in locations: + if location.is_dir(): + is_recorded = any( + path.is_relative_to(location) for path in recorded_paths + ) + else: + is_recorded = location in recorded_paths + if not is_recorded: + raise RuntimeError( + "Primary-QRF worker import resolution is not authenticated " + f"by its installed RECORD: {root!r} at {location}." + ) + return _canonical_sha256( + { + "distributions": distributions, + "torch_backend_entry_points": sorted( + ( + row + for name in sorted(selected) + for row in torch_backend_entry_points.get(name, ()) + ), + key=lambda row: ( + row["distribution"], + row["name"], + row["value"], + ), + ), + "unavailable_import_roots": sorted(unavailable_roots), + } + ) + + +def _readable_runtime_path(raw_path: object) -> Path | None: + if not isinstance(raw_path, (str, os.PathLike)): + return None + try: + path = Path(raw_path).resolve() + except (OSError, RuntimeError): + return None + return path if path.is_file() else None + + +def _mapped_posix_python_runtime() -> Path | None: + """Resolve the image containing Py_GetVersion with dladdr when available.""" + + if os.name != "posix": + return None + + class DlInfo(ctypes.Structure): + _fields_ = ( + ("filename", ctypes.c_char_p), + ("base_address", ctypes.c_void_p), + ("symbol_name", ctypes.c_char_p), + ("symbol_address", ctypes.c_void_p), + ) + + address = ctypes.cast(ctypes.pythonapi.Py_GetVersion, ctypes.c_void_p) + library_names: list[str | None] = [None] + libdl = ctypes.util.find_library("dl") + if libdl: + library_names.append(libdl) + for library_name in library_names: + try: + library = ctypes.CDLL(library_name) + dladdr = library.dladdr + except (AttributeError, OSError): + continue + dladdr.argtypes = (ctypes.c_void_p, ctypes.POINTER(DlInfo)) + dladdr.restype = ctypes.c_int + info = DlInfo() + if dladdr(address, ctypes.byref(info)) and info.filename: + path = _readable_runtime_path(os.fsdecode(info.filename)) + if path is not None: + return path + return None + + +def _mapped_windows_python_runtime() -> Path | None: + if os.name != "nt": + return None + try: + kernel32 = ctypes.WinDLL("kernel32", use_last_error=True) + get_module_handle = kernel32.GetModuleHandleExW + get_module_filename = kernel32.GetModuleFileNameW + except (AttributeError, OSError): + return None + get_module_handle.argtypes = ( + ctypes.c_uint32, + ctypes.c_void_p, + ctypes.POINTER(ctypes.c_void_p), + ) + get_module_handle.restype = ctypes.c_int + get_module_filename.argtypes = ( + ctypes.c_void_p, + ctypes.c_wchar_p, + ctypes.c_uint32, + ) + get_module_filename.restype = ctypes.c_uint32 + address = ctypes.cast(ctypes.pythonapi.Py_GetVersion, ctypes.c_void_p) + handle = ctypes.c_void_p() + from_address_unchanged_refcount = 0x00000004 | 0x00000002 + if not get_module_handle( + from_address_unchanged_refcount, + address, + ctypes.byref(handle), + ): + return None + buffer = ctypes.create_unicode_buffer(32768) + length = get_module_filename( + handle, + buffer, + ctypes.sizeof(buffer) // ctypes.sizeof(ctypes.c_wchar), + ) + if not length or length >= len(buffer): + return None + return _readable_runtime_path(buffer.value) + + +def _mapped_proc_python_runtime() -> Path | None: + maps_path = Path("/proc/self/maps") + if not maps_path.is_file(): + return None + try: + lines = maps_path.read_text( + encoding="utf-8", errors="surrogateescape" + ).splitlines() + except OSError: + return None + candidates: set[Path] = set() + for line in lines: + slash = line.find("/") + if slash < 0: + continue + raw_path = line[slash:] + if raw_path.endswith(" (deleted)") or "libpython" not in Path(raw_path).name: + continue + path = _readable_runtime_path(raw_path) + if path is not None: + candidates.add(path) + if len(candidates) > 1: + raise RuntimeError( + "Primary-QRF worker found multiple mapped Python runtime libraries." + ) + return next(iter(candidates), None) + + +def _configured_python_runtime() -> Path | None: + names: set[str] = set() + for key in ("INSTSONAME", "LDLIBRARY", "DLLLIBRARY"): + value = sysconfig.get_config_var(key) + if isinstance(value, str) and value: + names.add(value) + directories: set[Path] = set() + for key in ("LIBDIR", "LIBPL", "BINDIR"): + value = sysconfig.get_config_var(key) + if isinstance(value, str) and value: + directories.add(Path(value)) + directories.update({Path(sys.base_prefix), Path(sys.executable).parent}) + candidates: set[Path] = set() + for name in names: + configured = Path(name) + if configured.is_absolute(): + paths = (configured,) + else: + paths = tuple(directory / configured for directory in directories) + for raw_path in paths: + path = _readable_runtime_path(raw_path) + if path is not None and path.suffix not in {".a", ".lib"}: + candidates.add(path) + if len(candidates) > 1: + raise RuntimeError( + "Primary-QRF worker Python runtime configuration is ambiguous." + ) + return next(iter(candidates), None) + + +def _loaded_python_runtime_binary() -> tuple[str, Path]: + """Return the exact shared runtime image, or the executable for static Python.""" + + executable = Path(sys.executable).resolve() + mapped = ( + _mapped_windows_python_runtime() + or _mapped_posix_python_runtime() + or _mapped_proc_python_runtime() + ) + if mapped is not None: + kind = ( + "statically_linked_executable" if mapped == executable else "shared_library" + ) + return kind, mapped + shared = sysconfig.get_config_var("Py_ENABLE_SHARED") + if shared in (0, "0"): + if not executable.is_file(): + raise RuntimeError( + "Primary-QRF worker cannot read its static Python runtime executable." + ) + return "statically_linked_executable", executable + configured = _configured_python_runtime() + if configured is not None: + kind = ( + "statically_linked_executable" + if configured == executable + else "shared_library" + ) + return kind, configured + raise RuntimeError("Primary-QRF worker cannot resolve its loaded Python runtime.") + + +def _worker_stdlib_roots() -> tuple[tuple[tuple[str, Path], ...], tuple[Path, ...]]: + configured_paths = sysconfig.get_paths() + excluded_roots = tuple( + Path(path).resolve() + for name in ("purelib", "platlib") + if isinstance((path := configured_paths.get(name)), str) and path + ) + roots: list[tuple[str, Path]] = [] + for name in ("stdlib", "platstdlib"): + raw_root = configured_paths.get(name) + if not isinstance(raw_root, str) or not raw_root: + continue + root = Path(raw_root).resolve() + if all(existing != root for _, existing in roots): + roots.append((name, root)) + destination_shared = sysconfig.get_config_var("DESTSHARED") + if isinstance(destination_shared, str) and destination_shared: + root = Path(destination_shared).resolve() + if all(existing != root for _, existing in roots): + roots.append(("destshared", root)) + return tuple(roots), excluded_roots + + +def _stdlib_import_path( + origin: Path, + *, + module_name: str, + roots: Sequence[tuple[str, Path]], + excluded_roots: Sequence[Path], +) -> tuple[Path, str] | None: + if not origin.is_absolute(): + return None + resolved_origin = origin.resolve() + if any(resolved_origin.is_relative_to(root) for root in excluded_roots): + return None + stdlib_relative: Path | None = None + for _, root in roots: + try: + stdlib_relative = resolved_origin.relative_to(root) + break + except ValueError: + continue + if stdlib_relative is None: + return None + if any( + part in {"site-packages", "dist-packages"} for part in stdlib_relative.parts + ): + return None + source = _require_uncached_import_path( + origin, + boundary=f"Primary-QRF worker stdlib module {module_name!r}", + ) + resolved_source = source.resolve() + for root_name, root in roots: + try: + relative = resolved_source.relative_to(root) + except ValueError: + continue + return resolved_source, f"{root_name}/{relative.as_posix()}" + raise RuntimeError( + f"Primary-QRF worker stdlib module {module_name!r} escaped its stdlib root." + ) + + +def _stdlib_import_row( + module_name: str, + source: Path, + portable_path: str, +) -> dict[str, str]: + if not source.is_file(): + raise RuntimeError( + f"Primary-QRF worker stdlib module {module_name!r} is unreadable." + ) + try: + raw = source.read_bytes() + except OSError as error: + raise RuntimeError( + f"Cannot read primary-QRF worker stdlib module {module_name!r}." + ) from error + if source.suffix in {".py", ".pyw"}: + kind = "source" + elif any( + str(source).endswith(suffix) + for suffix in importlib.machinery.EXTENSION_SUFFIXES + ): + kind = "extension" + else: + kind = "file" + return { + "module": module_name, + "path": portable_path, + "kind": kind, + "sha256": hashlib.sha256(raw).hexdigest(), + } + + +def _worker_stdlib_import_rows( + trace: Mapping[str, object], +) -> list[dict[str, str]]: + """Hash file-backed stdlib modules present after the clean worker import.""" + + validated = _validated_worker_import_trace(trace) + roots, excluded_roots = _worker_stdlib_roots() + module_origins = validated["module_origins"] + assert isinstance(module_origins, Mapping) + rows: list[dict[str, str]] = [] + bound_paths: set[str] = set() + for module_name, raw_origin in sorted(module_origins.items()): + assert isinstance(module_name, str) + assert isinstance(raw_origin, str) + resolved = _stdlib_import_path( + Path(raw_origin), + module_name=module_name, + roots=roots, + excluded_roots=excluded_roots, + ) + if resolved is None: + continue + source, portable_path = resolved + bound_paths.add(portable_path) + rows.append(_stdlib_import_row(module_name, source, portable_path)) + for raw_path in validated["opened_files"]: + resolved = _stdlib_import_path( + Path(raw_path), + module_name="", + roots=roots, + excluded_roots=excluded_roots, + ) + if resolved is None: + continue + source, portable_path = resolved + if portable_path in bound_paths: + continue + bound_paths.add(portable_path) + rows.append(_stdlib_import_row("", source, portable_path)) + return sorted(rows, key=lambda row: (row["module"], row["path"])) + + +def _canonical_pyvenv_config() -> dict[str, object]: + path = Path(sys.prefix) / "pyvenv.cfg" + try: + lines = path.read_text(encoding="utf-8").splitlines() + except OSError as error: + raise RuntimeError( + f"Primary-QRF worker cannot read semantic virtualenv config {path}." + ) from error + parsed: dict[str, str] = {} + for line_number, raw_line in enumerate(lines, start=1): + line = raw_line.strip() + if not line or line.startswith("#"): + continue + key, separator, value = line.partition("=") + normalized_key = key.strip().lower().replace("_", "-") + if not separator or not normalized_key or normalized_key in parsed: + raise RuntimeError( + f"Primary-QRF worker has malformed pyvenv.cfg line {line_number}." + ) + parsed[normalized_key] = value.strip() + implementation = parsed.get("implementation") + version_text = parsed.get("version-info", parsed.get("version")) + include_system = parsed.get("include-system-site-packages") + uv_version = parsed.get("uv") + if not all( + isinstance(value, str) and value + for value in (implementation, version_text, uv_version) + ): + raise RuntimeError("Primary-QRF worker pyvenv.cfg lacks semantic uv fields.") + assert version_text is not None + try: + declared_version = [int(part) for part in version_text.split(".")] + except ValueError as error: + raise RuntimeError( + "Primary-QRF worker pyvenv.cfg version is not numeric." + ) from error + # uv writes ``version_info`` as ``major.minor.micro`` (<= 0.11) or + # ``major.minor`` (>= 0.12); the canonical form is the running + # interpreter's triplet, which the declared prefix must match. + if len(declared_version) not in {2, 3}: + raise RuntimeError( + "Primary-QRF worker pyvenv.cfg version must be major.minor or " + "major.minor.micro." + ) + version = list(sys.version_info[:3]) + if declared_version != version[: len(declared_version)]: + raise RuntimeError( + "Primary-QRF worker pyvenv.cfg version does not match the running " + f"interpreter: declared {version_text!r}, running " + f"{'.'.join(str(part) for part in version)!r}." + ) + if include_system not in {"true", "false"}: + raise RuntimeError( + "Primary-QRF worker pyvenv.cfg has invalid include-system-site-packages." + ) + return { + "implementation": implementation.casefold(), + "version": version, + "include_system_site_packages": include_system == "true", + "uv_version": uv_version, + } + + +def _semantic_environment() -> dict[str, object]: + fit_jobs_raw = os.environ.get("POPULACE_FIT_N_JOBS") + if fit_jobs_raw is None: + fit_jobs = -1 + else: + try: + fit_jobs = int(fit_jobs_raw) + except ValueError as error: + raise ValueError( + "POPULACE_FIT_N_JOBS must be a positive integer for the " + "primary-QRF worker binding." + ) from error + if fit_jobs < 1 or str(fit_jobs) != fit_jobs_raw: + raise ValueError( + "POPULACE_FIT_N_JOBS must be a canonical positive integer for " + "the primary-QRF worker binding." + ) + predict_workers_raw = os.environ.get("POPULACE_FIT_PREDICT_WORKERS") + if predict_workers_raw is None or not predict_workers_raw.strip(): + predict_workers = os.cpu_count() or 1 + predict_workers_source = "os_cpu_count_fallback" + else: + try: + predict_workers = int(predict_workers_raw) + except ValueError as error: + raise ValueError( + "POPULACE_FIT_PREDICT_WORKERS must be a positive integer for the " + "primary-QRF worker binding." + ) from error + if predict_workers < 1 or str(predict_workers) != predict_workers_raw: + raise ValueError( + "POPULACE_FIT_PREDICT_WORKERS must be a canonical positive " + "integer for the primary-QRF worker binding." + ) + predict_workers_source = "environment_override" + return { + "policy": ( + "inherit_parent_environment_with_bound_fit_controls_and_forced_overrides" + ), + "overrides": dict(_WORKER_ENVIRONMENT_OVERRIDES), + "semantic_controls": { + "POPULACE_FIT_N_JOBS": { + "configured": fit_jobs_raw, + "resolved": fit_jobs, + }, + "POPULACE_FIT_PREDICT_WORKERS": { + "configured": predict_workers_raw, + "resolved": predict_workers, + "resolution": predict_workers_source, + }, + }, + "bound_names": list(_BOUND_ENVIRONMENT_NAMES), + } + + +def clear_primary_qrf_worker_identity_cache() -> None: + """Clear process attestations after deliberate runtime or source mutations.""" + + _PRIMARY_QRF_WORKER_IDENTITY_CACHE.clear() + + +def primary_qrf_worker_semantic_identity( + *, + uv_lock_sha256: str | None = None, +) -> dict[str, object]: + """Return the shared canonical worker identity, excluding launcher aliases. + + A process's interpreter, source tree, and installed distributions are + attested once per process for each lock and bound-environment combination. + Anything that deliberately mutates them must call + ``clear_primary_qrf_worker_identity_cache()`` before reattesting. The + returned object graph is shared across calls and must be treated as read-only. + + The raw lock argument is part of the key: ``None`` validates the checkout's + lock on its first cache miss and after clearing, while explicit approved + and legacy digests have separate entries. Bound environment values are + likewise keyed by their raw configured strings so validation is preserved. + """ + + if uv_lock_sha256 is not None: + _require_sha256(uv_lock_sha256, boundary="primary-QRF worker lock") + key = ( + uv_lock_sha256, + os.environ.get("POPULACE_FIT_N_JOBS"), + os.environ.get("POPULACE_FIT_PREDICT_WORKERS"), + ) + if key not in _PRIMARY_QRF_WORKER_IDENTITY_CACHE: + _PRIMARY_QRF_WORKER_IDENTITY_CACHE[key] = ( + _uncached_primary_qrf_worker_semantic_identity( + uv_lock_sha256=uv_lock_sha256 + ) + ) + return _PRIMARY_QRF_WORKER_IDENTITY_CACHE[key] + + +def _uncached_primary_qrf_worker_semantic_identity( + *, + uv_lock_sha256: str | None = None, +) -> dict[str, object]: + """Build the canonical worker identity, excluding all launcher aliases.""" + + if uv_lock_sha256 is None: + lock_sha256 = _approved_uv_lock_sha256() + else: + lock_sha256 = _require_sha256( + uv_lock_sha256, boundary="primary-QRF worker lock" + ) + if lock_sha256 not in { + APPROVED_UV_LOCK_SHA256, + LEGACY_CAMPAIGN_UV_LOCK_SHA256, + }: + raise ValueError("Primary-QRF worker lock is not approved.") + executable = Path(sys.executable) + module_sha256, static_imports_sha256, external_roots = _worker_source_identity() + record_sha256 = _installed_distributions_record_sha256(external_roots) + try: + executable_sha256 = hashlib.sha256(executable.read_bytes()).hexdigest() + except OSError as error: + raise RuntimeError( + "Primary-QRF worker cannot read its interpreter executable." + ) from error + runtime_kind, runtime_path = _loaded_python_runtime_binary() + try: + runtime_sha256 = hashlib.sha256(runtime_path.read_bytes()).hexdigest() + except OSError as error: + raise RuntimeError( + "Primary-QRF worker cannot read its loaded Python runtime." + ) from error + pyvenv_config = _canonical_pyvenv_config() + environment = _semantic_environment() + import_trace = _clean_worker_import_trace() + namespace_rows = _worker_package_resource_rows(import_trace) + imports_sha256 = _canonical_sha256( + { + "static_python_imports_sha256": static_imports_sha256, + "clean_import_namespace_files": namespace_rows, + } + ) + stdlib_imports_sha256 = _canonical_sha256(_worker_stdlib_import_rows(import_trace)) + environment_code_sha256 = _canonical_sha256( + { + "worker_module_source_sha256": module_sha256, + "transitive_imports_sha256": imports_sha256, + "installed_distributions_record_sha256": record_sha256, + } + ) + return { + "interpreter": { + "bytes_sha256": executable_sha256, + "runtime_binary": { + "kind": runtime_kind, + "bytes_sha256": runtime_sha256, + }, + "stdlib_imports_sha256": stdlib_imports_sha256, + "implementation": sys.implementation.name, + "version": list(sys.version_info[:3]), + "abi": { + "soabi": sysconfig.get_config_var("SOABI") or "", + "abiflags": sys.abiflags, + }, + "cache_tag": sys.implementation.cache_tag, + "pyvenv_cfg": pyvenv_config, + }, + "worker_module": { + "name": PRIMARY_QRF_WORKER_MODULE, + "source_sha256": module_sha256, + "transitive_imports_sha256": imports_sha256, + }, + "uv_lock_sha256": lock_sha256, + "installed_distributions_record_sha256": record_sha256, + "transitive_environment_code_sha256": environment_code_sha256, + "argv_template": [ + PRIMARY_QRF_INTERPRETER_PLACEHOLDER, + "-m", + PRIMARY_QRF_WORKER_MODULE, + "--checkpoint-dir", + "{checkpoint_dir}", + "--target-index", + "{target_index}", + ], + "environment": environment, + } + + +def primary_qrf_worker_execution_binding() -> dict[str, object]: + """Return semantic worker identity plus integrity-bound audit aliases.""" + + raw_executable = sys.executable + executable = Path(raw_executable).absolute() + # Execution bindings become mutable artifact payloads; their edits must + # never change the shared identity used to authenticate later bindings. + semantic_identity = _json_clone(primary_qrf_worker_semantic_identity()) + assert isinstance(semantic_identity, dict) + result = { + "schema_version": PRIMARY_QRF_WORKER_IDENTITY_SCHEMA_VERSION, + "semantic_identity": semantic_identity, + "semantic_identity_sha256": _canonical_sha256(semantic_identity), + "audit_aliases": { + "sys_executable": str(executable), + "sys_prefix": str(Path(sys.prefix).absolute()), + "argv_template_0": raw_executable, + }, + } + validate_primary_qrf_worker_execution_binding( + result, + boundary="primary-QRF worker identity construction", + ) + return result + + +def _validate_semantic_identity( + semantic: object, *, boundary: str +) -> Mapping[str, object]: + value = _require_exact_keys( + semantic, + { + "interpreter", + "worker_module", + "uv_lock_sha256", + "installed_distributions_record_sha256", + "transitive_environment_code_sha256", + "argv_template", + "environment", + }, + boundary=boundary, + ) + for key in ( + "uv_lock_sha256", + "installed_distributions_record_sha256", + "transitive_environment_code_sha256", + ): + _require_sha256(value.get(key), boundary=f"{boundary} {key}") + worker_module = _require_exact_keys( + value.get("worker_module"), + {"name", "source_sha256", "transitive_imports_sha256"}, + boundary=f"{boundary} worker module", + ) + if worker_module.get("name") != PRIMARY_QRF_WORKER_MODULE: + raise ValueError(f"{boundary} worker module name changed.") + _require_sha256( + worker_module.get("source_sha256"), boundary=f"{boundary} worker source" + ) + _require_sha256( + worker_module.get("transitive_imports_sha256"), + boundary=f"{boundary} transitive imports", + ) + expected_environment_code = _canonical_sha256( + { + "worker_module_source_sha256": worker_module["source_sha256"], + "transitive_imports_sha256": worker_module["transitive_imports_sha256"], + "installed_distributions_record_sha256": value[ + "installed_distributions_record_sha256" + ], + } + ) + if value.get("transitive_environment_code_sha256") != expected_environment_code: + raise ValueError(f"{boundary} transitive environment/code digest changed.") + interpreter = _require_exact_keys( + value.get("interpreter"), + { + "bytes_sha256", + "runtime_binary", + "stdlib_imports_sha256", + "implementation", + "version", + "abi", + "cache_tag", + "pyvenv_cfg", + }, + boundary=f"{boundary} interpreter", + ) + _require_sha256( + interpreter.get("bytes_sha256"), boundary=f"{boundary} interpreter bytes" + ) + runtime_binary = _require_exact_keys( + interpreter.get("runtime_binary"), + {"kind", "bytes_sha256"}, + boundary=f"{boundary} runtime binary", + ) + if runtime_binary.get("kind") not in { + "shared_library", + "statically_linked_executable", + }: + raise ValueError(f"{boundary} runtime binary kind is invalid.") + _require_sha256( + runtime_binary.get("bytes_sha256"), + boundary=f"{boundary} runtime binary bytes", + ) + _require_sha256( + interpreter.get("stdlib_imports_sha256"), + boundary=f"{boundary} stdlib imports", + ) + _require_string( + interpreter.get("implementation"), boundary=f"{boundary} implementation" + ) + _require_string(interpreter.get("cache_tag"), boundary=f"{boundary} cache tag") + version = interpreter.get("version") + if ( + not isinstance(version, list) + or len(version) != 3 + or any( + isinstance(item, bool) or not isinstance(item, int) or item < 0 + for item in version + ) + ): + raise ValueError(f"{boundary} interpreter version must be an integer triplet.") + abi = _require_exact_keys( + interpreter.get("abi"), {"soabi", "abiflags"}, boundary=f"{boundary} ABI" + ) + _require_string(abi.get("soabi"), boundary=f"{boundary} SOABI") + _require_string( + abi.get("abiflags"), boundary=f"{boundary} ABI flags", allow_empty=True + ) + pyvenv = _require_exact_keys( + interpreter.get("pyvenv_cfg"), + {"implementation", "version", "include_system_site_packages", "uv_version"}, + boundary=f"{boundary} pyvenv.cfg", + ) + _require_string( + pyvenv.get("implementation"), boundary=f"{boundary} pyvenv implementation" + ) + _require_string(pyvenv.get("uv_version"), boundary=f"{boundary} pyvenv uv version") + pyvenv_version = pyvenv.get("version") + if ( + not isinstance(pyvenv_version, list) + or len(pyvenv_version) != 3 + or any( + isinstance(item, bool) or not isinstance(item, int) or item < 0 + for item in pyvenv_version + ) + or type(pyvenv.get("include_system_site_packages")) is not bool + ): + raise ValueError(f"{boundary} pyvenv.cfg semantic fields are malformed.") + expected_argv = [ + PRIMARY_QRF_INTERPRETER_PLACEHOLDER, + "-m", + PRIMARY_QRF_WORKER_MODULE, + "--checkpoint-dir", + "{checkpoint_dir}", + "--target-index", + "{target_index}", + ] + if value.get("argv_template") != expected_argv: + raise ValueError(f"{boundary} semantic argv template changed.") + environment = _require_exact_keys( + value.get("environment"), + {"policy", "overrides", "semantic_controls", "bound_names"}, + boundary=f"{boundary} environment", + ) + if ( + environment.get("policy") + != "inherit_parent_environment_with_bound_fit_controls_and_forced_overrides" + or environment.get("overrides") != _WORKER_ENVIRONMENT_OVERRIDES + or environment.get("bound_names") != list(_BOUND_ENVIRONMENT_NAMES) + ): + raise ValueError(f"{boundary} semantic environment policy changed.") + controls = _require_exact_keys( + environment.get("semantic_controls"), + set(_SEMANTIC_ENVIRONMENT_NAMES), + boundary=f"{boundary} semantic controls", + ) + fit = _require_exact_keys( + controls.get("POPULACE_FIT_N_JOBS"), + {"configured", "resolved"}, + boundary=f"{boundary} fit jobs", + ) + predict = _require_exact_keys( + controls.get("POPULACE_FIT_PREDICT_WORKERS"), + {"configured", "resolved", "resolution"}, + boundary=f"{boundary} predict workers", + ) + if fit.get("configured") is not None and not isinstance(fit.get("configured"), str): + raise ValueError(f"{boundary} configured fit jobs must be a string or null.") + if predict.get("configured") is not None and not isinstance( + predict.get("configured"), str + ): + raise ValueError( + f"{boundary} configured predict workers must be a string or null." + ) + if ( + isinstance(fit.get("resolved"), bool) + or not isinstance(fit.get("resolved"), int) + or int(fit["resolved"]) < -1 + or fit.get("resolved") == 0 + or isinstance(predict.get("resolved"), bool) + or not isinstance(predict.get("resolved"), int) + or int(predict["resolved"]) < 1 + or predict.get("resolution") + not in {"environment_override", "os_cpu_count_fallback"} + ): + raise ValueError(f"{boundary} resolved worker controls are malformed.") + return value + + +def validate_primary_qrf_worker_execution_binding( + binding: object, + *, + boundary: str, +) -> None: + """Validate the closed v1 worker identity and its semantic self-digest.""" + + worker = _require_exact_keys( + binding, + { + "schema_version", + "semantic_identity", + "semantic_identity_sha256", + "audit_aliases", + }, + boundary=boundary, + ) + if worker.get("schema_version") != PRIMARY_QRF_WORKER_IDENTITY_SCHEMA_VERSION: + raise ValueError( + f"{boundary} requires schema version " + f"{PRIMARY_QRF_WORKER_IDENTITY_SCHEMA_VERSION}." + ) + semantic = _validate_semantic_identity( + worker.get("semantic_identity"), boundary=f"{boundary} semantic_identity" + ) + semantic_sha256 = _require_sha256( + worker.get("semantic_identity_sha256"), + boundary=f"{boundary} semantic_identity_sha256", + ) + if semantic_sha256 != _canonical_sha256(semantic): + raise ValueError(f"{boundary} semantic identity SHA-256 mismatch.") + aliases = _require_exact_keys( + worker.get("audit_aliases"), + {"sys_executable", "sys_prefix", "argv_template_0"}, + boundary=f"{boundary} audit aliases", + ) + for name, value in aliases.items(): + _require_string(value, boundary=f"{boundary} audit alias {name}") + if name in {"sys_executable", "sys_prefix"} and not Path(value).is_absolute(): + raise ValueError(f"{boundary} audit alias {name} must be absolute.") + + +def _validated_primary_qrf_worker_semantic_identity( + binding: object, + *, + boundary: str, +) -> Mapping[str, object]: + validate_primary_qrf_worker_execution_binding(binding, boundary=boundary) + assert isinstance(binding, Mapping) + semantic = binding["semantic_identity"] + assert isinstance(semantic, Mapping) + return semantic + + +def primary_qrf_worker_semantic_projection( + binding: object, + *, + boundary: str, +) -> dict[str, object]: + """Project a binding for identities that must never hash audit aliases.""" + + semantic = _validated_primary_qrf_worker_semantic_identity( + binding, boundary=boundary + ) + assert isinstance(binding, Mapping) + return { + "schema_version": binding["schema_version"], + "semantic_identity": _json_clone(semantic), + "semantic_identity_sha256": binding["semantic_identity_sha256"], + } + + +def primary_qrf_worker_bindings_semantically_equal( + left: object, + right: object, + *, + boundary: str, +) -> bool: + """Compare validated semantic identities while ignoring launcher aliases.""" + + return _validated_primary_qrf_worker_semantic_identity( + left, boundary=f"{boundary} recorded worker" + ) == _validated_primary_qrf_worker_semantic_identity( + right, boundary=f"{boundary} live worker" + ) + + +def legacy_primary_qrf_worker_execution_binding( + *, + semantic_identity: Mapping[str, object] | None = None, +) -> dict[str, object]: + """Project the live worker into the frozen schema-4 execution shape.""" + + semantic = ( + primary_qrf_worker_semantic_identity( + uv_lock_sha256=LEGACY_CAMPAIGN_UV_LOCK_SHA256 + ) + if semantic_identity is None + else semantic_identity + ) + _validate_semantic_identity( + semantic, boundary="legacy live worker semantic identity" + ) + executable = Path(sys.executable) + worker_module = semantic["worker_module"] + argv = semantic["argv_template"] + assert isinstance(worker_module, Mapping) + assert isinstance(argv, list) + environment = _json_clone(semantic["environment"]) + assert isinstance(environment, dict) + # The sealed schema-9 worker predates the forced Torch override. Keep its + # recorded execution projection frozen so the plan-authorized compatibility + # mismatch remains exactly the two relocated launcher aliases. The attested + # semantic identity above still binds and enforces the current safe policy. + environment["policy"] = "inherit_parent_environment_with_bound_fit_controls" + environment["overrides"] = {} + environment["bound_names"] = list(_SEMANTIC_ENVIRONMENT_NAMES) + return { + "module": worker_module["name"], + "argv_template": [str(executable), *argv[1:]], + "interpreter": { + "executable": str(executable), + "resolved_executable": str(executable.resolve()), + "implementation": sys.implementation.name, + "cache_tag": sys.implementation.cache_tag, + "version": list(sys.version_info[:3]), + }, + "environment": environment, + } + + +def _legacy_worker_execution_mismatch_paths( + recorded: object, + live: object, +) -> tuple[str, ...]: + """Return deterministic leaf paths that differ in two legacy bindings.""" + + mismatches: list[str] = [] + + def visit(left: object, right: object, path: str) -> None: + if isinstance(left, Mapping) and isinstance(right, Mapping): + for key in sorted(set(left) | set(right), key=str): + child = f"{path}.{key}" if path else str(key) + if key not in left or key not in right: + mismatches.append(child) + else: + visit(left[key], right[key], child) + return + if ( + isinstance(left, Sequence) + and not isinstance(left, (str, bytes)) + and isinstance(right, Sequence) + and not isinstance(right, (str, bytes)) + ): + for index in range(max(len(left), len(right))): + child = f"{path}[{index}]" + if index >= len(left) or index >= len(right): + mismatches.append(child) + else: + visit(left[index], right[index], child) + return + if left != right: + mismatches.append(path or "$") + + visit(recorded, live, "") + return tuple(mismatches) + + +def authenticate_legacy_worker_identity_attestation( + path: str | Path, + *, + sealed_manifest_sha256: str, + sealed_pool_h5_sha256: str, + recorded_worker_execution: object, + boundary: str, +) -> LegacyWorkerIdentityAuthentication: + """Authenticate the explicit plan-gated schema-9 scoring exception.""" + + attestation_path = Path(path) + try: + raw = attestation_path.read_bytes() + parsed = json.loads(raw) + except (OSError, UnicodeDecodeError, json.JSONDecodeError) as error: + raise ValueError( + f"{boundary}: worker identity attestation is unreadable." + ) from error + attestation = _require_exact_keys(parsed, _ATTESTATION_KEYS, boundary=boundary) + if ( + attestation.get("artifact_kind") != LEGACY_WORKER_ATTESTATION_ARTIFACT_KIND + or attestation.get("schema_version") != LEGACY_WORKER_ATTESTATION_SCHEMA_VERSION + or attestation.get("purpose") != "scoring_only" + or attestation.get("plan_signature") != _PLAN_SIGNATURE + ): + raise ValueError(f"{boundary}: worker identity attestation authority changed.") + manifest_sha256 = _require_sha256( + attestation.get("sealed_manifest_sha256"), + boundary=f"{boundary} sealed manifest", + ) + pool_sha256 = _require_sha256( + attestation.get("sealed_pool_h5_sha256"), + boundary=f"{boundary} sealed pool H5", + ) + if manifest_sha256 != sealed_manifest_sha256: + raise ValueError( + f"{boundary}: worker identity attestation sealed manifest changed." + ) + if pool_sha256 != sealed_pool_h5_sha256: + raise ValueError(f"{boundary}: worker identity attestation sealed H5 changed.") + campaign_tree_sha = attestation.get("campaign_tree_sha") + if campaign_tree_sha != LEGACY_CAMPAIGN_TREE_SHA: + raise ValueError(f"{boundary}: worker identity attestation campaign changed.") + assert isinstance(campaign_tree_sha, str) + if attestation.get("uv_lock_sha256") != LEGACY_CAMPAIGN_UV_LOCK_SHA256: + raise ValueError(f"{boundary}: worker identity attestation lock changed.") + if attestation.get("recorded_worker_execution") != recorded_worker_execution: + raise ValueError(f"{boundary}: attested recorded worker changed.") + if attestation.get("permitted_mismatches") != list( + LEGACY_WORKER_PERMITTED_MISMATCHES + ): + raise ValueError(f"{boundary}: permitted worker mismatches changed.") + semantic = _validate_semantic_identity( + attestation.get("semantic_identity"), + boundary=f"{boundary} attested semantic identity", + ) + semantic_sha256 = _require_sha256( + attestation.get("semantic_identity_sha256"), + boundary=f"{boundary} semantic identity", + ) + if semantic_sha256 != _canonical_sha256(semantic): + raise ValueError(f"{boundary}: attested semantic identity digest changed.") + if semantic.get( + "uv_lock_sha256" + ) != LEGACY_CAMPAIGN_UV_LOCK_SHA256 or attestation.get( + "installed_transitive_environment_code_sha256" + ) != semantic.get("transitive_environment_code_sha256"): + raise ValueError(f"{boundary}: attested environment/code identity changed.") + expected_semantic = primary_qrf_worker_semantic_identity( + uv_lock_sha256=LEGACY_CAMPAIGN_UV_LOCK_SHA256 + ) + if semantic != expected_semantic: + raise ValueError(f"{boundary}: semantic worker identity changed.") + live_worker = legacy_primary_qrf_worker_execution_binding( + semantic_identity=expected_semantic + ) + if ( + _legacy_worker_execution_mismatch_paths(recorded_worker_execution, live_worker) + != LEGACY_WORKER_PERMITTED_MISMATCHES + ): + raise ValueError(f"{boundary}: legacy worker mismatch set changed.") + recorded = _json_clone(recorded_worker_execution) + semantic_copy = _json_clone(semantic) + assert isinstance(recorded, Mapping) + assert isinstance(semantic_copy, Mapping) + return LegacyWorkerIdentityAuthentication( + attestation_sha256=hashlib.sha256(raw).hexdigest(), + campaign_tree_sha=campaign_tree_sha, + recorded_worker_execution=recorded, + semantic_identity=semantic_copy, + semantic_identity_sha256=semantic_sha256, + ) + + +def current_worker_execution_authentication_receipt( + binding: object, + *, + manifest_schema_version: int, + execution_config_schema_version: int, + boundary: str, +) -> dict[str, object]: + """Describe the validated current worker identity without trusting aliases.""" + + validate_primary_qrf_worker_execution_binding(binding, boundary=boundary) + assert isinstance(binding, Mapping) + aliases = binding["audit_aliases"] + assert isinstance(aliases, Mapping) + return { + "manifest_schema_version": manifest_schema_version, + "execution_config_schema_version": execution_config_schema_version, + "worker_execution_schema_version": binding["schema_version"], + "semantic_identity_sha256": binding["semantic_identity_sha256"], + "audit_aliases": _json_clone(aliases), + } + + +__all__ = [ + "APPROVED_UV_LOCK_SHA256", + "LEGACY_CAMPAIGN_TREE_SHA", + "LEGACY_CAMPAIGN_UV_LOCK_SHA256", + "LEGACY_WORKER_PERMITTED_MISMATCHES", + "LegacyWorkerIdentityAuthentication", + "PRIMARY_QRF_INTERPRETER_PLACEHOLDER", + "PRIMARY_QRF_WORKER_IDENTITY_SCHEMA_VERSION", + "PRIMARY_QRF_WORKER_MODULE", + "_legacy_worker_execution_mismatch_paths", + "authenticate_legacy_worker_identity_attestation", + "clear_primary_qrf_worker_identity_cache", + "current_worker_execution_authentication_receipt", + "legacy_primary_qrf_worker_execution_binding", + "primary_qrf_worker_bindings_semantically_equal", + "primary_qrf_worker_execution_binding", + "primary_qrf_worker_semantic_identity", + "primary_qrf_worker_semantic_projection", + "validate_primary_qrf_worker_execution_binding", +] diff --git a/packages/microcosm-build/tests/conftest.py b/packages/microcosm-build/tests/conftest.py index ac3f6b9dc..e3c4e53ae 100644 --- a/packages/microcosm-build/tests/conftest.py +++ b/packages/microcosm-build/tests/conftest.py @@ -104,3 +104,64 @@ class ODSBuilder: def ods() -> ODSBuilder: """Helpers for writing a small ODS file to a temporary path.""" return ODSBuilder() + + +@pytest.fixture(scope="session") +def _session_primary_qrf_worker_identities(): + """Attest the real installed worker once; retain pristine identities by key. + + Additional lock/control keys (such as the sealed legacy lock) are populated + by the real code on first use in ordinary tests, never by a fabricated identity. + Import lazily so unrelated build tests need neither US extras nor a probe. + """ + from copy import deepcopy + + from microcosm.build.us_runtime import worker_identity + + worker_identity.clear_primary_qrf_worker_identity_cache() + worker_identity.primary_qrf_worker_semantic_identity() + return deepcopy(worker_identity._PRIMARY_QRF_WORKER_IDENTITY_CACHE) + + +@pytest.fixture +def prime_primary_qrf_worker_identity(request: pytest.FixtureRequest): + """Restore the session attestation for pipeline/receipt tests. + + Modules opt in with an autouse fixture. Tests changing identity inputs must + request ``live_worker_identity`` instead; their mutations never enter the + session snapshot. Neither public identity factory is replaced. + """ + if "live_worker_identity" in request.fixturenames: + yield + return + + from copy import deepcopy + + from microcosm.build.us_runtime import worker_identity + + identities = request.getfixturevalue("_session_primary_qrf_worker_identities") + memo = worker_identity._PRIMARY_QRF_WORKER_IDENTITY_CACHE + worker_identity.clear_primary_qrf_worker_identity_cache() + memo.update(deepcopy(identities)) + try: + yield + finally: + for key, identity in memo.items(): + # Preserve the original graph even when an artifact test tampers + # with a working copy; remember newly computed legitimate keys. + if key not in identities: + identities[key] = deepcopy(identity) + worker_identity.clear_primary_qrf_worker_identity_cache() + + +@pytest.fixture +def live_worker_identity(): + """Opt out of session priming and expose reset for within-test byte edits.""" + from microcosm.build.us_runtime import worker_identity + + clear = worker_identity.clear_primary_qrf_worker_identity_cache + clear() + try: + yield clear + finally: + clear() diff --git a/packages/microcosm-build/tests/test_puf_qrf_chain.py b/packages/microcosm-build/tests/test_puf_qrf_chain.py index 08ff48ecb..924212e93 100644 --- a/packages/microcosm-build/tests/test_puf_qrf_chain.py +++ b/packages/microcosm-build/tests/test_puf_qrf_chain.py @@ -5,7 +5,10 @@ import hashlib import json import os +import runpy import stat +import sys +import types from contextlib import nullcontext from pathlib import Path @@ -381,6 +384,38 @@ def tracked_replace(source: Path, destination: Path) -> None: ] +def test_primary_qrf_worker_launch_forces_torch_backend_autoload_off( + monkeypatch: pytest.MonkeyPatch, +) -> None: + """The worker disables Torch plugins before importing its QRF runtime.""" + + monkeypatch.setenv("TORCH_DEVICE_BACKEND_AUTOLOAD", "1") + observed: list[str | None] = [] + chain_stub = types.ModuleType( + "microcosm.build.us_runtime.puf_qrf_chain_bootstrap_test" + ) + + def imported_attribute(name: str) -> object: + if name != "run_primary_puf_qrf_target": + raise AttributeError(name) + observed.append(os.environ.get("TORCH_DEVICE_BACKEND_AUTOLOAD")) + return lambda *_args: None + + chain_stub.__getattr__ = imported_attribute # type: ignore[attr-defined] + monkeypatch.setitem( + sys.modules, + "microcosm.build.us_runtime.puf_qrf_chain", + chain_stub, + ) + + runpy.run_module( + "microcosm.build.us_runtime.puf_qrf_worker", + run_name="__primary_qrf_worker_bootstrap_test__", + ) + + assert observed == ["0"] + + def test_target_subprocess_chain_matches_monolith_raw_bits_and_final_frame( tmp_path: Path, monkeypatch: pytest.MonkeyPatch, diff --git a/packages/microcosm-build/tests/test_spec_engine_coverage_tool.py b/packages/microcosm-build/tests/test_spec_engine_coverage_tool.py index 099e68813..189ae4df5 100644 --- a/packages/microcosm-build/tests/test_spec_engine_coverage_tool.py +++ b/packages/microcosm-build/tests/test_spec_engine_coverage_tool.py @@ -2,8 +2,10 @@ from __future__ import annotations +import os from collections.abc import Callable from copy import deepcopy +from functools import cache from pathlib import Path from typing import Any @@ -13,6 +15,7 @@ from microcosm.build.spec_engine.legacy_adapter import compile_to_legacy_payload from microcosm.build.spec_engine.loader import load_bundle from microcosm.build.spec_engine.model import ResolvedSpec +from microcosm.build.us_runtime import worker_identity as worker_identity_module from tools.spec_engine_coverage import ( DEFAULT_REPORT_PATH, CoverageError, @@ -28,6 +31,39 @@ ) +@pytest.fixture(scope="module", autouse=True) +def _reuse_real_worker_binding_for_pin_checks() -> object: + """Reuse one real operational binding while testing digests that strip it.""" + + original = worker_identity_module.primary_qrf_worker_execution_binding + + @cache + def cached( + _fit_jobs: str | None, + _predict_workers: str | None, + _cpu_count: int | None, + ) -> dict[str, object]: + return original() + + def binding() -> dict[str, object]: + return deepcopy( + cached( + os.environ.get("POPULACE_FIT_N_JOBS"), + os.environ.get("POPULACE_FIT_PREDICT_WORKERS"), + os.cpu_count(), + ) + ) + + patcher = pytest.MonkeyPatch() + patcher.setattr( + worker_identity_module, + "primary_qrf_worker_execution_binding", + binding, + ) + yield + patcher.undo() + + @pytest.fixture(scope="module") def coverage_inputs() -> tuple[ResolvedSpec, CompiledSpecIR, dict[str, object]]: spec = load_bundle("us") @@ -89,9 +125,7 @@ def test_us_coverage_is_exact_complete_and_honest( "report schema version differs", ), ( - lambda report: report["spec_binding"].__setitem__( - "schema_version", 99 - ), + lambda report: report["spec_binding"].__setitem__("schema_version", 99), "spec_binding contract differs", ), ( diff --git a/packages/microcosm-build/tests/test_spec_engine_identity_contracts.py b/packages/microcosm-build/tests/test_spec_engine_identity_contracts.py index a2a682f68..fce631f3a 100644 --- a/packages/microcosm-build/tests/test_spec_engine_identity_contracts.py +++ b/packages/microcosm-build/tests/test_spec_engine_identity_contracts.py @@ -63,7 +63,7 @@ def test_pipeline_contract_is_an_exact_generation_zero_projection() -> None: == { "artifact_kind": "populace_us_stacked_pool_checkpoint_identity", "schema_version": 1, - "materializer_version": 12, + "materializer_version": 13, "pipeline": "us-stacked-pool", } ) diff --git a/packages/microcosm-build/tests/test_spec_engine_inventory_coverage.py b/packages/microcosm-build/tests/test_spec_engine_inventory_coverage.py index 922d23379..3aebb7ac8 100644 --- a/packages/microcosm-build/tests/test_spec_engine_inventory_coverage.py +++ b/packages/microcosm-build/tests/test_spec_engine_inventory_coverage.py @@ -3,12 +3,15 @@ from __future__ import annotations import copy +import os from collections.abc import Callable, Mapping from dataclasses import replace +from functools import cache from typing import Any import pytest +from microcosm.build.spec_engine import inventory_coverage as inventory_coverage_module from microcosm.build.spec_engine.compiler_ir import CompiledSpecIR, compile_spec from microcosm.build.spec_engine.inventory_coverage import ( InventoryCoverageError, @@ -19,6 +22,7 @@ from microcosm.build.spec_engine.legacy_adapter import compile_to_legacy_payload from microcosm.build.spec_engine.loader import load_bundle from microcosm.build.spec_engine.model import ResolvedSpec, ResourceKind, freeze_json +from microcosm.build.us_runtime import worker_identity as worker_identity_module EXPECTED_CHECKS = { "acs_group_predictors_exact", @@ -64,6 +68,40 @@ "take_up_program_order_exact", } + +@pytest.fixture(scope="module", autouse=True) +def _reuse_real_worker_binding_for_pin_checks() -> object: + """Reuse one real operational binding while testing digests that strip it.""" + + original = worker_identity_module.primary_qrf_worker_execution_binding + + @cache + def cached( + _fit_jobs: str | None, + _predict_workers: str | None, + _cpu_count: int | None, + ) -> dict[str, object]: + return original() + + def binding() -> dict[str, object]: + return copy.deepcopy( + cached( + os.environ.get("POPULACE_FIT_N_JOBS"), + os.environ.get("POPULACE_FIT_PREDICT_WORKERS"), + os.cpu_count(), + ) + ) + + patcher = pytest.MonkeyPatch() + patcher.setattr( + worker_identity_module, + "primary_qrf_worker_execution_binding", + binding, + ) + yield + patcher.undo() + + EXPECTED_COUNTS = { "adapter_surfaces": 13, "authority_components": 9, @@ -187,6 +225,75 @@ def test_full_checkpoint_vector_binds_dynamic_inputs_and_scale_controls( assert item["observed"]["sha256"] == item["expected"]["sha256"] +def test_operational_free_digest_ignores_the_worker_execution_binding() -> None: + """The primary-QRF worker binding authenticates a machine, not the spec. + + Its semantic identity hashes the interpreter binary, ABI, pyvenv.cfg, the + installed distributions' RECORD files and the resolved CPU count, all of + which differ between a macOS checkout and the Linux CI runners. The pinned + inventory digests must not move with any of it, so the whole subtree is + stripped before digesting, as are audit aliases and receipt self-hashes. + """ + + def receipt(worker_execution: object) -> dict[str, object]: + binding: dict[str, object] = {"clone_attachment": {"seed": 991}} + if worker_execution is not None: + binding["worker_execution"] = worker_execution + return { + "producers": [ + { + "producer": "primary_puf_qrf", + "resources": { + "tax_unit.@primary_puf_execution_config": { + "binding": binding, + "audit_aliases": {"executable": "/some/venv/bin/python"}, + } + }, + } + ], + "sha256": "self-hash over the unpruned receipt", + } + + macos = receipt( + { + "schema_version": 1, + "semantic_identity": { + "interpreter": {"bytes_sha256": "a" * 64, "abi": {"soabi": "darwin"}}, + "installed_distributions_record_sha256": "b" * 64, + "environment": {"POPULACE_FIT_PREDICT_WORKERS": {"resolved": 12}}, + }, + "semantic_identity_sha256": "c" * 64, + } + ) + linux = receipt( + { + "schema_version": 1, + "semantic_identity": { + "interpreter": {"bytes_sha256": "d" * 64, "abi": {"soabi": "linux"}}, + "installed_distributions_record_sha256": "e" * 64, + "environment": {"POPULACE_FIT_PREDICT_WORKERS": {"resolved": 4}}, + }, + "semantic_identity_sha256": "f" * 64, + } + ) + unbound = receipt(None) + + digests = { + inventory_coverage_module._operational_free_sha256(value) + for value in (macos, linux, unbound) + } + + assert len(digests) == 1 + stripped = inventory_coverage_module._without_operational_bindings(macos) + resource = stripped["producers"][0]["resources"][ + "tax_unit.@primary_puf_execution_config" + ] + assert "worker_execution" not in resource["binding"] + assert "audit_aliases" not in resource + assert "sha256" not in stripped + assert resource["binding"]["clone_attachment"] == {"seed": 991} + + def test_nonexistent_bundle_home_is_rejected( resolved_us: ResolvedSpec, compiled_us: CompiledSpecIR, diff --git a/packages/microcosm-build/tests/test_spec_engine_legacy_adapter.py b/packages/microcosm-build/tests/test_spec_engine_legacy_adapter.py index 9edc4e020..e04f560cc 100644 --- a/packages/microcosm-build/tests/test_spec_engine_legacy_adapter.py +++ b/packages/microcosm-build/tests/test_spec_engine_legacy_adapter.py @@ -195,7 +195,7 @@ def test_adapter_preserves_generation_zero_identity_components( imputation = legacy_payload["imputation"] assert isinstance(imputation, dict) assert legacy_payload["stacked_authority_receipt"]["sha256"] == ( - "e660a8ce42b69a39d29c5f0ec37264bc69d61b03f27adc386336ec8889531bb2" + "9d4a9672a0f03039b1fe874b9fe21ed575be0d29f14afc396d03cdf5c809bdd2" ) assert imputation["late_producer_schedule_receipt"]["schedule_sha256"] == ( "e59c019d3d454eac99ac0ac209b6c5b6faaf9bdfcaeee18c36a25be19bf7da2f" diff --git a/packages/microcosm-build/tests/test_spec_engine_stacked_authority_semantics.py b/packages/microcosm-build/tests/test_spec_engine_stacked_authority_semantics.py index 1096b4092..d0da404dd 100644 --- a/packages/microcosm-build/tests/test_spec_engine_stacked_authority_semantics.py +++ b/packages/microcosm-build/tests/test_spec_engine_stacked_authority_semantics.py @@ -73,7 +73,7 @@ def test_authority_projection_is_field_and_byte_identical_to_live_generation_zer assert projected == live assert stacked_identity_bytes(projected) == _canonical_bytes(live) assert projected["sha256"] == ( - "e660a8ce42b69a39d29c5f0ec37264bc69d61b03f27adc386336ec8889531bb2" + "9d4a9672a0f03039b1fe874b9fe21ed575be0d29f14afc396d03cdf5c809bdd2" ) assert { name: component["sha256"] for name, component in projected["components"].items() @@ -88,7 +88,7 @@ def test_authority_projection_is_field_and_byte_identical_to_live_generation_zer "cacc6c11e114dbae3aaa2761cc6b3fcb1191cd9b689b1c2bd096614c51ebff8b" ), "late_producer_schedule": ( - "1b81157b0e21e4763884620ec27b5c4e6e36cc28237273c24eeccdef05a7fbca" + "777979b267e7307581b39d14b7232b6ee2712e3da0029fffc090396ebd849166" ), "metric_registry": ( "d75cb9b29f8b0a9a085471a11f4c19c32ba04cbe5419053df94ea81cbe6125a9" diff --git a/packages/microcosm-build/tests/test_us_fiscal_refresh_builder.py b/packages/microcosm-build/tests/test_us_fiscal_refresh_builder.py index e698b84fd..8887aaba4 100644 --- a/packages/microcosm-build/tests/test_us_fiscal_refresh_builder.py +++ b/packages/microcosm-build/tests/test_us_fiscal_refresh_builder.py @@ -12,6 +12,7 @@ import pandas as pd import pytest +from microcosm.build.us_runtime import h5_io as builder_h5_io from microcosm.calibrate import TargetRegistry, TargetSpec, calibrate from microcosm.frame import Frame, WeightKind, Weights @@ -1716,6 +1717,7 @@ def test_builder_base_h5_pool_loader_receives_explicit_terminal_gate_policy( size_bytes=pool_h5.stat().st_size, publication_run_id="fixture-publication", manifest_sha256="a" * 64, + manifest_payload_sha256=builder_h5_io._canonical_json_sha256(manifest), ) frame = SimpleNamespace() monkeypatch.setattr( @@ -1918,6 +1920,7 @@ def test_authenticated_pool_h5_consumers_use_one_returned_identity() -> None: assert '"manifest_sha256": authenticated_pool_h5.manifest_sha256' in receipt_source assert '"pool_h5_sha256": authenticated_pool_h5.sha256' in receipt_source assert '"pool_h5_size_bytes": authenticated_pool_h5.size_bytes' in receipt_source + assert 'pool_receipt["worker_execution_authentication"] = dict(' in receipt_source def test_builder_reconciles_exact_k_count_before_any_release_write() -> None: @@ -9166,6 +9169,36 @@ def test_exact_k_receipt_stays_strict_even_when_base_h5_opt_in_is_present() -> N builder._exact_k_ladder_manifest_payload(**_gate_failed_exact_k_inputs(builder)) +def test_exact_k_receipt_carries_current_worker_authentication() -> None: + builder = _load_builder_module() + inputs = _gate_failed_exact_k_inputs(builder) + worker_authentication = { + "manifest_schema_version": 10, + "execution_config_schema_version": 5, + "worker_execution_schema_version": 1, + "semantic_identity_sha256": "6" * 64, + "audit_aliases": { + "sys_executable": "/audit/python", + "sys_prefix": "/audit", + "argv_template_0": "/audit/python", + }, + } + inputs["pool_manifest"]["agreement_gate"] = {"passed": True} + inputs["pool_manifest"]["worker_execution_authentication"] = worker_authentication + inputs["authenticated_pool_h5"] = builder.AuthenticatedPoolH5( + path=Path("pool.h5"), + sha256="1" * 64, + size_bytes=123, + publication_run_id="fixture-publication", + manifest_sha256="a" * 64, + worker_execution_authentication=worker_authentication, + ) + + receipt = builder._exact_k_ladder_manifest_payload(**inputs) + + assert receipt["pool"]["worker_execution_authentication"] == (worker_authentication) + + def _gate_failed_base_pool_receipt() -> dict[str, object]: failures = [ {"gate": "us_by_origin_battery", "message": "asec incidence differs"}, diff --git a/packages/microcosm-build/tests/test_us_late_producer_dag.py b/packages/microcosm-build/tests/test_us_late_producer_dag.py index d1857176f..b7a53ca74 100644 --- a/packages/microcosm-build/tests/test_us_late_producer_dag.py +++ b/packages/microcosm-build/tests/test_us_late_producer_dag.py @@ -784,9 +784,9 @@ def test_canonical_us_late_schedule_is_import_validated_and_byte_stable() -> Non assert reconstructed == CANONICAL_US_LATE_PRODUCER_SCHEDULE receipt = us_late_producer_schedule_receipt() - assert receipt["schema_version"] == 16 + assert receipt["schema_version"] == 17 assert receipt["execution_receipt_contract"] == { - "version": 3, + "version": 4, "row_binding": ( "declared_globally_reconciled_input_and_scope_exact_output_source_" "and_primary_callback_resource_receipt_and_previous_execution_sha256" @@ -799,7 +799,7 @@ def test_canonical_us_late_schedule_is_import_validated_and_byte_stable() -> Non "transition_authority": { "authority_id": "us_stacked_late_producer_transition", "metadata_key": "us_late_producer_transition_authority", - "version": 1, + "version": 2, "independent_digest_required": True, }, } diff --git a/packages/microcosm-build/tests/test_us_multispine_pool_h5_io.py b/packages/microcosm-build/tests/test_us_multispine_pool_h5_io.py index 6f51e3f5e..5cf6edbb0 100644 --- a/packages/microcosm-build/tests/test_us_multispine_pool_h5_io.py +++ b/packages/microcosm-build/tests/test_us_multispine_pool_h5_io.py @@ -2,6 +2,11 @@ import hashlib import json +import sys +from collections.abc import Callable +from copy import deepcopy +from dataclasses import replace +from functools import cache from pathlib import Path import numpy as np @@ -12,6 +17,7 @@ import microcosm.build.us_runtime.h5_io as h5_io import microcosm.build.us_runtime.post_transfer_calibration as post_transfer_calibration_runtime import microcosm.build.us_runtime.stacked_spine as stacked_spine_module +import microcosm.build.us_runtime.worker_identity as worker_identity_module from microcosm.build.frame_checkpoint import ( load_frame_checkpoint, write_frame_checkpoint, @@ -51,6 +57,13 @@ from microcosm.frame import US_SCHEMA, Frame, WeightKind, Weights +@pytest.fixture(autouse=True) +def _reuse_real_worker_identity_for_manifest_checks( + prime_primary_qrf_worker_identity: None, +) -> None: + """Prime the real session identity unless a test requests live computation.""" + + def _sha256(path: Path) -> str: return hashlib.sha256(path.read_bytes()).hexdigest() @@ -746,6 +759,22 @@ def _write_ready_pool( transition_authority = ( stacked_spine_module._late_producer_transition_authority_receipt(dag) ) + primary = next( + row + for row in dag["execution"] + if row["producer"] == stacked_spine_module.US_LATE_PRIMARY_PUF_STAGE + ) + config = primary["available_input_receipts"][ + "tax_unit.@primary_puf_execution_config" + ]["binding"] + worker_execution_authentication = ( + worker_identity_module.current_worker_execution_authentication_receipt( + config["qrf"]["worker_execution"], + manifest_schema_version=schema_version, + execution_config_schema_version=config["schema_version"], + boundary="stacked pool fixture worker", + ) + ) manifest.update( { "pipeline": "us-stacked-pool", @@ -779,8 +808,12 @@ def _write_ready_pool( "stacked_post_puf_transfer": dag["post_puf_transfer"], }, }, + "worker_execution_authentication": (worker_execution_authentication), } ) + diagnostics["worker_execution_authentication"] = worker_execution_authentication + diagnostics_path.write_text(json.dumps(diagnostics), encoding="utf-8") + manifest["agreement_diagnostics"]["sha256"] = _sha256(diagnostics_path) manifest["pool_h5"]["materializer_version"] = ( US_MULTISPINE_POOL_H5_MATERIALIZER_VERSION ) @@ -950,7 +983,12 @@ def _canonical_pregnancy_structural_receipt() -> dict[str, object]: } -def _canonical_stacked_late_dag_receipt() -> dict[str, object]: +@cache +def _cached_canonical_stacked_late_dag_receipt( + _fit_jobs: str | None, + _predict_workers: str | None, + _cpu_count: int | None, +) -> dict[str, object]: """Build a signed fixture receipt over the live canonical contracts.""" schedule = stacked_spine_module.CANONICAL_US_LATE_PRODUCER_SCHEDULE @@ -1268,6 +1306,304 @@ def _canonical_stacked_late_dag_receipt() -> dict[str, object]: return receipt +def _canonical_stacked_late_dag_receipt() -> dict[str, object]: + return deepcopy( + _cached_canonical_stacked_late_dag_receipt( + worker_identity_module.os.environ.get("POPULACE_FIT_N_JOBS"), + worker_identity_module.os.environ.get("POPULACE_FIT_PREDICT_WORKERS"), + worker_identity_module.os.cpu_count(), + ) + ) + + +def _rewrite_as_legacy_relocated_worker_pool( + manifest_path: Path, +) -> tuple[dict[str, object], dict[str, object]]: + """Re-sign the tiny fixture with the frozen schema-9 worker binding.""" + + manifest = json.loads(manifest_path.read_text(encoding="utf-8")) + dag = manifest["stage_receipts"]["impute"]["stacked_late_producer_dag"] + primary = next( + row + for row in dag["execution"] + if row["producer"] == stacked_spine_module.US_LATE_PRIMARY_PUF_STAGE + ) + available = primary["available_input_receipts"] + config_receipt = available["tax_unit.@primary_puf_execution_config"] + config = config_receipt["binding"] + recorded_executable = ( + "/Users/maxghenis/PolicyEngine/_worktrees/microcosm-c26-build/.venv/bin/python" + ) + try: + from microcosm.build.us_runtime import worker_identity + except ImportError: + live_legacy_worker = ( + stacked_spine_module._late_primary_qrf_worker_execution_binding() + ) + semantic_identity = { + "worker_module": {"name": live_legacy_worker["module"]}, + "argv_template": [ + "{python_interpreter}", + *live_legacy_worker["argv_template"][1:], + ], + "environment": live_legacy_worker["environment"], + "transitive_environment_code_sha256": "0" * 64, + } + else: + semantic_identity = deepcopy( + worker_identity.primary_qrf_worker_semantic_identity( + uv_lock_sha256=( + "27f47e385cfa35e2644a37410d1804b361ad9aee123577551c8421547bda65ee" + ) + ) + ) + legacy_environment = ( + worker_identity_module.legacy_primary_qrf_worker_execution_binding( + semantic_identity=semantic_identity + )["environment"] + ) + recorded_worker = { + "module": semantic_identity["worker_module"]["name"], + "argv_template": [ + recorded_executable, + *semantic_identity["argv_template"][1:], + ], + "interpreter": { + "executable": recorded_executable, + "resolved_executable": str(Path(sys.executable).resolve()), + "implementation": sys.implementation.name, + "cache_tag": sys.implementation.cache_tag, + "version": list(sys.version_info[:3]), + }, + "environment": legacy_environment, + } + config["schema_version"] = 4 + config["qrf"]["worker_execution"] = recorded_worker + config_receipt["binding_sha256"] = _json_sha256(config) + config_receipt_sha256 = _json_sha256(config_receipt) + + for declared_input in primary["declared_inputs"]: + evidence = declared_input["evidence"] + changed = False + for alternative in evidence["alternatives"]: + for column in alternative: + if ( + column["entity"] == "tax_unit" + and column["column"] == "@primary_puf_execution_config" + ): + column["content_sha256"] = config_receipt_sha256 + changed = True + if changed: + evidence["sha256"] = _json_sha256( + {"alternatives": evidence["alternatives"]} + ) + primary["producer_receipt"]["primary_resource_receipts_sha256"] = _json_sha256( + available + ) + + schedule = dag["producer_schedule"] + schedule["schema_version"] = 16 + schedule["execution_receipt_contract"]["version"] = 3 + schedule["execution_receipt_contract"]["transition_authority"]["version"] = 1 + schedule_payload = { + key: value + for key, value in schedule.items() + if key + not in { + "payload_sha256", + "producer_count", + "source_producer_count", + "transfer_group_count", + "transfer_target_count", + "status", + } + } + schedule["payload_sha256"] = _json_sha256(schedule_payload) + dag["post_puf_transfer"]["producer_schedule"] = json.loads(json.dumps(schedule)) + dag["post_puf_transfer"]["authority"] = ( + stacked_spine_module._legacy_stacked_authority_receipt() + ) + dag["version"] = 3 + previous_sha256 = _json_sha256( + { + "receipt_schema_version": 3, + "producer_schedule_sha256": dag["producer_schedule"]["payload_sha256"], + "input_frame_sha256": dag["input_frame_sha256"], + } + ) + for row in dag["execution"]: + row["input_surface_sha256"] = _json_sha256(row["declared_inputs"]) + row["output_surface_sha256"] = _json_sha256(row["output_surface"]) + row["producer_receipt_sha256"] = _json_sha256(row["producer_receipt"]) + row["previous_execution_sha256"] = previous_sha256 + row.pop("sha256", None) + row["sha256"] = stacked_spine_module._canonical_sha256(row) + previous_sha256 = row["sha256"] + dag["execution_chain_sha256"] = previous_sha256 + dag.pop("sha256", None) + dag["sha256"] = stacked_spine_module._canonical_sha256(dag) + manifest["stage_receipts"]["impute"]["stacked_post_puf_transfer"] = json.loads( + json.dumps(dag["post_puf_transfer"]) + ) + transition_authority = { + "authority_id": stacked_spine_module.US_LATE_PRODUCER_TRANSITION_AUTHORITY_ID, + "version": 1, + "receipt_sha256": dag["sha256"], + "producer_schedule_sha256": dag["producer_schedule"]["payload_sha256"], + "input_frame_sha256": dag["input_frame_sha256"], + "output_frame_sha256": dag["output_frame_sha256"], + "execution_chain_sha256": dag["execution_chain_sha256"], + } + transition_authority["sha256"] = _json_sha256(transition_authority) + manifest["late_producer_transition_authority_sha256"] = transition_authority[ + "sha256" + ] + manifest["schema_version"] = 9 + manifest.pop("worker_execution_authentication", None) + + diagnostics_path = Path(manifest["agreement_diagnostics"]["path"]) + diagnostics = json.loads(diagnostics_path.read_text(encoding="utf-8")) + diagnostics["schema_version"] = 9 + diagnostics.pop("worker_execution_authentication", None) + diagnostics_path.write_text(json.dumps(diagnostics), encoding="utf-8") + manifest["agreement_diagnostics"]["sha256"] = _sha256(diagnostics_path) + manifest_path.write_text(json.dumps(manifest), encoding="utf-8") + return recorded_worker, semantic_identity + + +def _write_legacy_worker_attestation( + manifest_path: Path, + *, + recorded_worker: dict[str, object], + semantic_identity: dict[str, object], + sealed_pool_h5_sha256: str | None = None, +) -> Path: + manifest = json.loads(manifest_path.read_text(encoding="utf-8")) + attestation = { + "artifact_kind": "populace_us_worker_identity_compatibility_attestation", + "schema_version": 1, + "plan_signature": { + "gate": "owner-authorization:c27-root-cause:2026-09-03", + "plan_sha256": ( + "0a3409cfe1560d56a78ecc9acf012abaeb32621af278d745b674ebf1bee32cf6" + ), + "prompt_sha256": ( + "9c1e4508f24d0915c1f3a2942723d3c219c990679227c7d0a315295d5e76efa2" + ), + "checklist_sha256": ( + "5ee1f5fb40387cb690c2e85b32b6bd5abed78200f367c253e517a3917c417238" + ), + "evidence_sha256": ( + "85345eae623d0081354d746a118c9dc5ddaa89a641238e546d8c8e9f7aabbb44" + ), + }, + "purpose": "scoring_only", + "sealed_manifest_sha256": _sha256(manifest_path), + "sealed_pool_h5_sha256": ( + sealed_pool_h5_sha256 or manifest["pool_h5"]["sha256"] + ), + "campaign_tree_sha": "b8819b3f", + "uv_lock_sha256": ( + "27f47e385cfa35e2644a37410d1804b361ad9aee123577551c8421547bda65ee" + ), + "installed_transitive_environment_code_sha256": semantic_identity[ + "transitive_environment_code_sha256" + ], + "recorded_worker_execution": recorded_worker, + "semantic_identity": semantic_identity, + "semantic_identity_sha256": _json_sha256(semantic_identity), + "permitted_mismatches": [ + "argv_template[0]", + "interpreter.executable", + ], + } + attestation_path = manifest_path.with_name("worker-identity-attestation.json") + attestation_path.write_text(json.dumps(attestation), encoding="utf-8") + return attestation_path + + +def _resign_worker_manifest( + manifest_path: Path, + mutate_worker: Callable[[dict[str, object]], None], + *, + current_worker_receipt: bool, +) -> dict[str, object]: + """Re-hash the tiny fixture after a deliberate worker-binding mutation.""" + + manifest = json.loads(manifest_path.read_text(encoding="utf-8")) + impute = manifest["stage_receipts"]["impute"] + dag = impute["stacked_late_producer_dag"] + primary = next( + row + for row in dag["execution"] + if row["producer"] == stacked_spine_module.US_LATE_PRIMARY_PUF_STAGE + ) + available = primary["available_input_receipts"] + config_receipt = available["tax_unit.@primary_puf_execution_config"] + config = config_receipt["binding"] + worker = config["qrf"]["worker_execution"] + mutate_worker(worker) + config_receipt["binding_sha256"] = _json_sha256(config) + config_receipt_sha256 = _json_sha256(config_receipt) + for declared_input in primary["declared_inputs"]: + evidence = declared_input["evidence"] + changed = False + for alternative in evidence["alternatives"]: + for column in alternative: + if ( + column["entity"] == "tax_unit" + and column["column"] == "@primary_puf_execution_config" + ): + column["content_sha256"] = config_receipt_sha256 + changed = True + if changed: + evidence["sha256"] = _json_sha256( + {"alternatives": evidence["alternatives"]} + ) + primary["producer_receipt"]["primary_resource_receipts_sha256"] = _json_sha256( + available + ) + previous_sha256 = stacked_spine_module._late_execution_genesis_sha256( + producer_schedule_sha256=dag["producer_schedule"]["payload_sha256"], + input_frame_sha256=dag["input_frame_sha256"], + receipt_schema_version=dag["version"], + ) + for row in dag["execution"]: + row["input_surface_sha256"] = _json_sha256(row["declared_inputs"]) + row["output_surface_sha256"] = _json_sha256(row["output_surface"]) + row["producer_receipt_sha256"] = _json_sha256(row["producer_receipt"]) + row["previous_execution_sha256"] = previous_sha256 + row.pop("sha256", None) + row["sha256"] = stacked_spine_module._canonical_sha256(row) + previous_sha256 = row["sha256"] + dag["execution_chain_sha256"] = previous_sha256 + dag.pop("sha256", None) + dag["sha256"] = stacked_spine_module._canonical_sha256(dag) + transition_authority = ( + stacked_spine_module._late_producer_transition_authority_receipt(dag) + ) + manifest["late_producer_transition_authority_sha256"] = transition_authority[ + "sha256" + ] + if current_worker_receipt: + authentication = ( + worker_identity_module.current_worker_execution_authentication_receipt( + worker, + manifest_schema_version=manifest["schema_version"], + execution_config_schema_version=config["schema_version"], + boundary="mutated stacked fixture worker", + ) + ) + manifest["worker_execution_authentication"] = authentication + diagnostics_path = Path(manifest["agreement_diagnostics"]["path"]) + diagnostics = json.loads(diagnostics_path.read_text(encoding="utf-8")) + diagnostics["worker_execution_authentication"] = authentication + diagnostics_path.write_text(json.dumps(diagnostics), encoding="utf-8") + manifest["agreement_diagnostics"]["sha256"] = _sha256(diagnostics_path) + manifest_path.write_text(json.dumps(manifest), encoding="utf-8") + return worker + + def test_ready_pool_loader_preserves_importance_weights_and_nullable_inputs( tmp_path: Path, monkeypatch: pytest.MonkeyPatch, @@ -1464,7 +1800,7 @@ def test_ready_stacked_pool_loader_binds_terminal_gate_aliases( frame, manifest, _ = load_simulation_ready_us_multispine_pool(manifest_path) assert manifest["terminal_gates"] == manifest["agreement_gate"] - assert manifest["schema_version"] == 9 + assert manifest["schema_version"] == US_MULTISPINE_POOL_MANIFEST_SCHEMA_VERSION assert ( manifest["pool_h5"]["materializer_version"] == US_MULTISPINE_POOL_H5_MATERIALIZER_VERSION @@ -1740,6 +2076,10 @@ def test_scoring_pool_loader_authenticates_failed_stacked_terminal_receipt( assert receipt["status"] == "gate_failed" assert receipt["simulation_ready"] is False assert receipt["allow_gate_failed_base_pool"] is True + assert ( + receipt["worker_execution_authentication"] + == loaded_manifest["worker_execution_authentication"] + ) assert receipt["agreement_gate_reference"] == { "battery_status": "red", "passed": False, @@ -1755,6 +2095,412 @@ def test_scoring_pool_loader_authenticates_failed_stacked_terminal_receipt( } +def test_current_worker_authentication_ignores_audit_alias_relocation( + tmp_path: Path, +) -> None: + pytest.importorskip("tables") + manifest_path = _write_ready_pool(tmp_path, stacked=True) + original = json.loads(manifest_path.read_text(encoding="utf-8")) + pool_sha256 = original["pool_h5"]["sha256"] + relocated = "/relocated/worktree/.venv/bin/python" + + worker = _resign_worker_manifest( + manifest_path, + lambda value: value.__setitem__( + "audit_aliases", + { + "sys_executable": relocated, + "sys_prefix": "/relocated/worktree/.venv", + "argv_template_0": relocated, + }, + ), + current_worker_receipt=True, + ) + frame, manifest, authenticated = load_simulation_ready_us_multispine_pool( + manifest_path + ) + + assert frame.n("household") == 3 + assert authenticated.sha256 == pool_sha256 + assert ( + manifest["worker_execution_authentication"]["audit_aliases"] + == worker["audit_aliases"] + ) + + +def test_scoring_loader_rejects_semantic_worker_change(tmp_path: Path) -> None: + pytest.importorskip("tables") + manifest_path = _write_gate_failed_pool(tmp_path) + + def mutate(worker: dict[str, object]) -> None: + semantic = worker["semantic_identity"] + semantic["interpreter"]["bytes_sha256"] = "0" * 64 + worker["semantic_identity_sha256"] = _json_sha256(semantic) + + _resign_worker_manifest( + manifest_path, + mutate, + current_worker_receipt=True, + ) + + with pytest.raises(ValueError, match="semantic worker identity changed"): + load_authenticated_us_multispine_pool_for_scoring(manifest_path) + + +def test_scoring_loader_accepts_legacy_worker_alias_relocation_only( + tmp_path: Path, +) -> None: + pytest.importorskip("tables") + manifest_path = _write_gate_failed_pool(tmp_path) + recorded_worker, semantic_identity = _rewrite_as_legacy_relocated_worker_pool( + manifest_path + ) + manifest_sha256 = _sha256(manifest_path) + attestation_path = _write_legacy_worker_attestation( + manifest_path, + recorded_worker=recorded_worker, + semantic_identity=semantic_identity, + ) + + with pytest.raises(ValueError, match="requires.*compatibility attestation"): + load_authenticated_us_multispine_pool_for_scoring(manifest_path) + + frame, manifest, authenticated = load_authenticated_us_multispine_pool_for_scoring( + manifest_path, + expected_manifest_sha256=manifest_sha256, + worker_identity_attestation=attestation_path, + ) + + expected_authentication = { + "manifest_schema_version": 9, + "execution_config_schema_version": 4, + "worker_execution_schema_version": 0, + "semantic_identity_sha256": _json_sha256(semantic_identity), + "audit_aliases": { + "sys_executable": recorded_worker["interpreter"]["executable"], + "argv_template_0": recorded_worker["argv_template"][0], + }, + "compatibility_attestation_sha256": _sha256(attestation_path), + "purpose": "scoring_only", + } + assert frame.n("household") == 3 + assert manifest["status"] == "gate_failed" + assert manifest["simulation_ready"] is False + assert authenticated.sha256 == manifest["pool_h5"]["sha256"] + assert authenticated.manifest_sha256 == manifest_sha256 + assert manifest["worker_execution_authentication"] == expected_authentication + assert authenticated.worker_execution_authentication == expected_authentication + assert _sha256(manifest_path) == manifest_sha256 + assert ( + stacked_spine_module._json_ready( + frame.metadata[stacked_spine_module.STACKED_SPINE_MANIFEST_KEY] + ) + == manifest["stack_manifest"] + ) + assert ( + frame.metadata[stacked_spine_module.US_LATE_PRODUCER_TRANSITION_AUTHORITY_KEY][ + "sha256" + ] + == manifest["late_producer_transition_authority_sha256"] + ) + with pytest.raises(ValueError, match="Scoring-only.*release receipt"): + us_multispine_pool_release_receipt( + manifest, + authenticated, + allow_gate_failed_base_pool=True, + ) + + +@pytest.mark.usefixtures("live_worker_identity") +def test_scoring_loader_requires_complete_schema_nine_stacked_envelope( + tmp_path: Path, + monkeypatch: pytest.MonkeyPatch, +) -> None: + pytest.importorskip("tables") + manifest_path = _write_gate_failed_pool(tmp_path) + recorded_worker, semantic_identity = _rewrite_as_legacy_relocated_worker_pool( + manifest_path + ) + complete_manifest = json.loads(manifest_path.read_text(encoding="utf-8")) + authentication_calls: list[Path] = [] + + def authenticate_without_recomputing_identity( + attestation_path: str | Path, + **_kwargs: object, + ) -> worker_identity_module.LegacyWorkerIdentityAuthentication: + path = Path(attestation_path) + authentication_calls.append(path) + return worker_identity_module.LegacyWorkerIdentityAuthentication( + attestation_sha256=_sha256(path), + campaign_tree_sha="b8819b3f", + recorded_worker_execution=recorded_worker, + semantic_identity=semantic_identity, + semantic_identity_sha256=_json_sha256(semantic_identity), + ) + + monkeypatch.setattr( + worker_identity_module, + "authenticate_legacy_worker_identity_attestation", + authenticate_without_recomputing_identity, + ) + cases = ( + ("missing_pipeline", "pipeline"), + ("wrong_pipeline", None), + ("missing_operator_order", "operator_order"), + ("missing_sampling", "sampling"), + ("missing_stack_manifest", "stack_manifest"), + ("missing_geography_assignment", "geography_assignment"), + ("missing_stage_receipts", "stage_receipts"), + ) + mismatches: list[str] = [] + for case, missing_field in cases: + manifest = json.loads(json.dumps(complete_manifest)) + if missing_field is None: + manifest["pipeline"] = "changed-stacked-pipeline" + expected_missing: list[str] = [] + else: + manifest.pop(missing_field) + expected_missing = [missing_field] + manifest_path.write_text(json.dumps(manifest), encoding="utf-8") + attestation_path = _write_legacy_worker_attestation( + manifest_path, + recorded_worker=recorded_worker, + semantic_identity=semantic_identity, + ) + + try: + load_authenticated_us_multispine_pool_for_scoring( + manifest_path, + worker_identity_attestation=attestation_path, + ) + except ValueError as exc: + message = str(exc) + expected_fragments = ( + "ambiguous stacked envelope", + f"missing={expected_missing!r}", + ) + if any(fragment not in message for fragment in expected_fragments): + mismatches.append(f"{case}: ValueError: {message}") + else: + mismatches.append(f"{case}: accepted") + + assert mismatches == [], "\n".join(mismatches) + assert authentication_calls == [] + + +def test_scoring_loader_rejects_mismatched_legacy_worker_attestation( + tmp_path: Path, +) -> None: + pytest.importorskip("tables") + manifest_path = _write_gate_failed_pool(tmp_path) + recorded_worker, semantic_identity = _rewrite_as_legacy_relocated_worker_pool( + manifest_path + ) + attestation_path = _write_legacy_worker_attestation( + manifest_path, + recorded_worker=recorded_worker, + semantic_identity=semantic_identity, + sealed_pool_h5_sha256="f" * 64, + ) + + with pytest.raises(ValueError, match="attestation.*H5|H5.*attestation"): + load_authenticated_us_multispine_pool_for_scoring( + manifest_path, + worker_identity_attestation=attestation_path, + ) + + +def test_legacy_manifest_cannot_supply_its_own_worker_authentication( + tmp_path: Path, +) -> None: + pytest.importorskip("tables") + manifest_path = _write_gate_failed_pool(tmp_path) + recorded_worker, semantic_identity = _rewrite_as_legacy_relocated_worker_pool( + manifest_path + ) + manifest = json.loads(manifest_path.read_text(encoding="utf-8")) + manifest["worker_execution_authentication"] = {"forged": True} + manifest_path.write_text(json.dumps(manifest), encoding="utf-8") + attestation_path = _write_legacy_worker_attestation( + manifest_path, + recorded_worker=recorded_worker, + semantic_identity=semantic_identity, + ) + + with pytest.raises(ValueError, match="unauthenticated worker receipt"): + load_authenticated_us_multispine_pool_for_scoring( + manifest_path, + worker_identity_attestation=attestation_path, + ) + + +def test_legacy_worker_authentication_cannot_be_stripped_for_release( + tmp_path: Path, +) -> None: + pytest.importorskip("tables") + manifest_path = _write_gate_failed_pool(tmp_path) + recorded_worker, semantic_identity = _rewrite_as_legacy_relocated_worker_pool( + manifest_path + ) + attestation_path = _write_legacy_worker_attestation( + manifest_path, + recorded_worker=recorded_worker, + semantic_identity=semantic_identity, + ) + _, manifest, authenticated = load_authenticated_us_multispine_pool_for_scoring( + manifest_path, + worker_identity_attestation=attestation_path, + ) + stripped_manifest = json.loads(json.dumps(manifest)) + stripped_manifest.pop("worker_execution_authentication") + stripped_manifest["schema_version"] = 4 + stripped_authenticated = replace( + authenticated, + worker_execution_authentication=None, + _legacy_worker_authentication=None, + ) + + with pytest.raises(ValueError, match="manifest payload changed"): + us_multispine_pool_release_receipt( + stripped_manifest, + stripped_authenticated, + allow_gate_failed_base_pool=True, + ) + + +@pytest.mark.parametrize( + "changed_field", + ( + "manifest", + "purpose", + "plan_signature", + "campaign_tree", + "lock", + "transitive_environment_code", + "recorded_worker", + "semantic_digest", + "permitted_mismatches", + ), +) +def test_scoring_loader_rejects_changed_legacy_attestation_field( + tmp_path: Path, + changed_field: str, +) -> None: + pytest.importorskip("tables") + manifest_path = _write_gate_failed_pool(tmp_path) + recorded_worker, semantic_identity = _rewrite_as_legacy_relocated_worker_pool( + manifest_path + ) + attestation_path = _write_legacy_worker_attestation( + manifest_path, + recorded_worker=recorded_worker, + semantic_identity=semantic_identity, + ) + attestation = json.loads(attestation_path.read_text(encoding="utf-8")) + if changed_field == "manifest": + attestation["sealed_manifest_sha256"] = "0" * 64 + elif changed_field == "purpose": + attestation["purpose"] = "release" + elif changed_field == "plan_signature": + attestation["plan_signature"]["gate"] = "unapproved" + elif changed_field == "campaign_tree": + attestation["campaign_tree_sha"] = "b8819b3f" + "1" * 32 + elif changed_field == "lock": + attestation["uv_lock_sha256"] = "0" * 64 + elif changed_field == "transitive_environment_code": + attestation["installed_transitive_environment_code_sha256"] = "0" * 64 + elif changed_field == "recorded_worker": + attestation["recorded_worker_execution"]["module"] = "changed.worker" + elif changed_field == "semantic_digest": + attestation["semantic_identity_sha256"] = "0" * 64 + else: + attestation["permitted_mismatches"] = ["interpreter.executable"] + attestation_path.write_text(json.dumps(attestation), encoding="utf-8") + + with pytest.raises(ValueError, match="attest|mismatch|campaign"): + load_authenticated_us_multispine_pool_for_scoring( + manifest_path, + worker_identity_attestation=attestation_path, + ) + + +@pytest.mark.parametrize("mismatch_count", (1, 3)) +def test_scoring_loader_requires_exact_legacy_alias_mismatch_set( + tmp_path: Path, + mismatch_count: int, +) -> None: + pytest.importorskip("tables") + manifest_path = _write_gate_failed_pool(tmp_path) + _recorded_worker, semantic_identity = _rewrite_as_legacy_relocated_worker_pool( + manifest_path + ) + + def mutate(worker: dict[str, object]) -> None: + if mismatch_count == 1: + worker["argv_template"][0] = str(Path(sys.executable)) + else: + worker["interpreter"]["resolved_executable"] = "/changed/python" + + recorded_worker = _resign_worker_manifest( + manifest_path, + mutate, + current_worker_receipt=False, + ) + attestation_path = _write_legacy_worker_attestation( + manifest_path, + recorded_worker=recorded_worker, + semantic_identity=semantic_identity, + ) + + with pytest.raises(ValueError, match="mismatch set changed"): + load_authenticated_us_multispine_pool_for_scoring( + manifest_path, + worker_identity_attestation=attestation_path, + ) + + +def test_release_loader_ignores_legacy_worker_attestation_and_refuses( + tmp_path: Path, +) -> None: + pytest.importorskip("tables") + manifest_path = _write_gate_failed_pool(tmp_path) + recorded_worker, semantic_identity = _rewrite_as_legacy_relocated_worker_pool( + manifest_path + ) + _write_legacy_worker_attestation( + manifest_path, + recorded_worker=recorded_worker, + semantic_identity=semantic_identity, + ) + + with pytest.raises(ValueError, match="unsupported artifact binding"): + load_authenticated_us_multispine_pool_for_release( + manifest_path, + allow_terminal_gate_failure=True, + ) + + +def test_scoring_loader_refuses_ready_legacy_worker_even_with_attestation( + tmp_path: Path, +) -> None: + pytest.importorskip("tables") + manifest_path = _write_ready_pool(tmp_path, stacked=True) + recorded_worker, semantic_identity = _rewrite_as_legacy_relocated_worker_pool( + manifest_path + ) + attestation_path = _write_legacy_worker_attestation( + manifest_path, + recorded_worker=recorded_worker, + semantic_identity=semantic_identity, + ) + + with pytest.raises(ValueError, match="unsupported artifact binding"): + load_authenticated_us_multispine_pool_for_scoring( + manifest_path, + worker_identity_attestation=attestation_path, + ) + + def test_denied_gate_failed_pool_is_available_only_for_scoring( tmp_path: Path, monkeypatch: pytest.MonkeyPatch, @@ -2336,6 +3082,10 @@ def test_release_receipt_rejects_incoherent_nested_gate_verdict( first_gate = next(iter(manifest["agreement_gate"]["gates"].values())) first_gate["passed"] = nested_passed first_gate["failures"] = failures + authenticated_h5 = replace( + authenticated_h5, + manifest_payload_sha256=_json_sha256(manifest), + ) with pytest.raises(ValueError, match="incoherent passed verdict"): us_multispine_pool_release_receipt( @@ -2539,6 +3289,7 @@ def test_ready_stacked_pool_cannot_be_stripped_into_legacy_shape( "terminal_gates", "operator_order", "stage_receipts", + "worker_execution_authentication", ): manifest.pop(field, None) diagnostics["schema_version"] = 4 diff --git a/packages/microcosm-build/tests/test_us_multispine_pool_tool.py b/packages/microcosm-build/tests/test_us_multispine_pool_tool.py index a9049e406..07e81d2fb 100644 --- a/packages/microcosm-build/tests/test_us_multispine_pool_tool.py +++ b/packages/microcosm-build/tests/test_us_multispine_pool_tool.py @@ -63,6 +63,11 @@ _FIXTURE_SEED_PERSON_COLUMN = "takes_up_medicaid_if_eligible" +@pytest.fixture(autouse=True) +def _prime_worker_identity(prime_primary_qrf_worker_identity: None) -> None: + """Share the real session attestation unless a test opts into live identity.""" + + @pytest.fixture(scope="module") def pool_tool() -> ModuleType: root = Path(__file__).resolve().parents[3] @@ -2499,7 +2504,7 @@ def capture_equality(expected: object, actual: object) -> None: "country": "us", "schema_id": "country_spec", "schema_version": 1, - "spec_sha256": "a6bc79878eb6f64637b9f3eceeea6cc2b050c0e5b8f9aca446179258940c44f2", + "spec_sha256": "9db29b4d33424fbb21a83c63927c7de55ba9a333d631f6323935f67a496eee46", }, } @@ -3518,7 +3523,7 @@ def test_legacy_checkpoint_identity_excludes_stacked_late_producer_schedule( assert changed == current -def test_stacked_checkpoint_identity_binds_v12_semantic_contracts( +def test_stacked_checkpoint_identity_binds_v13_semantic_contracts( pool_tool: ModuleType, monkeypatch: pytest.MonkeyPatch, tmp_path: Path, @@ -3551,8 +3556,8 @@ def identity() -> dict[str, object]: current = identity() pool_code = current["pool_code"] - assert current["materializer_version"] == 12 - assert current["stacked_authority"]["version"] == 11 + assert current["materializer_version"] == 13 + assert current["stacked_authority"]["version"] == 12 assert current["geography_assignment"] == ( pool_tool._stacked_geography_assignment_contract() ) @@ -3779,7 +3784,7 @@ def changed_source_stage_binding( ) ) - assert current["materializer_version"] == stale_qrf["materializer_version"] == 12 + assert current["materializer_version"] == stale_qrf["materializer_version"] == 13 assert stale_qrf["pool_code"]["primary_qrf_checkpoint_schema_version"] == 5 assert ( pool_tool._discover_stacked_checkpoint_identity( @@ -4034,7 +4039,7 @@ def test_qbi_receipt_route_resolution_rejects_wrong_or_ambiguous_paths( ) -@pytest.mark.parametrize("legacy_version", (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)) +@pytest.mark.parametrize("legacy_version", (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)) def test_legacy_stacked_materializer_checkpoint_is_not_discovered( pool_tool: ModuleType, monkeypatch: pytest.MonkeyPatch, @@ -4088,7 +4093,7 @@ def test_legacy_stacked_materializer_checkpoint_is_not_discovered( ) ) - assert pool_tool._STACKED_CHECKPOINT_MATERIALIZER_VERSION == 12 + assert pool_tool._STACKED_CHECKPOINT_MATERIALIZER_VERSION == 13 assert ( pool_tool._discover_stacked_checkpoint_identity( checkpoint_root, @@ -4492,7 +4497,7 @@ def deterministic_fixture_h5( outputs = pool_tool._output_paths(output, checkpoint_root=checkpoint_root) manifest = pool_tool._read_json_object(outputs.manifest) diagnostics = pool_tool._read_json_object(outputs.agreement_diagnostics) - assert pool_tool.POOL_MANIFEST_SCHEMA_VERSION == 9 + assert pool_tool.POOL_MANIFEST_SCHEMA_VERSION == 10 assert pool_tool.POOL_STAGE_CHECKPOINT_MATERIALIZER_VERSION == 7 assert manifest["schema_version"] == 4 assert diagnostics["schema_version"] == 4 diff --git a/packages/microcosm-build/tests/test_us_release_gate_preflight.py b/packages/microcosm-build/tests/test_us_release_gate_preflight.py index 949fc8f61..138a61bb5 100644 --- a/packages/microcosm-build/tests/test_us_release_gate_preflight.py +++ b/packages/microcosm-build/tests/test_us_release_gate_preflight.py @@ -793,6 +793,9 @@ def test__preflight_base__passes_explicit_terminal_gate_policy_to_release_loader size_bytes=base_h5.stat().st_size, publication_run_id="fixture-publication", manifest_sha256="a" * 64, + # The release receipt re-derives this from the manifest it is handed; + # a fake identity has to bind the same payload. + manifest_payload_sha256=h5_io._canonical_json_sha256(manifest), ) frame = _frame(_POOL) monkeypatch.setattr( diff --git a/packages/microcosm-build/tests/test_us_release_head_to_head_scorer.py b/packages/microcosm-build/tests/test_us_release_head_to_head_scorer.py index f601cdc66..fc4c0b9c6 100644 --- a/packages/microcosm-build/tests/test_us_release_head_to_head_scorer.py +++ b/packages/microcosm-build/tests/test_us_release_head_to_head_scorer.py @@ -179,8 +179,8 @@ def _tiny_frame_with_marketplace_columns( [True, False], dtype=bool ) if interview_leaf: - tables["person"]["has_marketplace_health_coverage_at_interview"] = ( - np.asarray([True, False], dtype=bool) + tables["person"]["has_marketplace_health_coverage_at_interview"] = np.asarray( + [True, False], dtype=bool ) return Frame( tables, @@ -298,7 +298,141 @@ def test_head_to_head_signature_has_no_target_membership_switches() -> None: "congressional_district_vintage_crosswalk", "maximum_microsim_batch_size", "candidate_manifest_sha256", + "candidate_worker_identity_attestation", + } + + +def test_candidate_worker_attestation_propagates_from_cli_to_artifact_loader( + monkeypatch: pytest.MonkeyPatch, + tmp_path: Path, +) -> None: + module = _load_head_to_head_module() + incumbent = tmp_path / "incumbent.h5" + candidate = tmp_path / "candidate.manifest.json" + attestation = tmp_path / "worker-attestation.json" + pin = "a" * 64 + args = module._parse_args( + [ + "--incumbent", + str(incumbent), + "--candidate", + str(candidate), + "--candidate-manifest-sha256", + pin, + "--candidate-worker-identity-attestation", + str(attestation), + "--ledger-facts", + str(tmp_path / "facts.jsonl"), + "--out-prefix", + str(tmp_path / "scorecard"), + ] + ) + assert args.candidate_worker_identity_attestation == attestation + + calls: list[tuple[Path, str | None, Path | None]] = [] + + def fake_load_artifact( + path: Path, + *, + expected_manifest_sha256: str | None = None, + worker_identity_attestation: Path | None = None, + ) -> SimpleNamespace: + calls.append((path, expected_manifest_sha256, worker_identity_attestation)) + return SimpleNamespace() + + monkeypatch.setattr(module, "load_artifact", fake_load_artifact) + monkeypatch.setattr( + module, + "compile_yardstick", + lambda **_kwargs: SimpleNamespace(identity={}, loss_basis={}), + ) + monkeypatch.setattr( + module, + "score_loaded_artifact", + lambda **kwargs: ({"name": kwargs["artifact_name"]}, (("fixture",),)), + ) + monkeypatch.setattr(module, "_assert_identical_scored_contracts", lambda _: None) + monkeypatch.setattr(module, "_comparison_payload", lambda *_: {}) + monkeypatch.setattr(module, "_canonical_battery_contract", lambda: {}) + monkeypatch.setattr(module, "_assert_rss_below_limit", lambda _: None) + + module.score_head_to_head( + incumbent=args.incumbent, + candidate=args.candidate, + ledger_facts=args.ledger_facts, + candidate_manifest_sha256=args.candidate_manifest_sha256, + candidate_worker_identity_attestation=( + args.candidate_worker_identity_attestation + ), + ) + + assert calls == [ + (incumbent, None, None), + (candidate, pin, attestation), + ] + + +def test_pool_scorecard_preserves_worker_authentication_receipts( + monkeypatch: pytest.MonkeyPatch, + tmp_path: Path, +) -> None: + module = _load_head_to_head_module() + manifest_path = tmp_path / "candidate.manifest.json" + pool_path = tmp_path / "candidate.h5" + attestation_path = tmp_path / "worker-attestation.json" + authentication = { + "semantic_identity_sha256": "b" * 64, + "compatibility_attestation_sha256": "c" * 64, + "purpose": "scoring_only", + } + authenticated = SimpleNamespace( + path=pool_path, + sha256="d" * 64, + size_bytes=123, + manifest_sha256="e" * 64, + publication_run_id="fixture-run", + worker_execution_authentication=authentication, + ) + captured: dict[str, object] = {} + + def fake_scoring_loader(path: Path, **kwargs): + captured["path"] = path + captured.update(kwargs) + return ( + _tiny_frame(measure_values=(1.0, 2.0)), + { + "release_id": "fixture-release", + "status": "gate_failed", + "simulation_ready": False, + "terminal_gates": {"passed": False}, + }, + authenticated, + ) + + monkeypatch.setattr( + module, + "load_authenticated_us_multispine_pool_for_scoring", + fake_scoring_loader, + ) + monkeypatch.setattr( + module, + "_drop_historical_formula_owned_columns", + lambda frame: (frame, {"count": 0, "columns_by_entity": {}}), + ) + + loaded = module._load_pool_manifest( + manifest_path, + expected_manifest_sha256="e" * 64, + worker_identity_attestation=attestation_path, + ) + + assert captured == { + "path": manifest_path, + "expected_manifest_sha256": "e" * 64, + "worker_identity_attestation": attestation_path, } + assert loaded.identity["worker_execution_authentication"] == authentication + assert loaded.loader["worker_execution_authentication"] == authentication def test_dense_candidate_streaming_plan_is_independent_of_total_pool_size() -> None: diff --git a/packages/microcosm-build/tests/test_us_spec_bundle.py b/packages/microcosm-build/tests/test_us_spec_bundle.py index 892ece523..5617e6920 100644 --- a/packages/microcosm-build/tests/test_us_spec_bundle.py +++ b/packages/microcosm-build/tests/test_us_spec_bundle.py @@ -9,6 +9,7 @@ import re import sys from collections import Counter +from functools import cache from pathlib import Path import pytest @@ -201,6 +202,11 @@ def _load_generator_module(): } +@pytest.fixture(autouse=True) +def _prime_worker_identity(prime_primary_qrf_worker_identity: None) -> None: + """Share the real session attestation unless a test opts into live identity.""" + + @pytest.fixture(scope="module") def resolved_us_spec() -> ResolvedSpec: return load_bundle("us") @@ -211,8 +217,17 @@ def resolved_country_spec() -> ResolvedCountrySpec: return load_country_spec("us") -@pytest.fixture(scope="module") -def generated_documents() -> dict[str, dict[str, object]]: +@pytest.fixture +def generated_documents( + prime_primary_qrf_worker_identity: None, +) -> dict[str, dict[str, object]]: + # The function fixture primes before the first cached generation, including + # when earlier tests already initialized and then cleared the session memo. + return _cached_generated_documents() + + +@cache +def _cached_generated_documents() -> dict[str, dict[str, object]]: # The extractor is intentionally exercised once per module: this proves # the checked-in package remains a projection of the live constants while # keeping the comparatively expensive PolicyEngine ABI read bounded. @@ -386,7 +401,7 @@ def test_constant_derived_domain_counts_are_complete( ) assert ( compiled_schedule["payload_sha256"] - == "02e618cc656eb39990ed99dca2b30a52794e01e2b06a3c2df87ca4a7d85ab086" + == "7be038d34f228d66c12b53558fc5f30c93f1b376f1058c5e4fd7e7563a88d67f" ) assert len(take_up["programs"]) == 17 @@ -722,6 +737,11 @@ def collect_sha256(value: object, path: tuple[str, ...] = ()) -> None: if key.endswith("sha256"): if key == "asset_sha256": asset_pins.append((str(value["asset"]), str(child))) + elif isinstance(child, dict) and "resolver_op" in child: + # A resolver binding names the runtime op that + # produces the digest; it is neither an authored + # digest nor an asset pin. + pass else: identity_digests.append((child_path, str(child))) collect_sha256(child, child_path) @@ -790,6 +810,25 @@ def collect_sha256(value: object, path: tuple[str, ...] = ()) -> None: for resource in primary_node["virtual_resources"] if resource["binding"]["resource_kind"] == "primary_puf_execution_config" ) + assert graph["schedule_payload_schema_version"] == 17 + assert graph["execution_receipt_contract"]["version"] == 4 + assert graph["execution_receipt_contract"]["transition_authority"]["version"] == 2 + assert graph["resource_semantics"]["schema_version"] == 2 + assert primary_binding["schema_version"] == 5 + assert primary_binding["qrf"]["worker_execution"] == { + "surface": "execution_profile", + "resolve_as": "worker_execution", + "template": { + "schema_version": 1, + "semantic_identity": { + "resolver_op": "primary_qrf_worker_semantic_identity" + }, + "semantic_identity_sha256": { + "resolver_op": "primary_qrf_worker_semantic_identity_sha256" + }, + "audit_aliases": {"resolver_op": "primary_qrf_worker_audit_aliases"}, + }, + } runtime_bands = primary_binding["capital_gains_tail"]["soi_e19200_agi_bands"][ "runtime_agi_bands" ] @@ -949,12 +988,8 @@ def test_legacy_seed_vintage_and_publication_grammars_are_pinned( assert geography["assignment"]["anchor"] == "puma" assert geography["assignment"]["order"] == "before_gap_fill" assert geography["assignment"]["assign_tract"] is False - assert geography["assignment"][ - "congressional_district_vintage_crosswalk" - ] == { - "source_ref": ( - "source:us_congressional_district_vintage_crosswalk_117_to_119" - ), + assert geography["assignment"]["congressional_district_vintage_crosswalk"] == { + "source_ref": ("source:us_congressional_district_vintage_crosswalk_117_to_119"), "source_vintage": "vintage:cd_117", "target_vintage": "vintage:cd_119", } @@ -984,9 +1019,12 @@ def test_legacy_seed_vintage_and_publication_grammars_are_pinned( assert engine_version_occurrences == { kind: int(kind == "take_up") for kind in TYPED_DOMAIN_KINDS } - assert take_up["legacy_contract_metadata"]["asserted_engine"][ - "inventory_built_against" - ] == engine_version + assert ( + take_up["legacy_contract_metadata"]["asserted_engine"][ + "inventory_built_against" + ] + == engine_version + ) assert _count_scalar(engine_lock, engine_version) == 1 resolved_vintages = thaw_json(resolved_us_spec.vintage_authorities) assert resolved_vintages["records"]["policyengine_us_surface"]["value"] == ( @@ -1085,3 +1123,17 @@ def test_root_us_drafting_location_is_a_symlink_free_pointer() -> None: assert "packages/microcosm-build/src/microcosm/build/us/spec" in ( readme.read_text(encoding="utf-8") ) + + +@pytest.mark.requires_us +def test_generated_bundle_reuses_primed_worker_identity( + generated_documents: dict[str, dict[str, object]], + request: pytest.FixtureRequest, +) -> None: + """Generation and session priming must share one real worker attestation.""" + from microcosm.build.us_runtime import worker_identity + + assert "imputation.yaml" in generated_documents + generated_identity = worker_identity.primary_qrf_worker_semantic_identity() + request.getfixturevalue("_session_primary_qrf_worker_identities") + assert worker_identity.primary_qrf_worker_semantic_identity() is generated_identity diff --git a/packages/microcosm-build/tests/test_us_spine_blindness.py b/packages/microcosm-build/tests/test_us_spine_blindness.py index 37ace836d..de6f713fc 100644 --- a/packages/microcosm-build/tests/test_us_spine_blindness.py +++ b/packages/microcosm-build/tests/test_us_spine_blindness.py @@ -307,6 +307,7 @@ # nothing with the source registry and treats no population itself. "graph.py", "graph_kernels.py", + "worker_identity.py", # Portable primary-QRF worker identity; no population treatment. } ) _CLASSIFIED_US_RUNTIME_MODULES = frozenset(_SPINE_BLIND_OPERATOR_MODULES).union( @@ -3402,8 +3403,8 @@ def test_pool_build_tool_import_graph_is_source_spine_blind() -> None: for tool in _SPINE_BLIND_BUILD_TOOLS: runtime_graph, missing_modules = _us_runtime_import_graph(tool) - assert len(runtime_graph) == 69, ( - f"{tool.name} must reach the pinned 69-module runtime graph; " + assert len(runtime_graph) == 70, ( + f"{tool.name} must reach the pinned 70-module runtime graph; " f"reached {len(runtime_graph)}" ) assert not missing_modules, ( diff --git a/packages/microcosm-build/tests/test_us_stacked_spine.py b/packages/microcosm-build/tests/test_us_stacked_spine.py index 0d4556814..b30c20272 100644 --- a/packages/microcosm-build/tests/test_us_stacked_spine.py +++ b/packages/microcosm-build/tests/test_us_stacked_spine.py @@ -9,15 +9,18 @@ from __future__ import annotations +import copy import hashlib import inspect import json import pickle +import sys from collections import Counter from collections.abc import Mapping from copy import deepcopy from dataclasses import FrozenInstanceError, replace from pathlib import Path +from types import SimpleNamespace import numpy as np import pandas as pd @@ -31,6 +34,7 @@ import microcosm.build.us_runtime.puf_capital_gains_tail as tail_module import microcosm.build.us_runtime.puf_support as puf_support_module import microcosm.build.us_runtime.stacked_spine as stacked_spine_module +import microcosm.build.us_runtime.worker_identity as worker_identity_module from microcosm.build.frame_checkpoint import ( load_frame_checkpoint, write_frame_checkpoint, @@ -4154,6 +4158,1159 @@ def test_late_table_content_digest_binds_dtype_index_and_order() -> None: ) +@pytest.fixture(autouse=True) +def _prime_worker_identity(prime_primary_qrf_worker_identity: None) -> None: + """Share the real session attestation unless a test opts into live identity.""" + + +def _fixture_primary_execution_config_binding() -> dict[str, object]: + return stacked_spine_module._late_primary_execution_config_binding( + clone_attachment_fraction=1.0, + clone_attachment_seed=578, + seed=0, + n_estimators=100, + predictors=None, + person_outputs=None, + tax_unit_outputs=None, + fit_records_enabled=True, + tail_bound_diagnostics_enabled=True, + ) + + +def _validate_fixture_primary_execution_config( + binding: Mapping[str, object], +) -> None: + # These cases mutate received bindings, never the installed environment. + # Reuse the real pristine fixture for comparison, independently of the + # potentially re-signed candidate; direct identity mutation tests stay live. + expected_worker = _fixture_primary_execution_config_binding()["qrf"][ + "worker_execution" + ] + with pytest.MonkeyPatch.context() as identity_fixture: + identity_fixture.setattr( + stacked_spine_module, + "_late_primary_qrf_worker_execution_binding", + lambda: deepcopy(expected_worker), + ) + stacked_spine_module._validate_late_resource_binding( + binding, + producer=stacked_spine_module.US_LATE_PRIMARY_PUF_STAGE, + entity="tax_unit", + column=stacked_spine_module.US_LATE_PRIMARY_EXECUTION_CONFIG_INPUT, + boundary="portable worker identity fixture", + ) + + +def test_late_primary_worker_authentication_ignores_audit_alias_relocation() -> None: + binding = _fixture_primary_execution_config_binding() + worker = binding["qrf"]["worker_execution"] + original_semantic_identity = deepcopy(worker["semantic_identity"]) + original_semantic_sha256 = worker["semantic_identity_sha256"] + relocated_interpreter = ( + "/Users/maxghenis/PolicyEngine/_worktrees/microcosm-c26-build/.venv/bin/python" + ) + + worker["audit_aliases"] = { + "sys_executable": relocated_interpreter, + "sys_prefix": str(Path(relocated_interpreter).parents[1]), + "argv_template_0": relocated_interpreter, + } + + _validate_fixture_primary_execution_config(binding) + assert worker["semantic_identity"] == original_semantic_identity + assert worker["semantic_identity_sha256"] == original_semantic_sha256 + + +def test_late_primary_worker_audit_paths_must_be_absolute() -> None: + binding = _fixture_primary_execution_config_binding() + binding["qrf"]["worker_execution"]["audit_aliases"]["sys_executable"] = ( + "relative/python" + ) + + with pytest.raises(ValueError, match="worker binding is malformed"): + _validate_fixture_primary_execution_config(binding) + + +def test_late_primary_worker_authentication_rejects_rehashed_semantic_change() -> None: + binding = _fixture_primary_execution_config_binding() + worker = binding["qrf"]["worker_execution"] + semantic_identity = worker["semantic_identity"] + semantic_identity["interpreter"]["bytes_sha256"] = "0" * 64 + worker["semantic_identity_sha256"] = stacked_spine_module._canonical_sha256( + semantic_identity + ) + + with pytest.raises(ValueError, match="semantic worker identity changed"): + _validate_fixture_primary_execution_config(binding) + + +@pytest.mark.usefixtures("live_worker_identity") +def test_worker_transitive_source_identity_includes_package_initializers( + tmp_path: Path, + monkeypatch: pytest.MonkeyPatch, +) -> None: + worker_source = tmp_path / "worker.py" + package_dir = tmp_path / "fixture" / "pkg" + package_dir.mkdir(parents=True) + package_init = package_dir / "__init__.py" + child_source = package_dir / "child.py" + worker_source.write_text("import fixture.pkg.child\n", encoding="utf-8") + package_init.write_text("PACKAGE_VALUE = 1\n", encoding="utf-8") + child_source.write_text("CHILD_VALUE = 1\n", encoding="utf-8") + source_index = { + worker_identity_module.PRIMARY_QRF_WORKER_MODULE: worker_source, + "fixture.pkg": package_init, + "fixture.pkg.child": child_source, + } + monkeypatch.setattr( + worker_identity_module, + "_module_source_index", + lambda: source_index, + ) + + worker_before, imports_before, _ = worker_identity_module._worker_source_identity() + package_init.write_text("PACKAGE_VALUE = 2\n", encoding="utf-8") + worker_after, imports_after, _ = worker_identity_module._worker_source_identity() + + assert worker_after == worker_before + assert imports_after != imports_before + + +@pytest.mark.usefixtures("live_worker_identity") +def test_worker_source_index_stays_inside_installed_namespace_roots( + tmp_path: Path, + monkeypatch: pytest.MonkeyPatch, +) -> None: + site_packages = tmp_path / "site-packages" + namespace_root = site_packages / "microcosm" + worker_source = namespace_root / "build" / "us_runtime" / "puf_qrf_worker.py" + neighboring_package = site_packages / "packaging" / "__init__.py" + worker_source.parent.mkdir(parents=True) + neighboring_package.parent.mkdir(parents=True) + worker_source.write_text("import packaging\n", encoding="utf-8") + neighboring_package.write_text("NEIGHBOR = True\n", encoding="utf-8") + monkeypatch.setattr( + worker_identity_module.importlib.util, + "find_spec", + lambda name: ( + SimpleNamespace(submodule_search_locations=(namespace_root,)) + if name == "microcosm" + else None + ), + ) + + index = worker_identity_module._module_source_index() + + assert index == { + worker_identity_module.PRIMARY_QRF_WORKER_MODULE: worker_source.resolve() + } + internal, external = worker_identity_module._source_imports( + worker_identity_module.PRIMARY_QRF_WORKER_MODULE, + worker_source, + worker_source.read_bytes(), + index=index, + ) + assert internal == set() + assert external == {"packaging"} + + +def _two_namespace_roots(tmp_path: Path, monkeypatch: pytest.MonkeyPatch): + roots = [] + for name in ("installed", "checkout"): + root = tmp_path / name / "microcosm" + (root / "build" / "us_runtime").mkdir(parents=True) + roots.append(root) + monkeypatch.setattr( + worker_identity_module.importlib.util, + "find_spec", + lambda name: ( + SimpleNamespace(submodule_search_locations=tuple(roots)) + if name == "microcosm" + else None + ), + ) + return roots + + +@pytest.mark.usefixtures("live_worker_identity") +def test_worker_source_index_accepts_a_byte_identical_shadow_root( + tmp_path: Path, + monkeypatch: pytest.MonkeyPatch, +) -> None: + """An installed wheel beside its own checkout (or lib64 beside lib) is the + same code; the first root on the import path wins.""" + installed, checkout = _two_namespace_roots(tmp_path, monkeypatch) + for root in (installed, checkout): + (root / "build" / "us_runtime" / "puf_qrf_worker.py").write_text( + "import packaging\n", encoding="utf-8" + ) + (checkout / "build" / "__init__.py").write_text("", encoding="utf-8") + + index = worker_identity_module._module_source_index() + + assert ( + index[worker_identity_module.PRIMARY_QRF_WORKER_MODULE] + == (installed / "build" / "us_runtime" / "puf_qrf_worker.py").resolve() + ) + assert index["microcosm.build"] == (checkout / "build" / "__init__.py").resolve() + + +@pytest.mark.usefixtures("live_worker_identity") +def test_worker_source_index_rejects_a_shadow_root_with_different_source( + tmp_path: Path, + monkeypatch: pytest.MonkeyPatch, +) -> None: + installed, checkout = _two_namespace_roots(tmp_path, monkeypatch) + (installed / "build" / "us_runtime" / "puf_qrf_worker.py").write_text( + "import packaging\n", encoding="utf-8" + ) + (checkout / "build" / "us_runtime" / "puf_qrf_worker.py").write_text( + "import packaging # edited\n", encoding="utf-8" + ) + + with pytest.raises(RuntimeError, match="Duplicate source modules .* differs"): + worker_identity_module._module_source_index() + + +def _pyvenv_prefix(tmp_path: Path, monkeypatch: pytest.MonkeyPatch, version: str): + (tmp_path / "pyvenv.cfg").write_text( + "home = /opt/python/bin\n" + "implementation = CPython\n" + "uv = 0.12.9\n" + f"version_info = {version}\n" + "include-system-site-packages = false\n", + encoding="utf-8", + ) + monkeypatch.setattr(worker_identity_module.sys, "prefix", str(tmp_path)) + + +@pytest.mark.parametrize("components", (2, 3)) +@pytest.mark.usefixtures("live_worker_identity") +def test_canonical_pyvenv_config_accepts_uv_major_minor_and_triplet_versions( + tmp_path: Path, + monkeypatch: pytest.MonkeyPatch, + components: int, +) -> None: + """uv 0.12 writes ``version_info = 3.13``; older uv wrote the triplet. Both + canonicalize to the running interpreter's triplet.""" + running = worker_identity_module.sys.version_info + _pyvenv_prefix( + tmp_path, monkeypatch, ".".join(str(part) for part in running[:components]) + ) + + config = worker_identity_module._canonical_pyvenv_config() + + assert config["version"] == list(running[:3]) + assert config["uv_version"] == "0.12.9" + + +@pytest.mark.parametrize( + ("version", "message"), + ( + ("9.9.9", "does not match the running interpreter"), + ("9.9", "does not match the running interpreter"), + ("3", "major.minor or major.minor.micro"), + ("3.13.11.0", "major.minor or major.minor.micro"), + ("3.13rc1", "is not numeric"), + ), +) +@pytest.mark.usefixtures("live_worker_identity") +def test_canonical_pyvenv_config_rejects_versions_that_are_not_the_interpreter( + tmp_path: Path, + monkeypatch: pytest.MonkeyPatch, + version: str, + message: str, +) -> None: + _pyvenv_prefix(tmp_path, monkeypatch, version) + + with pytest.raises(RuntimeError, match=message): + worker_identity_module._canonical_pyvenv_config() + + +def _stub_worker_identity_static_closure( + monkeypatch: pytest.MonkeyPatch, + *, + stub_installed_distributions: bool = True, +) -> None: + """Keep portable-identity mutation tests focused and inexpensive.""" + + monkeypatch.setattr( + worker_identity_module, + "_worker_source_identity", + lambda: ("a" * 64, "b" * 64, ()), + ) + if stub_installed_distributions: + monkeypatch.setattr( + worker_identity_module, + "_installed_distributions_record_sha256", + lambda _external_roots: "c" * 64, + ) + monkeypatch.setattr( + worker_identity_module, + "_canonical_pyvenv_config", + lambda: { + "implementation": sys.implementation.name, + "version": list(sys.version_info[:3]), + "include_system_site_packages": False, + "uv_version": "fixture", + }, + ) + monkeypatch.delenv("POPULACE_FIT_N_JOBS", raising=False) + monkeypatch.setenv("POPULACE_FIT_PREDICT_WORKERS", "2") + + +def _fixture_worker_import_trace( + tmp_path: Path, + *, + module_origins: Mapping[str, str] | None = None, +) -> dict[str, object]: + namespace_root = tmp_path / "namespace" / "microcosm" + worker_source = namespace_root / "build" / "us_runtime" / "puf_qrf_worker.py" + worker_source.parent.mkdir(parents=True, exist_ok=True) + worker_source.write_text("# fixture worker\n", encoding="utf-8") + return { + "module_origins": { + worker_identity_module.PRIMARY_QRF_WORKER_MODULE: str(worker_source), + **({} if module_origins is None else dict(module_origins)), + }, + "opened_files": (), + "namespace_roots": (str(namespace_root),), + } + + +@pytest.fixture +def _worker_identity_memo_inputs( + live_worker_identity, tmp_path: Path, monkeypatch: pytest.MonkeyPatch +): + """Exercise the real memo and file hashing with a tiny import closure.""" + _stub_worker_identity_static_closure(monkeypatch) + runtime = tmp_path / "libpython-fixture.so" + runtime.write_bytes(b"unchanged fixture runtime\n") + monkeypatch.setattr( + worker_identity_module, + "_loaded_python_runtime_binary", + lambda: ("shared_library", runtime), + ) + trace = _fixture_worker_import_trace(tmp_path) + source = Path( + trace["module_origins"][worker_identity_module.PRIMARY_QRF_WORKER_MODULE] + ) + trace["opened_files"] = (str(source),) + calls = [] + + def import_trace(): + calls.append(None) + return trace + + monkeypatch.setattr( + worker_identity_module, "_clean_worker_import_trace", import_trace + ) + return source, calls + + +def test_primary_qrf_worker_identity_memo_reuses_graph_and_clear_recomputes( + _worker_identity_memo_inputs, +) -> None: + _source, calls = _worker_identity_memo_inputs + first = worker_identity_module.primary_qrf_worker_semantic_identity() + second = worker_identity_module.primary_qrf_worker_semantic_identity() + assert second is first + assert second["interpreter"] is first["interpreter"] + assert second["environment"] is first["environment"] + assert len(calls) == 1 + + worker_identity_module.clear_primary_qrf_worker_identity_cache() + third = worker_identity_module.primary_qrf_worker_semantic_identity() + assert third == first + assert third is not first + assert third["interpreter"] is not first["interpreter"] + assert len(calls) == 2 + + +@pytest.mark.parametrize( + "name", ("POPULACE_FIT_N_JOBS", "POPULACE_FIT_PREDICT_WORKERS") +) +def test_primary_qrf_worker_identity_memo_binds_environment( + _worker_identity_memo_inputs, + monkeypatch: pytest.MonkeyPatch, + name: str, +) -> None: + _source, calls = _worker_identity_memo_inputs + monkeypatch.setenv(name, "1") + first = worker_identity_module.primary_qrf_worker_semantic_identity() + monkeypatch.setenv(name, "3") + second = worker_identity_module.primary_qrf_worker_semantic_identity() + assert second is not first + assert first["environment"]["semantic_controls"][name]["resolved"] == 1 + assert second["environment"]["semantic_controls"][name]["resolved"] == 3 + assert worker_identity_module._canonical_sha256( + first + ) != worker_identity_module._canonical_sha256(second) + assert len(calls) == 2 + monkeypatch.setenv(name, "1") + assert worker_identity_module.primary_qrf_worker_semantic_identity() is first + assert len(calls) == 2 + + +@pytest.mark.parametrize( + "name", ("POPULACE_FIT_N_JOBS", "POPULACE_FIT_PREDICT_WORKERS") +) +@pytest.mark.parametrize("value", ("0", "01", "invalid")) +def test_primary_qrf_worker_identity_memo_refuses_invalid_environment( + _worker_identity_memo_inputs, + monkeypatch: pytest.MonkeyPatch, + name: str, + value: str, +) -> None: + monkeypatch.setenv(name, "1") + worker_identity_module.primary_qrf_worker_semantic_identity() + monkeypatch.setenv(name, value) + with pytest.raises(ValueError, match=name): + worker_identity_module.primary_qrf_worker_semantic_identity() + + +def test_primary_qrf_worker_identity_memo_binds_lock( + _worker_identity_memo_inputs, +) -> None: + first = worker_identity_module.primary_qrf_worker_semantic_identity() + legacy = worker_identity_module.primary_qrf_worker_semantic_identity( + uv_lock_sha256=worker_identity_module.LEGACY_CAMPAIGN_UV_LOCK_SHA256 + ) + assert first["uv_lock_sha256"] == worker_identity_module.APPROVED_UV_LOCK_SHA256 + assert ( + legacy["uv_lock_sha256"] + == worker_identity_module.LEGACY_CAMPAIGN_UV_LOCK_SHA256 + ) + assert legacy != first + assert worker_identity_module.primary_qrf_worker_semantic_identity() is first + for invalid in ("0" * 64, "malformed", []): + with pytest.raises(ValueError, match="lock"): + worker_identity_module.primary_qrf_worker_semantic_identity( + uv_lock_sha256=invalid + ) + + +def test_primary_qrf_worker_execution_binding_isolates_semantic_memo( + _worker_identity_memo_inputs, +) -> None: + memo = worker_identity_module.primary_qrf_worker_semantic_identity() + expected = deepcopy(memo) + binding = worker_identity_module.primary_qrf_worker_execution_binding() + semantic = binding["semantic_identity"] + semantic["interpreter"]["runtime_binary"]["bytes_sha256"] = "0" * 64 + semantic["argv_template"].append("--changed") + semantic["environment"]["overrides"]["TORCH_DEVICE_BACKEND_AUTOLOAD"] = "1" + fresh = worker_identity_module.primary_qrf_worker_execution_binding() + assert memo == expected + assert fresh["semantic_identity"] == expected + assert fresh["semantic_identity"] is not memo + assert fresh["semantic_identity"]["interpreter"] is not memo["interpreter"] + + +def test_worker_identity_session_prime_matches_pipeline_binding( + _session_primary_qrf_worker_identities, +) -> None: + key = ( + None, + worker_identity_module.os.environ.get("POPULACE_FIT_N_JOBS"), + worker_identity_module.os.environ.get("POPULACE_FIT_PREDICT_WORKERS"), + ) + memo = worker_identity_module._PRIMARY_QRF_WORKER_IDENTITY_CACHE + assert key in memo + first = memo[key] + binding = _fixture_primary_execution_config_binding()["qrf"]["worker_execution"] + assert binding["semantic_identity"] == first + assert worker_identity_module.primary_qrf_worker_semantic_identity() is first + assert first == _session_primary_qrf_worker_identities[key] + + +def test_live_worker_identity_namespace_source_mutation_recomputes( + _session_primary_qrf_worker_identities, + live_worker_identity, + _worker_identity_memo_inputs, +) -> None: + # The session fixture attests first; the opt-out must then remove it rather + # than restoring that identity over the temporary namespace used below. + assert _session_primary_qrf_worker_identities + assert not worker_identity_module._PRIMARY_QRF_WORKER_IDENTITY_CACHE + source, calls = _worker_identity_memo_inputs + before = worker_identity_module.primary_qrf_worker_semantic_identity() + source.write_text("# changed fixture worker\n", encoding="utf-8") + assert worker_identity_module.primary_qrf_worker_semantic_identity() is before + + live_worker_identity() + after = worker_identity_module.primary_qrf_worker_semantic_identity() + assert after is not before + assert ( + after["worker_module"]["transitive_imports_sha256"] + != before["worker_module"]["transitive_imports_sha256"] + ) + assert ( + after["transitive_environment_code_sha256"] + != before["transitive_environment_code_sha256"] + ) + assert len(calls) == 2 + + +@pytest.mark.usefixtures("live_worker_identity") +def test_worker_import_trace_refuses_empty_result() -> None: + with pytest.raises(RuntimeError, match="no readable namespace roots"): + worker_identity_module._validated_worker_import_trace( + { + "module_origins": {}, + "opened_files": (), + "namespace_roots": (), + } + ) + + +@pytest.mark.parametrize("cache_location", ["source_tree", "inherited_prefix"]) +@pytest.mark.parametrize("execution_path", ["identity_probe", "worker_module"]) +@pytest.mark.usefixtures("live_worker_identity") +def test_worker_identity_ignores_valid_header_stale_bytecode( + tmp_path: Path, + monkeypatch: pytest.MonkeyPatch, + cache_location: str, + execution_path: str, +) -> None: + import importlib.util + import marshal + import os + import struct + import subprocess + + trace = _fixture_worker_import_trace(tmp_path) + worker_source = Path( + trace["module_origins"][worker_identity_module.PRIMARY_QRF_WORKER_MODULE] + ) + (worker_source.parent.parent / "__init__.py").write_text("", encoding="utf-8") + marker = tmp_path / "worker-executed.txt" + worker_source.write_text( + f"from pathlib import Path\nPath({str(marker)!r}).write_text('source')\n", + encoding="utf-8", + ) + source_bytes = worker_source.read_bytes() + source_stat = worker_source.stat() + poisoned_code = compile( + f"from pathlib import Path\nPath({str(marker)!r}).write_text('stale cache')\n", + str(worker_source), + "exec", + optimize=sys.flags.optimize, + ) + inherited_prefix = ( + tmp_path / "inherited-cache" if cache_location == "inherited_prefix" else None + ) + with monkeypatch.context() as cache_path_context: + cache_path_context.setattr( + sys, + "pycache_prefix", + None if inherited_prefix is None else str(inherited_prefix), + ) + cache_path = Path(importlib.util.cache_from_source(str(worker_source))) + cache_path.parent.mkdir(parents=True) + # Python accepts this timestamp cache: its source mtime and size are valid, + # although the executable code object is unrelated to the source bytes. + cache_bytes = ( + importlib.util.MAGIC_NUMBER + + struct.pack( + " None: + trace = _fixture_worker_import_trace(tmp_path) + source = Path( + trace["module_origins"][worker_identity_module.PRIMARY_QRF_WORKER_MODULE] + ) + cache_path = source.with_suffix(suffix) + cache_path.write_bytes(b"unexpected executable cache") + trace["opened_files"] = (str(cache_path),) + + with pytest.raises(RuntimeError, match="unexpectedly read bytecode"): + worker_identity_module._worker_package_resource_rows(trace) + + +@pytest.mark.usefixtures("live_worker_identity") +def test_worker_identity_probe_cleans_cache_prefix_on_launch_failure( + tmp_path: Path, + monkeypatch: pytest.MonkeyPatch, +) -> None: + inherited_prefix = tmp_path / "inherited-cache" + inherited_prefix.mkdir() + (inherited_prefix / "keep.txt").write_text("caller cache", encoding="utf-8") + monkeypatch.setenv("PYTHONPYCACHEPREFIX", str(inherited_prefix)) + monkeypatch.setenv("PYTHONDONTWRITEBYTECODE", "0") + observed_prefixes: list[Path] = [] + + def fail_launch( + _argv: list[str], *, env: dict[str, str], **_kwargs: object + ) -> None: + prefix = Path(env["PYTHONPYCACHEPREFIX"]) + assert prefix != inherited_prefix + assert prefix.is_absolute() + assert prefix.is_dir() + assert list(prefix.iterdir()) == [] + assert env["PYTHONDONTWRITEBYTECODE"] == "1" + observed_prefixes.append(prefix) + raise OSError("fixture launch failure") + + monkeypatch.setattr(worker_identity_module.subprocess, "run", fail_launch) + with pytest.raises(RuntimeError, match="clean worker import could not run"): + worker_identity_module._clean_worker_import_trace() + + assert len(observed_prefixes) == 1 + assert not observed_prefixes[0].exists() + assert worker_identity_module.os.environ["PYTHONPYCACHEPREFIX"] == str( + inherited_prefix + ) + assert worker_identity_module.os.environ["PYTHONDONTWRITEBYTECODE"] == "0" + assert (inherited_prefix / "keep.txt").read_text(encoding="utf-8") == "caller cache" + + +@pytest.mark.usefixtures("live_worker_identity") +def test_primary_qrf_worker_identity_binds_loaded_runtime_bytes( + tmp_path: Path, + monkeypatch: pytest.MonkeyPatch, +) -> None: + _stub_worker_identity_static_closure(monkeypatch) + runtime = tmp_path / "libpython-fixture.so" + runtime.write_bytes(b"fixture runtime version one\n") + # ``raising=False`` makes this a behavioral red test on the vulnerable + # baseline: that implementation ignores the future loaded-runtime seam and + # therefore returns the same identity after the library changes. + monkeypatch.setattr( + worker_identity_module, + "_loaded_python_runtime_binary", + lambda: ("shared_library", runtime), + raising=False, + ) + monkeypatch.setattr( + worker_identity_module, + "_clean_worker_import_trace", + lambda *_args, **_kwargs: _fixture_worker_import_trace(tmp_path), + raising=False, + ) + + before = worker_identity_module.primary_qrf_worker_semantic_identity( + uv_lock_sha256=worker_identity_module.APPROVED_UV_LOCK_SHA256 + ) + runtime.write_bytes(b"fixture runtime version two\n") + worker_identity_module.clear_primary_qrf_worker_identity_cache() + after = worker_identity_module.primary_qrf_worker_semantic_identity( + uv_lock_sha256=worker_identity_module.APPROVED_UV_LOCK_SHA256 + ) + + assert before["interpreter"].get("runtime_binary") != after["interpreter"].get( + "runtime_binary" + ) + + +@pytest.mark.usefixtures("live_worker_identity") +def test_primary_qrf_worker_identity_binds_imported_stdlib_source( + tmp_path: Path, + monkeypatch: pytest.MonkeyPatch, +) -> None: + _stub_worker_identity_static_closure(monkeypatch) + stdlib = tmp_path / "stdlib" + stdlib.mkdir() + argparse_source = stdlib / "argparse.py" + argparse_source.write_text("FIXTURE_VALUE = 1\n", encoding="utf-8") + site_packages = tmp_path / "site-packages" + monkeypatch.setattr( + worker_identity_module, + "_loaded_python_runtime_binary", + lambda: ("shared_library", tmp_path / "unchanged-libpython.so"), + raising=False, + ) + (tmp_path / "unchanged-libpython.so").write_bytes(b"unchanged runtime\n") + monkeypatch.setattr( + worker_identity_module, + "_clean_worker_import_trace", + lambda *_args, **_kwargs: _fixture_worker_import_trace( + tmp_path, + module_origins={"argparse": str(argparse_source)}, + ), + raising=False, + ) + original_get_paths = worker_identity_module.sysconfig.get_paths + + def fixture_get_paths(*args: object, **kwargs: object) -> dict[str, str]: + paths = dict(original_get_paths(*args, **kwargs)) + paths.update( + { + "stdlib": str(stdlib), + "platstdlib": str(stdlib), + "purelib": str(site_packages), + "platlib": str(site_packages), + } + ) + return paths + + monkeypatch.setattr( + worker_identity_module.sysconfig, "get_paths", fixture_get_paths + ) + + before = worker_identity_module.primary_qrf_worker_semantic_identity( + uv_lock_sha256=worker_identity_module.APPROVED_UV_LOCK_SHA256 + ) + argparse_source.write_text("FIXTURE_VALUE = 2\n", encoding="utf-8") + worker_identity_module.clear_primary_qrf_worker_identity_cache() + after = worker_identity_module.primary_qrf_worker_semantic_identity( + uv_lock_sha256=worker_identity_module.APPROVED_UV_LOCK_SHA256 + ) + + assert before["interpreter"].get("stdlib_imports_sha256") != after[ + "interpreter" + ].get("stdlib_imports_sha256") + + +@pytest.mark.usefixtures("live_worker_identity") +def test_worker_identity_refuses_unapproved_torch_backend_provider_before_import( + monkeypatch: pytest.MonkeyPatch, +) -> None: + _stub_worker_identity_static_closure( + monkeypatch, + stub_installed_distributions=False, + ) + provider = SimpleNamespace( + metadata={"Name": "fixture-torch-backend"}, + version="1.0", + requires=(), + files=(), + entry_points=( + worker_identity_module.metadata.EntryPoint( + name="fixture_backend", + value="fixture_backend:register", + group="torch.backends", + ), + ), + ) + monkeypatch.setattr( + worker_identity_module.metadata, + "distributions", + lambda: (provider,), + ) + monkeypatch.setattr( + worker_identity_module.metadata, + "packages_distributions", + lambda: {}, + ) + + def unexpected_import_trace(*_args: object, **_kwargs: object) -> object: + pytest.fail("clean worker import ran before torch backend provider refusal") + + monkeypatch.setattr( + worker_identity_module, + "_clean_worker_import_trace", + unexpected_import_trace, + raising=False, + ) + + with pytest.raises(RuntimeError, match=r"torch\.backends"): + worker_identity_module.primary_qrf_worker_semantic_identity( + uv_lock_sha256=worker_identity_module.APPROVED_UV_LOCK_SHA256 + ) + + +@pytest.mark.usefixtures("live_worker_identity") +def test_worker_identity_refuses_duplicate_backend_provider_distribution_identity( + monkeypatch: pytest.MonkeyPatch, +) -> None: + entry_point = worker_identity_module.metadata.EntryPoint( + name="fixture_backend", + value="fixture_backend:register", + group="torch.backends", + ) + distributions = tuple( + SimpleNamespace( + metadata={"Name": "fixture-torch-backend"}, + version=version, + requires=(), + files=(), + entry_points=entry_points_for_distribution, + ) + for version, entry_points_for_distribution in ( + ("1.0", ()), + ("2.0", (entry_point,)), + ) + ) + monkeypatch.setattr( + worker_identity_module.metadata, + "distributions", + lambda: distributions, + ) + monkeypatch.setattr( + worker_identity_module.metadata, + "packages_distributions", + lambda: {"fixture_backend": ["fixture-torch-backend"]}, + ) + + with pytest.raises(RuntimeError, match="duplicate installed distribution identity"): + worker_identity_module._installed_distributions_record_sha256( + ("fixture_backend",) + ) + + +@pytest.mark.usefixtures("live_worker_identity") +def test_worker_transitive_source_identity_binds_actual_imported_package_resource( + tmp_path: Path, + monkeypatch: pytest.MonkeyPatch, +) -> None: + target_name = "soi_table_2_1_interest_components_ty2015.json" + trace = worker_identity_module._clean_worker_import_trace() + before = worker_identity_module._worker_package_resource_rows(trace) + stdlib_rows = worker_identity_module._worker_stdlib_import_rows(trace) + assert any(row["module"] == "argparse" for row in stdlib_rows) + target_rows = [ + row for row in before if str(row.get("resource", "")).endswith(target_name) + ] + assert len(target_rows) == 1 + target_resource = target_rows[0]["resource"] + target_sha256 = target_rows[0]["sha256"] + _stub_worker_identity_static_closure(monkeypatch) + runtime = tmp_path / "libpython-fixture.so" + runtime.write_bytes(b"fixture runtime\n") + monkeypatch.setattr( + worker_identity_module, + "_loaded_python_runtime_binary", + lambda: ("shared_library", runtime), + ) + monkeypatch.setattr( + worker_identity_module, + "_clean_worker_import_trace", + lambda: trace, + ) + identity_before = worker_identity_module.primary_qrf_worker_semantic_identity( + uv_lock_sha256=worker_identity_module.APPROVED_UV_LOCK_SHA256 + ) + original_read_bytes = Path.read_bytes + + def changed_resource_bytes(path: Path) -> bytes: + raw = original_read_bytes(path) + if path.name == target_name: + return raw + b"\n" + return raw + + monkeypatch.setattr(Path, "read_bytes", changed_resource_bytes) + worker_identity_module.clear_primary_qrf_worker_identity_cache() + after = worker_identity_module._worker_package_resource_rows(trace) + identity_after = worker_identity_module.primary_qrf_worker_semantic_identity( + uv_lock_sha256=worker_identity_module.APPROVED_UV_LOCK_SHA256 + ) + changed_target = next(row for row in after if row["resource"] == target_resource) + + assert changed_target["sha256"] != target_sha256 + assert worker_identity_module._canonical_sha256(after) != ( + worker_identity_module._canonical_sha256(before) + ) + assert ( + identity_after["worker_module"]["transitive_imports_sha256"] + != (identity_before["worker_module"]["transitive_imports_sha256"]) + ) + assert worker_identity_module._canonical_sha256(identity_after) != ( + worker_identity_module._canonical_sha256(identity_before) + ) + + +@pytest.mark.parametrize( + "semantic_change", + ( + "interpreter_bytes", + "runtime_binary", + "stdlib_imports", + "implementation", + "version", + "abi", + "cache_tag", + "pyvenv_implementation", + "pyvenv_version", + "pyvenv_include_system", + "pyvenv_uv", + "worker_module", + "worker_source", + "transitive_source", + "argv_1", + "argv_2", + "argv_3", + "argv_4", + "argv_5", + "argv_6", + "uv_lock", + "distribution_record", + "environment_code", + "fit_jobs", + "predict_workers", + "torch_backend_autoload", + "python_dont_write_bytecode", + "python_pycache_prefix", + ), +) +def test_late_primary_worker_authentication_rejects_semantic_matrix( + semantic_change: str, +) -> None: + binding = _fixture_primary_execution_config_binding() + worker = binding["qrf"]["worker_execution"] + semantic = worker["semantic_identity"] + refresh_environment_code = False + if semantic_change == "interpreter_bytes": + semantic["interpreter"]["bytes_sha256"] = "0" * 64 + elif semantic_change == "runtime_binary": + semantic["interpreter"]["runtime_binary"]["bytes_sha256"] = "0" * 64 + elif semantic_change == "stdlib_imports": + semantic["interpreter"]["stdlib_imports_sha256"] = "0" * 64 + elif semantic_change == "implementation": + semantic["interpreter"]["implementation"] = "changed" + elif semantic_change == "version": + semantic["interpreter"]["version"] = [99, 0, 0] + elif semantic_change == "abi": + semantic["interpreter"]["abi"]["soabi"] = "changed" + elif semantic_change == "cache_tag": + semantic["interpreter"]["cache_tag"] = "changed" + elif semantic_change == "pyvenv_implementation": + semantic["interpreter"]["pyvenv_cfg"]["implementation"] = "changed" + elif semantic_change == "pyvenv_version": + semantic["interpreter"]["pyvenv_cfg"]["version"] = [99, 0, 0] + elif semantic_change == "pyvenv_include_system": + pyvenv = semantic["interpreter"]["pyvenv_cfg"] + pyvenv["include_system_site_packages"] = not pyvenv[ + "include_system_site_packages" + ] + elif semantic_change == "pyvenv_uv": + semantic["interpreter"]["pyvenv_cfg"]["uv_version"] = "changed" + elif semantic_change == "worker_module": + semantic["worker_module"]["name"] = "changed.worker" + elif semantic_change == "worker_source": + semantic["worker_module"]["source_sha256"] = "0" * 64 + refresh_environment_code = True + elif semantic_change == "transitive_source": + semantic["worker_module"]["transitive_imports_sha256"] = "0" * 64 + refresh_environment_code = True + elif semantic_change.startswith("argv_"): + semantic["argv_template"][int(semantic_change.removeprefix("argv_"))] = ( + "changed" + ) + elif semantic_change == "uv_lock": + semantic["uv_lock_sha256"] = "0" * 64 + elif semantic_change == "distribution_record": + semantic["installed_distributions_record_sha256"] = "0" * 64 + refresh_environment_code = True + elif semantic_change == "environment_code": + semantic["transitive_environment_code_sha256"] = "0" * 64 + elif semantic_change == "fit_jobs": + semantic["environment"]["semantic_controls"]["POPULACE_FIT_N_JOBS"][ + "resolved" + ] = 1 + elif semantic_change == "predict_workers": + predict = semantic["environment"]["semantic_controls"][ + "POPULACE_FIT_PREDICT_WORKERS" + ] + predict["resolved"] = int(predict["resolved"]) + 1 + elif semantic_change == "python_dont_write_bytecode": + semantic["environment"]["overrides"]["PYTHONDONTWRITEBYTECODE"] = "0" + elif semantic_change == "python_pycache_prefix": + semantic["environment"]["overrides"]["PYTHONPYCACHEPREFIX"] = "/existing/cache" + else: + semantic["environment"]["overrides"]["TORCH_DEVICE_BACKEND_AUTOLOAD"] = "1" + if refresh_environment_code: + semantic["transitive_environment_code_sha256"] = ( + worker_identity_module._canonical_sha256( + { + "worker_module_source_sha256": semantic["worker_module"][ + "source_sha256" + ], + "transitive_imports_sha256": semantic["worker_module"][ + "transitive_imports_sha256" + ], + "installed_distributions_record_sha256": semantic[ + "installed_distributions_record_sha256" + ], + } + ) + ) + worker["semantic_identity_sha256"] = worker_identity_module._canonical_sha256( + semantic + ) + + with pytest.raises(ValueError, match="worker (binding|identity)"): + _validate_fixture_primary_execution_config(binding) + + +def test_portable_worker_identity_does_not_mutate_origin_battery_receipt() -> None: + values = np.asarray([True, True, True, False, False, False], dtype=bool) + frame = _battery_frame({"has_esi": (values, values.copy())}) + assert frame.n("household") == 12 + surface = {"person": {"model_required_boolean": ("has_esi",)}} + authority = stacked_spine_module._make_test_stacked_authority( + declared_surface=surface, + metric_registry={ + ("person", "model_required_boolean", "has_esi", 0): ("boolean_incidence") + }, + support_profile=replace( + stacked_spine_module.CANONICAL_ORIGIN_BATTERY_SUPPORT_PROFILE, + min_effective_support=5, + ), + ) + before = stacked_spine_module._by_origin_battery_with_test_authority( + frame, + authority=authority, + ) + before_receipt = stacked_spine_module._json_ready( + { + "name": before.name, + "passed": before.passed, + "failures": list(before.failures), + "details": before.details, + } + ) + + config = _fixture_primary_execution_config_binding() + config["qrf"]["worker_execution"]["audit_aliases"]["sys_prefix"] = ( + "/relocated/worktree/.venv" + ) + _validate_fixture_primary_execution_config(config) + after = stacked_spine_module._by_origin_battery_with_test_authority( + frame, + authority=authority, + ) + after_receipt = stacked_spine_module._json_ready( + { + "name": after.name, + "passed": after.passed, + "failures": list(after.failures), + "details": after.details, + } + ) + + label = "person/model_required_boolean/has_esi[clone_0]" + comparison = after.details["comparisons"][label] + assert before_receipt == after_receipt + assert stacked_spine_module._canonical_sha256(before_receipt) == ( + stacked_spine_module._canonical_sha256(after_receipt) + ) + assert after.passed is True + assert after.failures == () + assert comparison["status"] == "tested" + assert comparison["nonzero_rows"] == {"asec": 3, "acs": 3} + assert comparison["asec_incidence"] == 0.5 + assert comparison["acs_incidence"] == 0.5 + assert comparison["incidence_ratio_acs_over_asec"] == 1.0 + + +def test_legacy_worker_mismatch_paths_reproduce_sealed_stop_case() -> None: + sealed_interpreter = ( + "/Users/maxghenis/PolicyEngine/_worktrees/microcosm-c26-build/.venv/bin/python" + ) + replay_interpreter = "/private/tmp/microcosm-c27-rootcause/.venv/bin/python" + common_argv = [ + "-m", + "microcosm.build.us_runtime.puf_qrf_worker", + "--checkpoint-dir", + "{checkpoint_dir}", + "--target-index", + "{target_index}", + ] + sealed_worker = { + "module": "microcosm.build.us_runtime.puf_qrf_worker", + "argv_template": [sealed_interpreter, *common_argv], + "interpreter": { + "executable": sealed_interpreter, + "resolved_executable": ( + "/Users/maxghenis/.local/share/uv/python/" + "cpython-3.14.4-macos-aarch64-none/bin/python3.14" + ), + "implementation": "cpython", + "cache_tag": "cpython-314", + "version": [3, 14, 4], + }, + "environment": { + "policy": "inherit_parent_environment_with_bound_fit_controls", + "overrides": {}, + "semantic_controls": { + "POPULACE_FIT_N_JOBS": {"configured": None, "resolved": -1}, + "POPULACE_FIT_PREDICT_WORKERS": { + "configured": "18", + "resolved": 18, + "resolution": "environment_override", + }, + }, + "bound_names": [ + "POPULACE_FIT_N_JOBS", + "POPULACE_FIT_PREDICT_WORKERS", + ], + }, + } + replay_worker = deepcopy(sealed_worker) + replay_worker["argv_template"][0] = replay_interpreter + replay_worker["interpreter"]["executable"] = replay_interpreter + + mismatch_paths = stacked_spine_module._legacy_worker_execution_mismatch_paths( + sealed_worker, + replay_worker, + ) + + assert set(mismatch_paths) == { + "argv_template[0]", + "interpreter.executable", + } + + +@pytest.mark.usefixtures("live_worker_identity") def test_late_primary_resources_bind_donor_content_and_execution_config( monkeypatch: pytest.MonkeyPatch, ) -> None: @@ -4238,7 +5395,7 @@ def test_late_primary_resources_bind_donor_content_and_execution_config( "tax_unit_outputs": "canonical_default", } execution = baseline["tax_unit.@primary_puf_execution_config"]["binding"] - assert execution["schema_version"] == 4 + assert execution["schema_version"] == 5 assert execution["clone_attachment"]["support_channels"] == [ stacked_spine_module.BASE_ASEC_SUPPORT_CHANNEL, stacked_spine_module.PUF_TAX_DETAIL_SUPPORT_CHANNEL, @@ -4267,9 +5424,36 @@ def test_late_primary_resources_bind_donor_content_and_execution_config( } } worker = execution["qrf"]["worker_execution"] - assert worker["module"] == "microcosm.build.us_runtime.puf_qrf_worker" - assert worker["argv_template"] == [ - worker["interpreter"]["executable"], + assert set(worker) == { + "schema_version", + "semantic_identity", + "semantic_identity_sha256", + "audit_aliases", + } + assert worker["schema_version"] == 1 + semantic = worker["semantic_identity"] + assert semantic["worker_module"]["name"] == ( + "microcosm.build.us_runtime.puf_qrf_worker" + ) + interpreter = semantic["interpreter"] + assert set(interpreter) == { + "bytes_sha256", + "runtime_binary", + "stdlib_imports_sha256", + "implementation", + "version", + "abi", + "cache_tag", + "pyvenv_cfg", + } + assert interpreter["runtime_binary"]["kind"] in { + "shared_library", + "statically_linked_executable", + } + assert len(interpreter["runtime_binary"]["bytes_sha256"]) == 64 + assert len(interpreter["stdlib_imports_sha256"]) == 64 + assert semantic["argv_template"] == [ + worker_identity_module.PRIMARY_QRF_INTERPRETER_PLACEHOLDER, "-m", "microcosm.build.us_runtime.puf_qrf_worker", "--checkpoint-dir", @@ -4277,14 +5461,29 @@ def test_late_primary_resources_bind_donor_content_and_execution_config( "--target-index", "{target_index}", ] - environment = worker["environment"] + assert worker["semantic_identity_sha256"] == ( + worker_identity_module._canonical_sha256(semantic) + ) + assert worker["audit_aliases"] == { + "sys_executable": str(Path(sys.executable)), + "sys_prefix": str(Path(sys.prefix)), + "argv_template_0": str(Path(sys.executable)), + } + environment = semantic["environment"] assert environment["policy"] == ( - "inherit_parent_environment_with_bound_fit_controls" + "inherit_parent_environment_with_bound_fit_controls_and_forced_overrides" ) - assert environment["overrides"] == {} + assert environment["overrides"] == { + "TORCH_DEVICE_BACKEND_AUTOLOAD": "0", + "PYTHONDONTWRITEBYTECODE": "1", + "PYTHONPYCACHEPREFIX": "{empty_pycache_dir}", + } assert environment["bound_names"] == [ "POPULACE_FIT_N_JOBS", "POPULACE_FIT_PREDICT_WORKERS", + "TORCH_DEVICE_BACKEND_AUTOLOAD", + "PYTHONDONTWRITEBYTECODE", + "PYTHONPYCACHEPREFIX", ] assert environment["semantic_controls"] == { "POPULACE_FIT_N_JOBS": {"configured": None, "resolved": -1}, @@ -4374,6 +5573,14 @@ def test_late_primary_resource_identity_binds_every_tail_control( name: str, replacement: object, ) -> None: + # In-memory tail controls change the resource config, while the worker's + # installed source and startup environment remain identical in both calls. + worker = _fixture_primary_execution_config_binding()["qrf"]["worker_execution"] + monkeypatch.setattr( + stacked_spine_module, + "_late_primary_qrf_worker_execution_binding", + lambda: deepcopy(worker), + ) donor = pd.DataFrame({"fixture_donor": [1.0]}) common = { "primary_qrf_checkpoint_identity_sha256": "a" * 64, @@ -4460,6 +5667,7 @@ def test_stacked_primary_qrf_refuses_unbound_surface_and_missing_audit_sink() -> binding = stacked_spine_module.stacked_late_primary_checkpoint_input_binding( resources ) + assert binding["schema_version"] == 2 frame = _late_primary_entry(_stacked_gap_fixture()) with pytest.raises(ValueError, match=r"canonical predictor/output surface"): @@ -4534,6 +5742,167 @@ def test_late_primary_resource_rejects_shallow_receipt_before_callback() -> None ) +@pytest.mark.usefixtures("live_worker_identity") +def test_stacked_worker_first_torch_import_forces_autoload_off( + monkeypatch: pytest.MonkeyPatch, + tmp_path: Path, +) -> None: + """Exercise the stacked launch in a child with no preloaded parent packages.""" + + import subprocess + + import microcosm.build.us_runtime.puf_qrf_chain as chain_module + + monkeypatch.setenv("TORCH_DEVICE_BACKEND_AUTOLOAD", "1") + inherited_prefix = tmp_path / "inherited-pycache" + inherited_prefix.mkdir() + monkeypatch.setenv("PYTHONPYCACHEPREFIX", str(inherited_prefix)) + monkeypatch.setenv("PYTHONDONTWRITEBYTECODE", "") + worker_binding = _fixture_primary_execution_config_binding()["qrf"][ + "worker_execution" + ] + monkeypatch.setattr( + stacked_spine_module, + "_late_primary_qrf_worker_execution_binding", + lambda: deepcopy(worker_binding), + ) + checkpoint_identity = "a" * 64 + checkpoint_dir = tmp_path / checkpoint_identity + donor = pd.DataFrame({"fixture_donor": [1.0]}) + + def initialize(_frame: Frame, _donor: pd.DataFrame, root: Path, **_kwargs) -> None: + root.mkdir(parents=True) + (root / stacked_spine_module.PRIMARY_QRF_MANIFEST_FILENAME).write_text("{}") + + monkeypatch.setattr( + stacked_spine_module, "initialize_primary_puf_qrf_chain", initialize + ) + monkeypatch.setattr( + stacked_spine_module, + "primary_puf_qrf_recipient_predictor_universe_receipt", + lambda _root: {"fixture": "recipient-universe"}, + ) + monkeypatch.setattr( + stacked_spine_module, + "finalize_primary_puf_qrf_chain", + lambda frame, _root, **_kwargs: ( + frame, + frame.resolve_weights("tax_unit").kind, + ), + ) + # Keep the real chain's subprocess argv/environment assembly; replace only + # the model/checkpoint work, which the first-import probe never reaches. + monkeypatch.setattr( + chain_module, + "_load_manifest", + lambda _root: {"target_order": ["fixture"], "initial_state": {}}, + ) + monkeypatch.setattr( + chain_module, "QRFChainState", SimpleNamespace(from_dict=lambda _raw: None) + ) + monkeypatch.setattr( + chain_module, "_load_target_checkpoint", lambda *_args, **_kwargs: (None, None) + ) + observed: list[dict[str, object]] = [] + launch_prefixes: list[Path] = [] + script = r""" +import builtins +import json +import os +import runpy +import sys + +assert "torch" not in sys.modules +assert "microcosm.build" not in sys.modules +original_import = builtins.__import__ + +def record_first_torch_import(name, *args, **kwargs): + if name == "torch" or name.startswith("torch."): + print("FIRST_TORCH_IMPORT=" + json.dumps({ + "autoload": os.environ.get("TORCH_DEVICE_BACKEND_AUTOLOAD"), + "worker_loaded": "microcosm.build.us_runtime.puf_qrf_worker" in sys.modules, + "pycache_prefix": sys.pycache_prefix, + "dont_write_bytecode": sys.flags.dont_write_bytecode, + }), flush=True) + raise SystemExit(0) + return original_import(name, *args, **kwargs) + +builtins.__import__ = record_first_torch_import +sys.argv = [sys.argv[1], *sys.argv[2:]] +runpy.run_module("microcosm.build.us_runtime.puf_qrf_worker", run_name="__main__") +raise AssertionError("worker never imported torch") +""" + + def launch_probe(argv: list[str], **kwargs): + assert argv[1:3] == ["-m", worker_identity_module.PRIMARY_QRF_WORKER_MODULE] + prefix = Path(kwargs["env"]["PYTHONPYCACHEPREFIX"]) + assert prefix.is_absolute() and prefix.is_dir() + assert prefix != inherited_prefix + assert not list(prefix.iterdir()) + launch_prefixes.append(prefix) + completed = subprocess.run( + [argv[0], "-c", script, *argv[2:]], + **kwargs, + capture_output=True, + text=True, + timeout=120, + ) + assert completed.returncode == 0, completed.stderr + for line in completed.stdout.splitlines(): + if line.startswith("FIRST_TORCH_IMPORT="): + observed.append(json.loads(line.removeprefix("FIRST_TORCH_IMPORT="))) + return completed + + monkeypatch.setattr(chain_module, "subprocess", SimpleNamespace(run=launch_probe)) + resources = stacked_spine_module.stacked_late_primary_resource_receipts( + donor, + primary_qrf_checkpoint_identity_sha256=checkpoint_identity, + clone_attachment_fraction=1.0, + clone_attachment_seed=578, + seed=0, + n_estimators=100, + fit_records_enabled=True, + tail_bound_diagnostics_enabled=True, + ) + stacked_spine_module._run_stacked_puf_pass_without_tail_for_test( + _late_primary_entry(_stacked_gap_fixture()), + donor, + clone_attachment_fraction=1.0, + clone_attachment_seed=578, + fit_records=[], + tail_bound_diagnostics=[], + primary_qrf_checkpoint_dir=checkpoint_dir, + primary_qrf_input_binding=( + stacked_spine_module.stacked_late_primary_checkpoint_input_binding( + resources + ) + ), + ) + + assert len(launch_prefixes) == 1 + assert observed == [ + { + "autoload": "0", + "worker_loaded": False, + "pycache_prefix": str(launch_prefixes[0]), + "dont_write_bytecode": 1, + } + ] + assert not launch_prefixes[0].exists() + assert inherited_prefix.is_dir() + assert stacked_spine_module.os.environ["PYTHONPYCACHEPREFIX"] == str( + inherited_prefix + ) + assert stacked_spine_module.os.environ["PYTHONDONTWRITEBYTECODE"] == "" + assert ( + worker_binding["semantic_identity"]["environment"]["overrides"][ + "TORCH_DEVICE_BACKEND_AUTOLOAD" + ] + == "0" + ) + assert stacked_spine_module.os.environ["TORCH_DEVICE_BACKEND_AUTOLOAD"] == "1" + + def test_stacked_primary_qrf_refuses_stale_bound_checkpoint( monkeypatch: pytest.MonkeyPatch, tmp_path: Path, @@ -4630,6 +5999,98 @@ def binding(bound_donor: pd.DataFrame) -> dict[str, object]: ) +def test_relocated_checkpoint_resume_reports_the_retained_sidecar_digest( + monkeypatch: pytest.MonkeyPatch, + tmp_path: Path, +) -> None: + """Resume across a worker relocation keeps the sidecar's bytes, so the + receipt must report the sidecar's own authenticated digest, not the live + binding's, which hashes the current audit aliases.""" + checkpoint_identity = "a" * 64 + checkpoint_dir = tmp_path / checkpoint_identity + donor = pd.DataFrame({"fixture_donor": [1.0]}) + + def initialize(_frame: Frame, _donor: pd.DataFrame, root: Path, **_kwargs) -> None: + root.mkdir(parents=True) + (root / stacked_spine_module.PRIMARY_QRF_MANIFEST_FILENAME).write_text( + "{}", + encoding="utf-8", + ) + + monkeypatch.setattr( + stacked_spine_module, "initialize_primary_puf_qrf_chain", initialize + ) + monkeypatch.setattr( + stacked_spine_module, + "primary_puf_qrf_recipient_predictor_universe_receipt", + lambda _root: {"fixture": "recipient-universe"}, + ) + monkeypatch.setattr( + stacked_spine_module, "run_primary_puf_qrf_chain", lambda _root, **_kwargs: None + ) + monkeypatch.setattr( + stacked_spine_module, + "finalize_primary_puf_qrf_chain", + lambda frame, _root, **_kwargs: (frame, frame.resolve_weights("tax_unit").kind), + ) + + def binding(bound_donor: pd.DataFrame) -> dict[str, object]: + resources = stacked_spine_module.stacked_late_primary_resource_receipts( + bound_donor, + primary_qrf_checkpoint_identity_sha256=checkpoint_identity, + clone_attachment_fraction=1.0, + clone_attachment_seed=578, + seed=0, + n_estimators=100, + fit_records_enabled=True, + tail_bound_diagnostics_enabled=True, + ) + return stacked_spine_module.stacked_late_primary_checkpoint_input_binding( + resources + ) + + def run(input_binding: dict[str, object]): + return stacked_spine_module._run_stacked_puf_pass_without_tail_for_test( + _late_primary_entry(_stacked_gap_fixture()), + donor, + clone_attachment_fraction=1.0, + clone_attachment_seed=578, + fit_records=[], + tail_bound_diagnostics=[], + primary_qrf_checkpoint_dir=checkpoint_dir, + primary_qrf_input_binding=input_binding, + ) + + initialized = run(binding(donor)).receipt["primary_puf_qrf"] + sidecar_path = checkpoint_dir / "late-producer-input-binding.json" + sidecar_bytes = sidecar_path.read_bytes() + sidecar_digest = json.loads(sidecar_bytes)["sha256"] + assert initialized["resume_status"] == "initialized" + assert initialized["input_binding_sha256"] == sidecar_digest + + real_binding = stacked_spine_module._late_primary_qrf_worker_execution_binding + + def relocated_binding() -> dict[str, object]: + relocated = copy.deepcopy(real_binding()) + relocated["audit_aliases"]["sys_executable"] = "/relocated/venv/bin/python" + relocated["audit_aliases"]["sys_prefix"] = "/relocated/venv" + return relocated + + monkeypatch.setattr( + stacked_spine_module, + "_late_primary_qrf_worker_execution_binding", + relocated_binding, + ) + live_binding = binding(donor) + assert live_binding["sha256"] != sidecar_digest, "aliases must move the live digest" + + resumed = run(live_binding).receipt["primary_puf_qrf"] + + assert resumed["resume_status"] == "resumed" + assert sidecar_path.read_bytes() == sidecar_bytes + assert resumed["input_binding_sha256"] == sidecar_digest + + def test_late_transfer_rejects_identityless_bank_before_dispatch() -> None: group = stacked_spine_module.CANONICAL_US_LATE_TRANSFER_GROUPS[0] @@ -5446,9 +6907,9 @@ def transfer( "residual_null_rows": 0, } if target == "is_pregnant": - pregnancy_policy = execution_contract[ - "structural_target_policies" - ]["is_pregnant"] + pregnancy_policy = execution_contract["structural_target_policies"][ + "is_pregnant" + ] target_receipt["structural_policy"] = { "policy_sha256": pregnancy_policy["sha256"], "source_person_key": "person_source_id", @@ -6360,7 +7821,9 @@ def test_post_puf_transfer_preserves_complete_asec_source_producers() -> None: ) -def test_complete_pregnancy_surface_retains_zero_imputation_structural_receipt() -> None: +def test_complete_pregnancy_surface_retains_zero_imputation_structural_receipt() -> ( + None +): frame = _post_puf_transfer_fixture() person = frame.table("person").copy() recipient_rows = person[support_channel_column("person")].astype(str).eq("acs") @@ -6389,9 +7852,7 @@ def test_complete_pregnancy_surface_retains_zero_imputation_structural_receipt() n_estimators=10, ) - receipt = result.receipt["targets"][ - "person/model_required_boolean/is_pregnant" - ] + receipt = result.receipt["targets"]["person/model_required_boolean/is_pregnant"] assert receipt["authorized_null_rows"] == 0 assert receipt["imputed_rows"] == 0 assert receipt["structural_policy"]["status"] == "verified" @@ -6412,9 +7873,7 @@ def test_post_puf_transfer_refuses_invalid_pregnancy_source_producer() -> None: person["is_female"].astype(bool) & person["age"].between(15, 44, inclusive="both") ) - donor_ineligible = ineligible & person[ - support_clone_index_column("person") - ].eq(1) + donor_ineligible = ineligible & person[support_clone_index_column("person")].eq(1) person.loc[person.index[donor_ineligible][0], "is_pregnant"] = True tables = {entity: frame.table(entity) for entity in frame.entities} tables["person"] = person @@ -8228,7 +9687,7 @@ def test_self_digested_partial_authority_cannot_forge_production_identity() -> N GateReport((result,)).to_manifest() -@pytest.mark.parametrize("stale_version", (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)) +@pytest.mark.parametrize("stale_version", (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)) def test_self_consistent_stale_stacked_authority_versions_are_rejected( stale_version: int, ) -> None: @@ -8249,7 +9708,7 @@ def test_self_consistent_stale_stacked_authority_versions_are_rejected( ) stale_receipt = stacked_spine_module._authority_receipt(stale) - assert stacked_spine_module.stacked_spine_authority_receipt()["version"] == 11 + assert stacked_spine_module.stacked_spine_authority_receipt()["version"] == 12 assert stale_receipt["version"] == stale_version assert stale_receipt["integrity_valid"] is True assert stale_receipt["digest_matches_declared"] is True @@ -8268,7 +9727,7 @@ def test_stacked_authority_binds_import_validated_late_producer_schedule() -> No receipt = stacked_spine_module.stacked_spine_authority_receipt() component = receipt["components"]["late_producer_schedule"] - assert receipt["version"] == 11 + assert receipt["version"] == 12 assert component["producer_count"] == 38 assert component["schedule_sha256"] == ( stacked_spine_module.CANONICAL_US_LATE_PRODUCER_SCHEDULE.sha256 diff --git a/tools/build_us_fiscal_refresh_release.py b/tools/build_us_fiscal_refresh_release.py index 71eb7f907..acb168644 100644 --- a/tools/build_us_fiscal_refresh_release.py +++ b/tools/build_us_fiscal_refresh_release.py @@ -8359,23 +8359,42 @@ def _exact_k_ladder_manifest_payload( raise RuntimeError("Validated pool manifest lost a required receipt block.") if agreement_gate.get("passed") is not True: raise RuntimeError("Validated pool manifest lost its passing agreement gate.") + worker_execution_authentication = ( + authenticated_pool_h5.worker_execution_authentication + ) + if ( + pool_manifest.get("worker_execution_authentication") + != worker_execution_authentication + ): + raise RuntimeError( + "Validated pool manifest worker authentication receipt changed." + ) pool_release_id = _assert_pool_release_id_value( args.pool_release_id, authenticated_pool_h5.publication_run_id, ) + pool_receipt = { + "release_id": pool_release_id, + "release_id_source": "pool_manifest.publication_run_id", + "manifest_sha256": authenticated_pool_h5.manifest_sha256, + "publication_run_id": authenticated_pool_h5.publication_run_id, + "pool_h5_sha256": authenticated_pool_h5.sha256, + "pool_h5_size_bytes": authenticated_pool_h5.size_bytes, + "agreement_diagnostics_sha256": agreement_diagnostics.get("sha256"), + } + if worker_execution_authentication is not None: + if not isinstance(worker_execution_authentication, Mapping): + raise RuntimeError( + "Validated pool manifest has a malformed worker authentication receipt." + ) + pool_receipt["worker_execution_authentication"] = dict( + worker_execution_authentication + ) payload = exact_k_ladder_manifest_payload( outcome, k=int(args.exact_k), seed=int(args.seed), - pool={ - "release_id": pool_release_id, - "release_id_source": "pool_manifest.publication_run_id", - "manifest_sha256": authenticated_pool_h5.manifest_sha256, - "publication_run_id": authenticated_pool_h5.publication_run_id, - "pool_h5_sha256": authenticated_pool_h5.sha256, - "pool_h5_size_bytes": authenticated_pool_h5.size_bytes, - "agreement_diagnostics_sha256": agreement_diagnostics.get("sha256"), - }, + pool=pool_receipt, agreement_gate_reference={ "passed": True, "publication_run_id": authenticated_pool_h5.publication_run_id, diff --git a/tools/build_us_multispine_pool.py b/tools/build_us_multispine_pool.py index 23e0de84d..7cc27764c 100644 --- a/tools/build_us_multispine_pool.py +++ b/tools/build_us_multispine_pool.py @@ -228,6 +228,9 @@ CANONICAL_US_LATE_TRANSFER_GROUPS, us_late_producer_schedule_receipt, ) +from microcosm.build.us_runtime.worker_identity import ( + current_worker_execution_authentication_receipt, +) from microcosm.frame import US_SCHEMA, Frame __all__ = [ @@ -329,6 +332,7 @@ _STACKED_CHECKPOINT_IDENTITY_ARTIFACT_KIND = ( "populace_us_stacked_pool_checkpoint_identity" ) +# Version 13 binds the portable authenticated primary-QRF worker identity. # Version 12 binds the post-assembly household geography assignment authority, # target vintage, algorithm, operator order, and seed. Earlier checkpoints # predate the congressional-district support required by release preflight. @@ -336,7 +340,7 @@ # Earlier checkpoints must rebuild rather than resume with a nullable # s_corp_income leaf. Version 10 bound the complete late-resource semantics and # corrected outer order (the primary PUF callback is nested inside the DAG). -_STACKED_CHECKPOINT_MATERIALIZER_VERSION = 12 +_STACKED_CHECKPOINT_MATERIALIZER_VERSION = 13 _STACKED_RELEASE_ID_PATTERN = re.compile( r"^populace-us-2024-stacked-f(?:001|004|010|025|100)-s[0-9]+-" r"asec[0-9]+-acs[0-9]+-[0-9]{8}T[0-9]{6}Z-[0-9a-f]{8}$" @@ -1648,9 +1652,7 @@ def _ordered_household_geography_receipt( dtype=np.float64, na_value=np.nan, ) - valid_ids = np.isfinite(household_ids) & ( - household_ids == np.floor(household_ids) - ) + valid_ids = np.isfinite(household_ids) & (household_ids == np.floor(household_ids)) if not valid_ids.all(): raise ValueError("Stacked geography output household IDs must be integral.") @@ -1718,9 +1720,11 @@ def _validate_stacked_geography_assignment_receipt( ) -> None: """Bind a live assembled-or-later Frame to its assignment receipt.""" - if receipt.get("artifact_kind") != ( - "populace_us_stacked_household_geography_assignment" - ) or receipt.get("schema_version") != 1: + if ( + receipt.get("artifact_kind") + != ("populace_us_stacked_household_geography_assignment") + or receipt.get("schema_version") != 1 + ): raise ValueError(f"{boundary}: geography assignment receipt is unsupported.") expected_contract = _stacked_geography_assignment_contract() if _json_ready(receipt.get("contract")) != _json_ready(expected_contract): @@ -1729,9 +1733,7 @@ def _validate_stacked_geography_assignment_receipt( target_districts ) if receipt.get("target_universe") != expected_universe: - raise ValueError( - f"{boundary}: congressional-district target universe changed." - ) + raise ValueError(f"{boundary}: congressional-district target universe changed.") output = receipt.get("output") if not isinstance(output, Mapping): raise ValueError(f"{boundary}: geography assignment output is missing.") @@ -1759,9 +1761,10 @@ def _validate_stacked_geography_assignment_receipt( clone_index = pd.to_numeric(household[clone_column], errors="coerce") native_household = household.loc[clone_index.eq(0)] expected_order = receipt.get("pre_assignment_household_order") - if ( - len(native_household) != assigned_rows - or expected_order != _ordered_household_id_receipt(native_household) + if len( + native_household + ) != assigned_rows or expected_order != _ordered_household_id_receipt( + native_household ): raise ValueError( f"{boundary}: ordered native household IDs differ from the seeded " @@ -1901,9 +1904,7 @@ def _assign_stacked_household_geography( "schema_version": 1, "contract": _stacked_geography_assignment_contract(), "pre_assignment_household_order": pre_assignment_order, - "assigned_household_geography": _ordered_household_geography_receipt( - household - ), + "assigned_household_geography": _ordered_household_geography_receipt(household), "target_universe": _target_congressional_district_universe_receipt( target_districts ), @@ -4130,6 +4131,49 @@ def _stacked_run_config_receipt( return normalized +def _stacked_worker_execution_authentication( + stage_receipts: Mapping[str, object], +) -> dict[str, object]: + """Derive publication evidence from the signed primary-QRF DAG resource.""" + + impute = stage_receipts.get("impute") + dag = ( + impute.get("stacked_late_producer_dag") if isinstance(impute, Mapping) else None + ) + execution = dag.get("execution") if isinstance(dag, Mapping) else None + primary_rows = [ + row + for row in execution or () + if isinstance(row, Mapping) and row.get("producer") == "primary_puf_qrf" + ] + if len(primary_rows) != 1: + raise ValueError( + "Stacked publication must carry exactly one primary-QRF execution row." + ) + available = primary_rows[0].get("available_input_receipts") + config_receipt = ( + available.get("tax_unit.@primary_puf_execution_config") + if isinstance(available, Mapping) + else None + ) + config = ( + config_receipt.get("binding") if isinstance(config_receipt, Mapping) else None + ) + qrf = config.get("qrf") if isinstance(config, Mapping) else None + if ( + not isinstance(config, Mapping) + or config.get("schema_version") != 5 + or not isinstance(qrf, Mapping) + ): + raise ValueError("Stacked publication primary execution config changed.") + return current_worker_execution_authentication_receipt( + qrf.get("worker_execution"), + manifest_schema_version=POOL_MANIFEST_SCHEMA_VERSION, + execution_config_schema_version=5, + boundary="stacked publication primary-QRF worker", + ) + + def _stacked_manifest_payload( *, result: StackedPoolBuildResult, @@ -4177,6 +4221,9 @@ def _stacked_manifest_payload( _assert_stacked_geography_verified_inputs(verified_inputs) gates = _stacked_gate_payload(result) stack_manifest = _json_ready(result.stack_receipt) + worker_execution_authentication = _stacked_worker_execution_authentication( + result.stage_receipts + ) return { "artifact_kind": US_MULTISPINE_POOL_MANIFEST_ARTIFACT_KIND, "schema_version": POOL_MANIFEST_SCHEMA_VERSION, @@ -4237,6 +4284,7 @@ def _stacked_manifest_payload( "provenance_counts": result.provenance_counts, "stage_receipts": result.stage_receipts, "stage_checkpoints": checkpoint_provenance, + "worker_execution_authentication": worker_execution_authentication, "terminal_gates": gates, # Compatibility alias for existing simulation-ready manifest readers. # Its contents are the stacked terminal battery, never us_spine_agreement. @@ -4468,6 +4516,9 @@ def _write_stacked_outputs( publication_run_id=publication_run_id, ) gates = _stacked_gate_payload(result) + worker_execution_authentication = _stacked_worker_execution_authentication( + result.stage_receipts + ) diagnostics = { "artifact_kind": US_MULTISPINE_AGREEMENT_DIAGNOSTICS_ARTIFACT_KIND, "schema_version": POOL_MANIFEST_SCHEMA_VERSION, @@ -4478,6 +4529,7 @@ def _write_stacked_outputs( "publication_run_id": publication_run_id, "terminal_gates": gates, "agreement_gate": gates, + "worker_execution_authentication": worker_execution_authentication, } try: write_nullable_us_h5( @@ -4489,9 +4541,7 @@ def _write_stacked_outputs( materializer_version=US_MULTISPINE_POOL_H5_MATERIALIZER_VERSION, root_attributes={ CONGRESSIONAL_DISTRICT_VINTAGE_CROSSWALK_SHA256_ATTR: ( - verified_inputs[ - _STACKED_CD_CROSSWALK_INPUT_ROLE - ].actual_sha256 + verified_inputs[_STACKED_CD_CROSSWALK_INPUT_ROLE].actual_sha256 ), CONGRESSIONAL_DISTRICT_VINTAGE_TARGET_ATTR: ( CURRENT_CONGRESSIONAL_DISTRICT_VINTAGE diff --git a/tools/score_us_release_head_to_head.py b/tools/score_us_release_head_to_head.py index 54e369aca..9c2b56ded 100644 --- a/tools/score_us_release_head_to_head.py +++ b/tools/score_us_release_head_to_head.py @@ -302,6 +302,14 @@ def _parse_args(argv: Sequence[str] | None = None) -> argparse.Namespace: "--candidate-manifest-sha256", help="Optional external SHA-256 pin for a candidate pool manifest.", ) + parser.add_argument( + "--candidate-worker-identity-attestation", + type=Path, + help=( + "Explicit plan-gated compatibility attestation for a legacy " + "gate-failed candidate pool; scoring use only." + ), + ) parser.add_argument( "--age-targets", action=argparse.BooleanOptionalAction, @@ -476,9 +484,7 @@ def _drop_historical_formula_owned_columns( for entity in frame.entities: columns = columns_by_entity.get(entity) cleaned_tables[entity] = ( - tables[entity].drop(columns=columns) - if columns - else tables[entity].copy() + tables[entity].drop(columns=columns) if columns else tables[entity].copy() ) cleaned_weights = { entity: frame.weights_for(entity) for entity in frame.weighted_entities @@ -501,10 +507,12 @@ def _load_pool_manifest( manifest_path: Path, *, expected_manifest_sha256: str | None, + worker_identity_attestation: Path | None, ) -> LoadedArtifact: frame, manifest, authenticated = load_authenticated_us_multispine_pool_for_scoring( manifest_path, expected_manifest_sha256=expected_manifest_sha256, + worker_identity_attestation=worker_identity_attestation, ) frame, formula_owned_receipt = _drop_historical_formula_owned_columns(frame) terminal_gates = manifest.get("terminal_gates") @@ -522,6 +530,9 @@ def _load_pool_manifest( "manifest_sha256": authenticated.manifest_sha256, "publication_run_id": authenticated.publication_run_id, "release_id": manifest.get("release_id"), + "worker_execution_authentication": dict( + authenticated.worker_execution_authentication or {} + ), } return LoadedArtifact( frame=frame, @@ -531,6 +542,9 @@ def _load_pool_manifest( "weight_kind": frame.weights_for("household").kind.value, "publication_status": manifest.get("status"), "simulation_ready": manifest.get("simulation_ready"), + "worker_execution_authentication": dict( + authenticated.worker_execution_authentication or {} + ), }, h5_path=authenticated.path, terminal_gates=terminal_gates, @@ -590,6 +604,7 @@ def load_artifact( path: Path, *, expected_manifest_sha256: str | None = None, + worker_identity_attestation: Path | None = None, ) -> LoadedArtifact: """Load a role-neutral H5 or authenticated pool into the common frame API.""" @@ -598,11 +613,16 @@ def load_artifact( artifact = _load_pool_manifest( resolved, expected_manifest_sha256=expected_manifest_sha256, + worker_identity_attestation=worker_identity_attestation, ) else: - if expected_manifest_sha256 is not None: + if ( + expected_manifest_sha256 is not None + or worker_identity_attestation is not None + ): raise ValueError( - "--candidate-manifest-sha256 applies only to a pool manifest." + "Candidate manifest authentication options apply only to a " + "pool manifest." ) artifact = _load_h5(resolved) _assert_rss_below_limit(f"after loading {artifact.identity['filename']}") @@ -1776,6 +1796,7 @@ def score_head_to_head( release.DEFAULT_MAXIMUM_MICROSIM_BATCH_SIZE ), candidate_manifest_sha256: str | None = None, + candidate_worker_identity_attestation: Path | None = None, ) -> dict[str, object]: """Compile once, then score incumbent and optional candidate sequentially.""" @@ -1788,15 +1809,32 @@ def score_head_to_head( allow_unaged_dollar_targets=allow_unaged_dollar_targets, congressional_district_vintage_crosswalk=crosswalk, ) - artifact_paths = [("incumbent", incumbent, None)] + artifact_paths = [("incumbent", incumbent, None, None)] if candidate is not None: - artifact_paths.append(("candidate", candidate, candidate_manifest_sha256)) + artifact_paths.append( + ( + "candidate", + candidate, + candidate_manifest_sha256, + candidate_worker_identity_attestation, + ) + ) + elif candidate_worker_identity_attestation is not None: + raise ValueError( + "--candidate-worker-identity-attestation requires --candidate." + ) artifacts: dict[str, dict[str, object]] = {} contracts: dict[str, tuple[tuple[str, str, str], ...]] = {} - for name, path, expected_manifest_sha256 in artifact_paths: + for ( + name, + path, + expected_manifest_sha256, + worker_identity_attestation, + ) in artifact_paths: loaded = load_artifact( path, expected_manifest_sha256=expected_manifest_sha256, + worker_identity_attestation=worker_identity_attestation, ) artifact_payload, contract = score_loaded_artifact( artifact=loaded, @@ -2276,6 +2314,9 @@ def main(argv: Sequence[str] | None = None) -> int: ), maximum_microsim_batch_size=args.maximum_microsim_batch_size, candidate_manifest_sha256=args.candidate_manifest_sha256, + candidate_worker_identity_attestation=( + args.candidate_worker_identity_attestation + ), ) json_path, markdown_path = write_scorecard(payload, args.out_prefix) print( diff --git a/tools/us_bundle_generation/imputation.py b/tools/us_bundle_generation/imputation.py index 42a11953a..ade31c352 100644 --- a/tools/us_bundle_generation/imputation.py +++ b/tools/us_bundle_generation/imputation.py @@ -913,59 +913,14 @@ def _worker_execution_template() -> dict[str, object]: "surface": "execution_profile", "resolve_as": "worker_execution", "template": { - "module": "microcosm.build.us_runtime.puf_qrf_worker", - "argv_template": [ - {"resolver_op": "sys_executable"}, - "-m", - "microcosm.build.us_runtime.puf_qrf_worker", - "--checkpoint-dir", - "{checkpoint_dir}", - "--target-index", - "{target_index}", - ], - "interpreter": { - "executable": {"resolver_op": "sys_executable"}, - "resolved_executable": {"resolver_op": "resolved_sys_executable"}, - "implementation": {"resolver_op": "python_implementation"}, - "cache_tag": {"resolver_op": "python_cache_tag"}, - "version": {"resolver_op": "python_version_triplet"}, + "schema_version": 1, + "semantic_identity": { + "resolver_op": "primary_qrf_worker_semantic_identity" }, - "environment": { - "policy": "inherit_parent_environment_with_bound_fit_controls", - "overrides": {}, - "semantic_controls": { - "POPULACE_FIT_N_JOBS": { - "configured": { - "resolver_op": "environment_value", - "name": "POPULACE_FIT_N_JOBS", - }, - "resolved": { - "resolver_op": "env_canonical_positive_int_or_default", - "name": "POPULACE_FIT_N_JOBS", - "default": -1, - }, - }, - "POPULACE_FIT_PREDICT_WORKERS": { - "configured": { - "resolver_op": "environment_value", - "name": "POPULACE_FIT_PREDICT_WORKERS", - }, - "resolved": { - "resolver_op": "env_positive_int_or_cpu_count", - "name": "POPULACE_FIT_PREDICT_WORKERS", - "fallback_minimum": 1, - }, - "resolution": { - "resolver_op": "env_or_cpu_count_resolution_label", - "name": "POPULACE_FIT_PREDICT_WORKERS", - }, - }, - }, - "bound_names": [ - "POPULACE_FIT_N_JOBS", - "POPULACE_FIT_PREDICT_WORKERS", - ], + "semantic_identity_sha256": { + "resolver_op": "primary_qrf_worker_semantic_identity_sha256" }, + "audit_aliases": {"resolver_op": "primary_qrf_worker_audit_aliases"}, }, }