recordThreadEvent used to drop the event whenever `envelope.taskId` was
null, so communication wakes produced nothing in the thread view even
while the agent actively replied to peers. Taskless runs now write into
a per-agent general thread (`ensureAgentCommunicationThread`), so the UI
surfaces peer conversations alongside task activity.
Peer-authored user turns inside the transcript used to be labelled with
the recipient's id — pi erases the sender once the message is projected.
A new `inboundCorrelations` map on `RuntimeBridge` pins each pi-message
timestamp to its source `agent_messages` row at injection time, so the
thread-event writer can recover the real author id and `senderKind` on
`message_end`. prepareRun projections (no `message_end` fires for
priorMessages) write their thread event directly as the projection lands
so they are not silently lost.