Changes to a member's `member_info` entry that no event in the room anchors
(erasure, and MSC4430 link verification) were only delivered when the member
next appeared in a response. Give them a stream so that syncing clients are
woken and told.
* `StreamToken.member_info_key`: a trailing `MultiWriterStreamToken`
component (`StreamKeyType.MEMBER_INFO`); tokens without it still parse.
* `msc4428_member_info_changes` (delta 95/01) behind a multi-writer id
generator with no fixed writer list, as for cache invalidations: any
worker may write (erasure runs wherever deactivation is handled).
`MemberInfoChangesStream` replicates rows; workers wake room members.
* Retention: rows older than 30 days are pruned hourly on the background
worker and the prune point recorded; a since token older than that is
sent the full map per room instead of deltas.
* Producer: `MemberInfoHandler.on_user_erased`, from `deactivate_account`,
one row per room the user has any membership in.
* Consumers: sync v2 reads the changes for all joined rooms once per sync
and includes a room with an empty timeline when it has any; sliding sync
includes such rooms when choosing what to send and resends the full map
for rooms it last sent at an older position.
The stream exists always, like every stream, but nothing writes to it unless
`msc4428_enabled` is set.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>