cedf4a3d78
Answers the P1 review on #111187: build_profile_secret_scope() held only <profile>/.env plus that profile's external-source snapshot, never the administrator-managed .env. The launch process applies that file LAST with override (_apply_managed_env), so a managed key beats the user's own value in os.environ. Under multiplex semantics get_secret() stops falling back to os.environ on a scope miss, so inside a routed cron fire (and equally inside a real multiplex gateway turn, which builds its scope through the same function via gateway/run.py::_load_profile_secret_scope) a managed-only credential resolved as absent and a managed-vs-user collision resolved to the USER value: reversed precedence. Fix at the source: build_profile_secret_scope() overlays load_managed_env() last, after the profile .env and external sources, skipping process-global names exactly as it does for the other two layers. Every multiplex-authoritative scope (gateway turn, routed desktop fire, external worker env build) is built here, so managed authority is composed once instead of restored per consumer. No generic ambient-env fallback is reintroduced: only the managed file's own keys enter the scope, and only with the managed file's values. Regression (parametrized, two invariants): inside a routed fire a managed-only key resolves through get_secret(); a managed-vs-user collision yields the managed value.