fix(pr-review): retry the merge-queue state read and surface a failed read

Merged
DO
6d ago
+83-1

Closes #2186

Problem

mq_dequeue_if_unapproved runs right after an approval is dismissed. It read the PR's live queue and review state once; if that read failed (a transient GraphQL error, a rate limit) it logged one warning and returned, and a PR sitting in the merge queue could then merge with no approval standing. Raised by CodeRabbit on the pull request for #2174 and accepted there as a follow-up.

What changes

  • The state read is retried a bounded number of times (MQ_READ_ATTEMPTS, default 3; MQ_READ_RETRY_DELAY_SEC between attempts, default 2).
  • If every attempt fails, the unknown state is also written to the job step summary, naming the PR. Still no dequeue call and no PR comment on that path (most PRs that reach it are not queued), and the run never fails.
  • AGENTS.md documents the retry and the two settings.

Risk

Low. One library function gains a retry loop; a malformed setting falls back to the default. Worst case is up to two extra reads and four seconds on a path that only runs after a dismissal.

Test plan

  • bats tests/test_merge_queue_dequeue.bats: 27 of 27 pass locally (three new cases: one failed read then success still dequeues; every read failing makes exactly MQ_READ_ATTEMPTS reads, no dequeue, no comment, a summary entry, exit 0; a malformed setting uses the default). The 24 existing tests are unchanged.
  • Mutation check: with the loop cut to a single attempt, all three new tests fail.
  • scripts/check-duplicate-decls.sh passes. shellcheck -x reports only the two existing SC2016 info notes on the GraphQL query strings.

Rollback

Revert this commit. The dequeue behaviour returns to a single read.

Monitoring

A failed read shows as a ::warning:: in the pr-review run and as a "Merge queue: state unknown" entry in its step summary.

This PR is authored directly in the session and labelled dev-lead:hands-off.

๐Ÿค– Generated with Claude Code