# Secure Backward Cursor Pagination with Chronological Pages
## Trigger
Use when an API fetches older records newest first with one overflow row, returns each page chronologically, and accepts a cursor that can outlive a UI change of conversation or filters.
## Practical steps
1. Choose a stable, unique ordering tuple. Authenticate the caller, authorize the requested conversation, canonicalize effective filters and defaults, fix backward direction, and establish a durable snapshot or as-of revision.
2. Fetch page size plus one matching rows in descending order within that snapshot. If an extra row exists, remove the final and oldest fetched row, then reverse the retained rows. Issue a cursor only when that extra row proves more data exists. Its exclusive boundary is the oldest returned row, never the removed row.
3. Bind the cursor to the authorized subject or tenant, resolved conversation, canonical filters, direction, ordering version, snapshot, boundary, purpose, and expiry. Authenticate it. Use authenticated encryption or a signed random handle backed by server state when internal identifiers or filter state must remain hidden; a readable signature alone provides no confidentiality.
4. On continuation, authenticate and validate the token before trusting its fields. Independently reauthorize the currently requested conversation and compare current bindings. The token normally defines the continuation snapshot. Compare a separate snapshot value only if the API explicitly accepts one. Verify snapshot availability, then query that same historical view using the exclusive older-than boundary.
5. Reject altered, expired, inaccessible, or context-mismatched cursors with one generic external error that reveals neither internal identifiers nor which binding failed. The client can clear the cursor and begin a new walk.
## Limits
A maximum-sequence cutoff substitutes for a full snapshot only when later inserts always receive strictly greater keys, existing records are append-only, and filter membership cannot change. Backfilled inserts with older keys, edits, deletions, or changing filters require temporal reads or a durable result-set snapshot. Expired snapshot state requires a fresh walk. Cursor authenticity never replaces authorization.
## Failure prevented
These steps prevent skipped boundary rows, false continuation, cross-conversation or cross-filter replay, direction confusion, snapshot drift, and identifier disclosure. This guidance is supported by reasoned sequence and security analysis, including an independent reasoning review; no executable tests were run.