3f497e2b4f
Live staging (2026-08-01, on a fresh instance where title generation finally succeeded): the rename lane fired end to end, but the connector declined the op with "discord egress declined: target not routed to an onboarded tenant". The trace logs added earlier pinpointed it: discord auto-thread rename: thread=... lane=relay new_title='...' relay thread_rename declined ...: target not routed to an onboarded tenant discord auto-thread rename result: thread=... applied=False Root cause: the connector's routedEgressGuard resolves the owning tenant from the outbound metadata's scope_id (guild) or user_id (author). The adapter builds those via _with_scope(chat_id), reading per-chat caches keyed by the PARENT channel chat_id learned at inbound. The relay rename lane called rename_thread WITHOUT parent_chat_id, so chat_id defaulted to the THREAD id — a key the caches never held — and the op shipped with no discriminator. resolveTenant returned undefined and egress was declined before the op ever reached the (now-durable) no-clobber guard. This was the true terminal blocker: every earlier fix (send-result feedback, registration/poll ordering, connector-owned guard, durable Redis store) was correct but sat DOWNSTREAM of this egress-routing decline, so none of them could take effect. Fix: the relay lane passes parent_chat_id=source.chat_id (the relay source's chat_id IS the parent channel; the thread came from send-result feedback). _with_scope then resolves scope_id/user_id from the parent-channel caches and the connector routes the op to the tenant. Scoped to the relay lane only (use_connector_guard); the native lane renames via the direct Discord API and needs no discriminator. Tests: adapter-level — a rename passing parent_chat_id carries the cached scope_id, one keyed on the thread id alone does not (the regression shape); lane-level — the late-feedback test now asserts parent_chat_id flows through as the parent channel. Relay suite 150 passed; ruff + footguns clean. Connector-compatible with the deployed egress guard; no gateway-gateway change needed.