A sequence-based message feed reads newest records first for efficient backward pagination, requests one extra record to detect whether older data exists, and reverses each retained page before returning it. The key correctness questions are when to discard the probe record and which retained boundary should seed an exclusive continuation cursor, so that no message is skipped or duplicated.
Correct boundary handling for backward keyset pagination with chronological responses
For a page size of three over sequences one through eight, the descending fetches are eight, seven, six, five; then five, four, three, two; then two, one. In each overflowing fetch, discard the final descending row before presentation reversal. The chronological responses are six, seven, eight; three, four, five; and one, two. With an exclusive older-than predicate, continuation positions are six and then three, taken from the oldest retained row. The discarded rows five and two are lookahead evidence only; using either as an exclusive cursor would skip it. Removing after reversal is equivalent only if the chronological head is removed, whereas removing the chronological tail is incorrect.
The cursor boundary must extend from ordering state into authorization and query scope. On the first page, derive the authorized thread and canonical effective filters from the request, establish a high-water snapshot, and store the oldest returned key as the exclusive position. Bind purpose, authorization scope, a keyed thread digest, a keyed digest of canonical filters, backward direction, the unchanged snapshot, the position, version, and expiry. A signature alone does not conceal readable claims, so either sign a random server-side handle that maps to this state or authenticate encrypted cursor state. On continuation, verify authenticity and expiry, independently reauthorize and recompute current scope bindings, compare them safely, and use a single generic invalid-cursor response for signature, thread, filter, direction, snapshot, position, or expiry failures. Keep the original snapshot while only advancing position. A monotonic high-water mark prevents later appends from entering the traversal but does not freeze edits, deletions, or backdated inserts.