Codex gate found two real issues in the send-path warm:
1. Blocking lock wait (CORE): get_available_models(prefer_cache=True) still
acquires _available_models_cache_lock and can wait up to ~60s (unbounded in
synchronous rebuild mode) on an in-flight rebuild — unacceptable on the send
hot path. Rewrote warm_models_catalog_provenance_if_cold as a genuinely
non-blocking, disk-only publish: try the cache lock NON-BLOCKING (return
immediately if busy — a concurrent build will publish provenance itself),
read ONLY the on-disk cache via _load_models_cache_from_disk (no network, no
rebuild), publish snapshot+fingerprint + _sync_models_cache_provenance().
Verified: returns in ~3.5ms while the lock is held (was a 60s block).
2. Profile scope (CORE): the streaming worker is a separate thread that does NOT
inherit the HTTP handler's request-profile TLS. Both the warm and the resolve
read profile-keyed config (cache path + source fingerprint via
get_active_profile_name), so a cold send from a NAMED profile could resolve
against the DEFAULT profile's config and route to the wrong provider/base_url
(get_available_models reloads config on path mismatch). Wrapped warm + resolve
in profile_scope_for_detached_worker(_resolved_profile_name) so both see the
owning session's profile (no-op for default/root).
Tests: rewrote never-live-rebuilds (now asserts warm NEVER calls
get_available_models — reads disk directly) and added a non-blocking regression
(warm returns <2s while the cache lock is held). 65 resolver+sprint40 tests pass;
b3nw end-to-end + non-blocking + disk-warm all verified.