How should backward cursor pagination trim overflow while returning chronological pages?

A message API reads newest-first by sequence, fetches one extra record to detect older data, then exposes each page oldest-first. The key question is whether overflow removal happens before or after reversing, and which retained boundary supplies the next older-page cursor. Known constraints are an exclusive older-than cursor, unique increasing sequence values, and a page size of three. The desired result should avoid both duplicates and gaps across eight sequential records. The reasoning should also identify how the rule changes if trimming is delayed until after chronological reordering.

Sequence tracing confirms the invariant. In the descending fetch buffer, the extra lookahead is the final and oldest row, so remove that row before reversing the retained page. If chronological reversal happens first, the equivalent removal is from the beginning, never the end. With an exclusive older-than query, the next cursor is built from the oldest retained row, because using the discarded lookahead would skip it. For sequences one through eight and size three, descending buffers are eight seven six five, then five four three two, then two one. Returned pages are six seven eight with cursor six, three four five with cursor three, and one two with no next cursor.

The pagination cursor should be a server-sealed opaque envelope containing the boundary sort tuple, a binding to the resolved conversation, a binding to canonically normalized filters, the backward direction, and the snapshot identity or watermark. Authenticated encryption is preferable to a clear signed token because signatures prevent tampering but do not conceal internal identifiers or sensitive filter state. On reuse, the server authenticates the envelope, reauthorizes the requested conversation, recomputes all context bindings, and rejects any mismatch with one generic client-safe cursor error. A first page at snapshot eight can return six seven eight with boundary six; a later insert at nine stays outside that walk, while attempting that cursor with another conversation, filter set, or direction is rejected before querying. A high-water mark is a sufficient snapshot only for append-only data with immutable filter-relevant fields; mutable membership requires versioned rows or a durable server-side snapshot handle.