OverviewFilesCommitsIssuesDocsReleasesPeers

atproto-room commits / 116892b

serve-membrane: project the frame time the signer RECORDED, not one derived from the rev
projectFirehose recomputed each #commit frame's `time` from the rev (revTime) so that every device projected a byte-identical frame. That was sound while revs were wall-clock TIDs. Revs are now a deterministic prev+1us chain, so a derived time is PINNED at the chain's origin and recedes from reality forever — measured: a chain whose head was minted 30 days ago still derives a time 30 days stale after five further commits. Relays read `time` as liveness metadata, and this fleet already fights non-archival relays dropping accounts that look stale, so a permanently-receding timestamp is a federation risk rather than a cosmetic one. Read the time the SIGNER recorded into the shared __commit__ log instead: real AND identical on every device, because they all replicate and read one stored fact rather than each deriving it — so the cross-device frame identity that motivated revTime is preserved. Frames predating the field fall back to revTime, which is correct for them since their revs WERE wall-clock TIDs. `time` is frame metadata only, never part of the signed commit (atproto-store firehose.js:37). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
116892bd1fcadfb79cb005439fa36637ec842e67
by plankatron <fleeky@gmail.com> · 2026-07-25T00:46:32.000Z

Changed files (1) +7 -3

lib/serve-membrane.js +7 -3
……@@ -51,9 +51,13 @@ async function projectFirehose (device, seq, log = null) {
5151 if (!log) log = await device.firehoseLog() // seq-ordered
5252 for (let i = seq.length; i < log.length; i++) {
5353 const write = deserializeEntry(log[i])
54 // time is derived deterministically from the rev so every device emits an identical frame
55 // (the membrane's repo assembly ignores it; relays use it as metadata).
56 await seq.sequenceCommit(write, { time: revTime(log[i].rev) })
54 // `time` comes from the frame the SIGNER recorded in the shared __commit__ log, so it is a real
55 // wall-clock instant AND identical on every device (all reading one replicated fact). Frames
56 // written before that field existed fall back to deriving it from the rev — correct for those,
57 // because their revs WERE wall-clock TIDs. Deriving it from a deterministic prev+1µs rev chain
58 // would freeze `time` near the first commit and drift ever further into the past, which relays
59 // read as staleness. Frame metadata only — never part of the signed commit.
60 await seq.sequenceCommit(write, { time: log[i].time || revTime(log[i].rev) })
5761 }
5862}
5963