···7788## open items
991010-### OutdatedCursor info frame
1111-1212-`replayTo` (broadcaster.zig) needs to detect when the requested cursor
1313-is older than the replay buffer and send an OutdatedCursor error frame
1414-before closing. currently silently starts from oldest available.
1515-1610### broadcast after flush (architectural)
17111812indigo's `flushLog` writes to disk first, then calls `broadcast()` for
···28222923router.zig:68 has no getRepo. should redirect to the PDS hosting the
3024repo (like indigo service.go:153). needs DID → host lookup + new handler.
2525+2626+---
2727+2828+## 2026-03-18
2929+3030+### OutdatedCursor + FutureCursor (indigo#1328)
3131+3232+implemented spec-compliant cursor validation for downstream consumers of
3333+`subscribeRepos` (broadcaster.zig). addresses bluesky-social/indigo#1328 — relays
3434+weren't sending these messages, PDSes were.
3535+3636+- **OutdatedCursor**: `#info` message frame (`op: 1, t: "#info"`, body
3737+ `{name, message}`). sent when cursor < oldest available seq. connection
3838+ stays open, stream continues from oldest available. every major consumer
3939+ (jetstream, indigo, @atproto/sync, python SDK, skyfall) either handles
4040+ `#info` frames or silently ignores them — no breakage risk.
4141+- **FutureCursor**: error frame (`op: -1`, body `{error, message}`). sent
4242+ when cursor > current relay seq. connection closes.
4343+- added `firstSeq()` to DiskPersist (event_log.zig) — queries oldest
4444+ `seq_start` from `log_file_refs`.
4545+- renamed `encodeInfoFrame` → `encodeErrorFrame` (was always an error frame
4646+ encoder, just misnamed).
4747+- added `encodeInfoMessage` for proper `#info` message frames.
4848+4949+files: broadcaster.zig, event_log.zig
5050+5151+### note: lightrail adjacent key proof approach
5252+5353+fig explained (discord) how lightrail detects collection creation/deletion from
5454+the firehose using MST adjacent key proofs — the adjacent keys included in
5555+sync 1.1 commit ops happen to contain enough MST nodes to verify the proof chain
5656+up to the root. this lets lightrail detect first-write and last-delete for a
5757+collection without calling `describeRepo`.
5858+5959+zlay's approach (planned resync.zig) is simpler: re-fetch `describeRepo` on
6060+`#sync` events. fig's approach is more robust but requires MST proof verification.
6161+worth revisiting if we ever need tighter collection tracking.
31623263---
3364