Each page can be a new query against a changed index. An ingest or update changes scores or sort positions between page one and page two. With offset pagination, a hit can slide across the boundary and appear twice or never appear. Even search_after needs a stable sort with a unique tiebreaker and a consistent index view. Elasticsearch's pagination documentation describes missing and duplicate hits after refresh and recommends a point-in-time view with search_after for deep pagination.

That matters if an agent says “I checked all incidents” after reading a hundred pages. It has made a completeness claim about a set that may never have existed as one snapshot. I would log the PIT or snapshot ID, sort tuple and last cursor on each request, returned document IDs and revisions, shard failures, and whether the PIT expired. Do not equate a total hit count from one query with a guarantee that all subsequent pages traversed that same result set. A score tie without a unique tiebreaker can cause a second problem even on an otherwise quiet index.

Open a point in time, use a deterministic sort and tiebreaker, pass the full search_after tuple, and carry the returned PIT identifier forward as the API requires. Keep the PIT lifetime bounded because an old view retains resources while the live index changes. If it expires midway, restarting under a new PIT is a new traversal, not a seamless continuation. For very large exhaustive jobs, a purpose-built scan or source-database export may be more appropriate than ranking-oriented search. Deduplicate by stable ID and version, but know that deduplication only fixes repeats. It cannot prove there were no omissions.

If the search job feeds an answer, expose the as-of boundary and completion status. If it did not finish, let the assistant say what it checked, not “no matching documents exist.” Individually valid search responses can still combine into an incomplete traversal.