c5c9aa8d44
Session-hygiene compaction ran _compress_context on a bare loop.run_in_executor(None, ...) worker. Under gateway.multiplex_profiles the profile secret scope and HERMES_HOME override are ContextVars installed by the per-turn _profile_runtime_scope, and a bare worker starts with an empty Context — so the summary model's get_secret(<PROVIDER>_API_KEY) failed closed with UnscopedSecretError on EVERY hygiene pass and compaction silently degraded to a lossy truncation (#100849 debug bundle: 'Failed to generate context summary: get_secret(SURPLUS_API_KEY) called with no profile secret scope active'). - gateway/run.py: run both hygiene executor hops (detached-agent path and codex app-server path) inside copy_context().run, keeping the default executor so a fence-cancelled hung summary never occupies a gateway agent-work slot. - agent/context_compressor.py: UnscopedSecretError is a missing-credential class failure — abort and preserve the session instead of dropping the middle window for a placeholder summary (same carve-out as 401/402/403). - tools/daemon_pool.py: correct the salvaged docstrings — stdlib ThreadPoolExecutor only propagates contextvars from 3.14; nothing is stripped from the bundled runtime. - tests: hygiene worker inherits caller ContextVars (fails on bare run_in_executor); UnscopedSecretError classified as access failure. Live A/B (real get_secret in a run_in_executor worker, multiplex on, profile .env scope installed): main -> UnscopedSecretError; fixed -> scoped value.