declarative relay deployment on hetzner relay-eval.waow.tech
atproto relay
14
fork

Configure Feed

Select the types of activity you want to include in your feed.

ops changelog: OutdatedCursor/FutureCursor + lightrail adjacent keys note

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

zzstoatzz acccfdf0 21ff2ef7

+37 -6
+37 -6
docs/ops-changelog.md
··· 7 7 8 8 ## open items 9 9 10 - ### OutdatedCursor info frame 11 - 12 - `replayTo` (broadcaster.zig) needs to detect when the requested cursor 13 - is older than the replay buffer and send an OutdatedCursor error frame 14 - before closing. currently silently starts from oldest available. 15 - 16 10 ### broadcast after flush (architectural) 17 11 18 12 indigo's `flushLog` writes to disk first, then calls `broadcast()` for ··· 28 22 29 23 router.zig:68 has no getRepo. should redirect to the PDS hosting the 30 24 repo (like indigo service.go:153). needs DID → host lookup + new handler. 25 + 26 + --- 27 + 28 + ## 2026-03-18 29 + 30 + ### OutdatedCursor + FutureCursor (indigo#1328) 31 + 32 + implemented spec-compliant cursor validation for downstream consumers of 33 + `subscribeRepos` (broadcaster.zig). addresses bluesky-social/indigo#1328 — relays 34 + weren't sending these messages, PDSes were. 35 + 36 + - **OutdatedCursor**: `#info` message frame (`op: 1, t: "#info"`, body 37 + `{name, message}`). sent when cursor < oldest available seq. connection 38 + stays open, stream continues from oldest available. every major consumer 39 + (jetstream, indigo, @atproto/sync, python SDK, skyfall) either handles 40 + `#info` frames or silently ignores them — no breakage risk. 41 + - **FutureCursor**: error frame (`op: -1`, body `{error, message}`). sent 42 + when cursor > current relay seq. connection closes. 43 + - added `firstSeq()` to DiskPersist (event_log.zig) — queries oldest 44 + `seq_start` from `log_file_refs`. 45 + - renamed `encodeInfoFrame` → `encodeErrorFrame` (was always an error frame 46 + encoder, just misnamed). 47 + - added `encodeInfoMessage` for proper `#info` message frames. 48 + 49 + files: broadcaster.zig, event_log.zig 50 + 51 + ### note: lightrail adjacent key proof approach 52 + 53 + fig explained (discord) how lightrail detects collection creation/deletion from 54 + the firehose using MST adjacent key proofs — the adjacent keys included in 55 + sync 1.1 commit ops happen to contain enough MST nodes to verify the proof chain 56 + up to the root. this lets lightrail detect first-write and last-delete for a 57 + collection without calling `describeRepo`. 58 + 59 + zlay's approach (planned resync.zig) is simpler: re-fetch `describeRepo` on 60 + `#sync` events. fig's approach is more robust but requires MST proof verification. 61 + worth revisiting if we ever need tighter collection tracking. 31 62 32 63 --- 33 64