Under multiplex a served secondary profile's remote MCP server whose config has a
`${VAR}` Authorization header was brought up at gateway boot with the placeholder
unresolved (HTTP 401) and retried that same rendering forever.
Mechanism: `_owner_scope_home()` trusted any caller-bound secret scope, and the
gateway's boot-time `_profile_runtime_scope` binding is a SNAPSHOT taken before the
profile's external secret source (`secrets.command`) may have answered. The run
task copies that context, and `_refresh_remote_config` re-read config.yaml on every
probe but rendered it under the same frozen mapping, so a parked server sent the
literal `Bearer ${VAR}` every ~5 min for the life of the process.
- `_owner_scope_home()` now returns the owner home (the scope's stamped home, else
the registry scope) even when a scope is bound: MCP rebuilds the owner's scope
fresh, which retries hydration (cached once it succeeds). Single-profile
processes (scope key None) are unchanged.
- `MCPServerTask.run()` binds that fresh owner scope around the rebuild-time config
refresh, so a reconnect heals once the source hydrates.
- `_require_rendered_remote` fails closed: a remote `url`/`headers` still carrying
a `${VAR}` after rendering raises naming the variable instead of sending it.
- Salvaged from #119097 (@JoaoMarcos44): the connect-time re-render, which also
covers a lazy server whose config was rendered at boot; its mechanism alone was a
no-op for the reported topology because the owner-scope install was skipped
whenever a (frozen) scope was already bound.
Row L1/L3, topology T2. Tests: A→B→A under set_multiplex_active(True) with two
temp homes, red on origin/main (literal placeholder sent), green on head.
Co-authored-by: JoaoMarcos44 <JoaoMarcos44@users.noreply.github.com>