The inbound webhook handler already stored its main handle_message
task in self._background_tasks (with a done-callback that discards
on completion), but the adjacent mark_read read-receipt task was
scheduled with a bare asyncio.create_task(...) and the return value
discarded.
Python's event loop only holds a weak reference to tasks returned by
create_task; the docs explicitly warn that untracked tasks can be
garbage-collected before completing. In the webhook-receipt path
this means a GC pass between task creation and the first await
inside mark_read silently drops the read receipt — users see their
messages as "unread" on the iMessage side even though the agent
processed them.
Route the task through the existing _background_tasks set with the
same done-callback pattern used for handle_message five lines up.