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