LearnNewsExamplesServices
Frontmatter
titlefix(github-workflow): PR + Discussion delta-fetch cutoffs (#12190)
authorneo-opus-ada
stateMerged
createdAtMay 30, 2026, 7:59 AM
updatedAtMay 30, 2026, 8:05 AM
closedAtMay 30, 2026, 8:05 AM
mergedAtMay 30, 2026, 8:05 AM
branchesdevfix/gh-syncer-rate-limit-12190
urlhttps://github.com/neomjs/neo/pull/12193
Merged
neo-opus-ada
neo-opus-ada commented on May 30, 2026, 7:59 AM

Authored by Opus 4.8 (Claude Code). Session de8830c3-8d1b-47f8-90db-bd236c8b9bd2.

Related: #12190 Related: #12186

PR + Discussion sync scanned the entire corpus every run — the dominant driver of the rising GitHub rate-limit hits (issues were already delta-gated; PRs/Discussions were not). The pullRequests and discussions GraphQL connections have no server-side since filter (only issues does), but both already order UPDATED_AT DESC. This adds a client-side cutoff: stop paginating once a batch's oldest item predates the cached high-water mark (max updatedAt across metadata.pulls / metadata.discussions). A clean-slate run (lastSync === null) or an empty cache still traverses the full history — consistent with the issue delta + sealed-chunk model (archived items stay put; only new/changed items re-bucket).

FAIR-band: over-target — sole active implementer (@neo-gpt rate-limited, @neo-gemini benched per current project state) + operator-directed lane (epic #12186 P1).

Evidence: L1 (unit: cutoff stops pagination at the high-water mark — 2 new tests, 208 green) → L1 required (no runtime-only ACs; the win is fewer GraphQL page-fetches, asserted via query-call count). No residuals for the delta.

Deltas from ticket (if any)

This PR delivers the substantive half of #12190 — the PR + Discussion delta cutoffs, which are the dominant rate-limit driver. Two items from #12190's body are intentionally not pursued here, with rationale:

  • Discussion query-cost reduction (the replies(first:$maxReplies) nesting): unnecessary post-delta. Once the discussion sync fetches only changed discussions (a handful of pages, not the full corpus), the per-page nesting cost is marginal. Reducing it would add continuation-query complexity (like the issue timeline) for negligible gain.
  • Shared rate-limit governance (lifting the low-remaining guard out of IssueSyncer): low-urgency post-delta. With both syncers delta-gated, PR/Discussion runs are cheap; the guard gap is a robustness nicety, not a driver. Easy follow-up if the reviewer deems it worth a dedicated lane.

Related: #12190 (not Resolves) so the operator decides whether the delta suffices to close it or to keep it open for the optional governance item.

Test Evidence

  • npm run test-unit -- test/playwright/unit/ai/services/github-workflow/208 passed (2 new, 0 regressions).
  • New tests (PullRequestSyncer.spec + DiscussionSyncer.spec): a 3-page stub where page 2's oldest item predates the cached high-water mark → the sync issues exactly 2 GraphQL calls (page 3 never requested). Pre-fix this would be 3 (full-corpus scan). Existing tests (empty/clean-slate metadata → cutoff 0 → full fetch) are unaffected.
  • node --check on all touched source files; pre-commit whitespace/shorthand hooks green.

Post-Merge Validation

  • On the next live sync, confirm PR + Discussion fetch only changed items (log shows pagination stopping early; far fewer GraphQL page-fetches than a full-corpus scan).
  • Confirm a clean-slate re-sync (lastSync === null) still traverses the full PR/Discussion history — the eventual v8.1.0 re-bucket re-sync must not be truncated by the cutoff.