fix(pr-monitor): REST transport — multi-node monitor runs exhaust GraphQL - #2952
Conversation
…phQL
Measured live 2026-09-05: B850 + SPARK + CI bots running the learnings
loop in one hour burned the 5000/h GraphQL budget and the monitor died
mid-run (operator: "we may be graphql limited — we have rest api").
- _pr_numbers: `gh pr list --json` (GraphQL) -> `gh api
repos/{repo}/pulls` (REST); `merged` state maps to closed+filter
- _pr_summary: `gh pr view --json` (GraphQL) -> new `_pr_detail()`
assembling the same shape from REST: pulls/{n}, issues/{n}/comments,
pulls/{n}/reviews, commits/{sha}/check-runs
- reviewDecision derived GitHub-style: latest SUBMITTED review per
author (PENDING drafts skipped); APPROVED > CHANGES_REQUESTED
- _review_thread_flags: review threads are GraphQL-only (no REST
equivalent) — on rate-limit they degrade loudly to stderr instead of
killing the run; comment bodies still flow (REST)
Verified against official GitHub docs (2026-09-05):
- check-run status: queued/in_progress/completed (+Actions-only
waiting/requested/pending) — all non-completed count pending; conclusion
null only while incomplete
- conclusions: action_required/cancelled/failure/neutral/success/skipped/
stale/timed_out — SUCCESS_STATES {SUCCESS,NEUTRAL,SKIPPED} matches exactly
- review states: APPROVED/CHANGES_REQUESTED/PENDING (+COMMENTED which
counts as no decision)
GitHub App stance: no local token hand-roll — GITHUB_APP.md's rule is
mint via _app-token.yml (CI) only; the monitor stays token-agnostic over
gh CLI auth, and REST quota is the separate, plentiful budget.
Full-queue validation: 30+ PRs via REST under an exhausted GraphQL
budget, 0 warnings, learnings + JSON artifacts written.
|
Important Review skippedAuto reviews are limited based on label configuration. 🏷️ Required labels (at least one) (1)
Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Team Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c36667cc3d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…heck change-requests before approvals (Codex #2952) Five review findings on the REST transport, each fixed at the cause: - PR list: `gh api --paginate` emits one JSON document per page, so json.loads stopped at page one. New `_run_json_pages()` uses --paginate --slurp and flattens; the pulls list, issue comments and reviews all go through it. - check-runs: every page (list_key="check_runs"), not the 30-per-page default that under-counted pending/failed runs on busy PRs. - legacy commit statuses: /commits/{sha}/status statuses[] folded into the rollup as StatusContext, which is what the GraphQL rollup used to include. - reviews: paginated before deriving the decision. - reviewDecision: an outstanding CHANGES_REQUESTED blocks regardless of approvals (checked first); COMMENTED never changes an author's standing; DISMISSED clears it; PENDING ignored. Live-run over REST against #2952/#2924 after the change. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017g8jC7dupS2ubafo6zPQY6
What
The learnings loop (
make -C pmoves pr-monitor) died mid-run when B850 + SPARK + CI bots exhausted the 5000/h GraphQL budget in one hour (measured live:GraphQL: API rate limit already exceeded). Operator direction: we have the REST API._pr_numbers:gh pr list --json→ RESTrepos/{repo}/pulls(merged maps to closed+filter)_pr_summary:gh pr view --json→_pr_detail()— same shape assembled from REST:pulls/{n},issues/{n}/comments,pulls/{n}/reviews,commits/{sha}/check-runsreviewDecisionderived GitHub-style: latest submitted review per author (PENDING drafts skipped); APPROVED > CHANGES_REQUESTEDDocs verification
Mappings checked against official GitHub REST docs (2026-09-05): check-run
status/conclusionenumerations (the tool'sSUCCESS_STATES {SUCCESS, NEUTRAL, SKIPPED}matches exactly), reviewstatevalues, conclusion-null-only-while-incomplete.GitHub App stance (no hand-rolls)
Per
GITHUB_APP.md: the App token mints via_app-token.ymlin CI only — never re-implemented inline. The monitor stays token-agnostic overghCLI auth; REST quota is the separate budget that makes multi-node runs viable.Testing
pr_monitor_learnings_latest.md,pr_monitor_latest.json)Warning
Generated with Crush