With busy_input_mode: interrupt, a message B arriving while A's turn runs
redirects the turn: the answer now answers B, but the final send was still
bracketed against the event that OPENED the turn, so platforms with reply /
quote semantics (Feishu, Moti, Telegram DMs) quoted A under an answer to B
(#115001, Repro A). The reply anchor, the ledger identity and the
TurnContext anchor (read by the queued-first-response lane) were all bound
at turn start and nothing moved them on a successful redirect.
Both redirect entry points (interrupt-mode busy path and the PRIORITY path
in run_inbound) now go through _redirect_active_turn, which on success
rebinds the running turn's opening event (reply_anchor_override +
ledger_message_id) and its TurnContext to the redirecting message. The
running turn's event/ctx live on TurnState (set at claim / promotion,
cleared with the slot), and the rebind is skipped when the slot is already
owned by a newer agent, so a displaced turn's redirect can never re-anchor
a later turn.
Live repro (real GatewayRunner._handle_message with a fake platform adapter
and an agent that honours redirect): before, final reply_to='A' for
ANSWER-TO<What day is tomorrow?>; after, reply_to='B'. The busy ack was
already anchored to B on both sides.
The queue half of #115001 (both Moti quote blocks on B) is not touched: the
gateway already hands each lane a different anchor and needs the adapter
boundary datapoint the thread asks for.
Supersedes #115065 (@Finn763): same reply_anchor_override seam, without the
generation-tuple state and the queued-chain re-anchoring.
Co-authored-by: finn763 <165816600+finn763@users.noreply.github.com>