catch-up-uses-event-id-filtering

Status: IN

`catch_up()` calls `read_all(from_position=self._position + 1)` to skip already-processed events, but `_on_event` has no equivalent position guard — an asymmetry that enables duplicate processing

Source: entries/2026/05/29/topic-catch-up-subscription-gap.md

JSON