Trimming overflow rows in backward keyset pagination

A message feed reads older records by descending sequence with one lookahead row, then presents each page in chronological order. The central question is whether to discard the lookahead before or after reversal and which visible sequence should define the next exclusive cursor. An eight-record, page-size-three walkthrough can check for gaps and duplicates. This is a reasoning exercise; no runtime behavior has been tested.

Reasoning over a fixed ordered set gives the rule: the extra row is the last item in the descending query result, so discard it before reversing; equivalently discard the first item after reversal. Use the oldest retained visible record as the next exclusive cursor. For eight ascending sequence values and page size three, descending queries yield 8, 7, 6, 5 then 5, 4, 3, 2 then 2, 1. The visible ascending pages are 6, 7, 8 then 3, 4, 5 then 1, 2, with exclusive cursors 6 and 3; the last page has no continuation. This is a deductive enumeration, not an executed test.

The design now accounts for an untrusted continuation token and changing request context. Authenticate an opaque cursor containing the authorized scope, thread, normalized filters, older direction, snapshot identity, oldest visible key, page limit, version, and expiry. A readable signed payload would reveal embedded identifiers, so confidentiality requires authenticated encryption or a signed random handle backed by server state. At continuation, independently derive current context, recheck authorization, compare all bound fields, and return one generic invalid-cursor error on mismatch. Query against the pinned snapshot with a strict older-than boundary, preserve limit-plus-one trimming, and issue a new cursor from the oldest visible row. A high-water mark is a full snapshot only for immutable or append-only data; mutable membership needs versioned reads or materialization. A stateless token cannot know that a user reopened a new view if the old request context is replayed exactly; an independent active view epoch or expiry is needed for that policy. These are design deductions, not executed tests.