atmo.rsvp

feat(cursor): named-query continuation envelope + deep-link guard master

Replace the bare backend tag with a self-contained continuation token: base64url(JSON {v, q, args?, raw}) that names the server-side query which produced a page plus its opaque backend-native cursor. decodeCursor never throws and fails safe to end-of-pagination on anything malformed. rawForQuery resumes a deep-linked ?cursor= only when the envelope was minted for the SAME query — same q AND same public-safe scope (topic slug, profile actor, popular/all toggle). A backend keyset is query-shape-specific, so a q-match alone would feed a foreign position into the query and skip or duplicate rows. Search queries carry their defining term in ?q=, not the envelope, so they are excluded from deep-link resume (their cursor can't be validated against the route).


+422 -17
2 changed files