watch-pr: review threads are fetched without pagination (first 100 only) #471
Description
Observed at commit 2eb7ed4.
pstack/skills/poteto-mode/scripts/watch-pr/github.ts line 5 defines the review-thread query as:
reviewThreads(first: 100) {
nodes { id isResolved comments(first: 10) { nodes { ... } } }
}It has no pageInfo and no cursor. reviewThreads() at line 571 issues this single query and parseReviewThreads (line 360) reads only reviewThreads.nodes. By contrast, the check-rollup query in the same file (line 9) paginates with pageInfo { hasNextPage endCursor } and a loop (around line 616).
Impact
On a PR with more than 100 review threads, threads after the first 100 are never seen. policy.ts line 66 builds the PR snapshot from this list (line 66), so an unresolved thread beyond the first page is invisible to the readiness decision. Comments beyond the first 10 in a thread are likewise dropped, though that matters less because only thread-level resolution seems to be used.
Minimal reproduction
Run the watcher against a PR with 101+ review threads where only a thread past the first 100 is unresolved; the PR is reported as having no unresolved threads.
Suggested fix
Add pageInfo { hasNextPage endCursor } and an $after cursor to the reviewThreads query and loop until hasNextPage is false, as is already done for contexts. If a hard cap is wanted, report an explicit "truncated" state rather than silently using the first page.
Activity
deanrie commentedon Oct 3, 2026
Hey, thanks — this one's clear from the code alone.
REVIEW_THREADS_QUERYasks forreviewThreads(first: 100)with nopageInfo,reviewThreads()fires it once, andparseReviewThreadsonly readsnodes, so anything past the first page never reachesreadSnapshot. Ironically thecontextsquery right below it already paginates properly, so the pattern was there to copy.There are two PRs on this and I went through both. #460 is the smaller one: it loops the cursor inside
github.ts, keeps thereviewThreads()signature, and fails closed if the cursor goes missing or repeats. #484 mirrors howresolveChecksalready does it — the reader returns a page,policy.tsloops — and updates types, fakes and tests to match. Both fix the bug; I've recommended #484 internally since it keeps thread and check pagination on the same shape, with a note to borrow #460's stuck-cursor guard. Neither touchescomments(first: 10), which as you say matters less since only thread-level resolution feeds the decision.fix(watch-pr): paginate review threads instead of reading only the fi…
fix(watch-pr): paginate review threads instead of reading only the fi…
fix(watch-pr): paginate review threads instead of reading only the fi…
feat(pstack): port 13 upstream fixes and two new skills (#5)