e2f3dc60bd
A channel interaction (e.g. a Slack approval click) is resolved at the top of the turn by matching its toolCallId against the in-memory accumulator. For agents that register hydrateMessages, the accumulator is empty on a fresh continuation / OOM-retry boot (those agents own persistence, so the boot seeding block is skipped and the hydrate hook only runs later in the turn). The click therefore matched nothing, was classified as a stale interaction, and was dropped, losing the human's decision and leaving the paused turn unresolved. When an interaction arrives and hydrateMessages is registered but the accumulator is empty, load the persisted chain via the hydrate hook first so the interaction can find its pending tool call. The per-turn hydrate later in the turn still runs to persist the synthesized resolution message. Guarded on an empty accumulator so warm turns don't re-hydrate.