Skip to content

fix: gate merge-ready on the real merge predicate, not the watcher exit (BRO-1489)#4

Merged
broomva merged 1 commit into
mainfrom
feature/bro-1489-merge-ready-verdict
Jun 12, 2026
Merged

fix: gate merge-ready on the real merge predicate, not the watcher exit (BRO-1489)#4
broomva merged 1 commit into
mainfrom
feature/bro-1489-merge-ready-verdict

Conversation

@broomva

@broomva broomva commented Jun 12, 2026

Copy link
Copy Markdown
Owner

BRO-1489 — the watcher exit code is necessary-not-sufficient

Rule-of-three this session on bstack PR #78: gh pr checks --watch returned exit 0 three times while the PR was NOT safe to merge — UNSTABLE / pending required checks / mid-flight CodeRabbit review. cmd_merge_ready trusted GREEN (= watcher exit 0) and promoted straight to MERGE_READY, so auto-merge could fire on a not-actually-mergeable PR. Each time it was caught only by agent reasoning, never by the mechanism.

Fix

  • merge_ready_verdict(pr, repo) — the real predicate: gh pr view --json mergeable,mergeStateStatus,reviewDecision + a best-effort gh api graphql unresolved-review-thread count. Ready iff mergeStateStatus ∈ {CLEAN, UNSTABLE}, not CONFLICTING, reviewDecision != CHANGES_REQUESTED, 0 unresolved threads. BLOCKED/DIRTY/BEHIND/DRAFT/UNKNOWN or any gh error → not ready (fail-safe). Trusts GitHub's server-computed required-vs-non-required (mergeStateStatus) over fragile isRequired parsing.
  • cmd_merge_ready verifies the verdict before GREEN→MERGE_READY (--no-verify escape for test/offline). Closes the loop: refuse → stays GREENauto-merge blocks.
  • p9 merge-status <pr> [--json] — query the predicate directly; exit 0 iff merge-ready.

Test plan / validation

  • 22 new tests (tests/test_p9_merge_verdict.py): every predicate state, all fail-safe error paths, the gate refusing on not-ready. Full suite 130/130 green.
  • Dogfooded live: p9 merge-status 78 on the merged bstack PR → NOT-READY; the graphql thread count returned 0 against real gh. Dogfooding also caught the original reviewThreads-is-not-a-gh pr view-field bug → fixed (moved to graphql).

P20 cross-review

Independent reviewer: PASS 9/10, no blockers. Verified no false-positive READY (hard-blocking states checked first; REVIEW_REQUIREDBLOCKED gap closed via mergeStateStatus), every error path fails safe, the gate closes the loop, tests non-tautological. Informational: graphql first:100 thread cap only relaxes the stricter layer.

Provenance: bstack PR #78 (BRO-1482) this session.

🤖 Generated with Claude Code

…it (BRO-1489)

Rule-of-three this session on bstack PR #78: `gh pr checks --watch` returned
exit 0 three times while the PR was NOT safe to merge (UNSTABLE / pending
required checks / mid-flight bot review). The watcher exit code is
necessary-not-sufficient, but `cmd_merge_ready` trusted GREEN (= watcher exit 0)
and promoted straight to MERGE_READY → auto-merge could fire on a not-actually-
mergeable PR. Caught each time only by agent reasoning, not the mechanism.

Fix (scripts/p9.py):
- merge_ready_verdict(pr, repo): query `gh pr view --json mergeable,
  mergeStateStatus,reviewDecision` + best-effort `gh api graphql` unresolved-
  review-thread count. Ready iff mergeStateStatus ∈ {CLEAN, UNSTABLE}, not
  CONFLICTING, reviewDecision != CHANGES_REQUESTED, 0 unresolved threads.
  BLOCKED/DIRTY/BEHIND/DRAFT/UNKNOWN or ANY gh error → not ready (fail-safe).
  Trusts GitHub's server-computed required-vs-non-required (mergeStateStatus)
  instead of fragile isRequired parsing.
- _unresolved_review_threads(): graphql count; -1 if undeterminable (does not
  block — mergeStateStatus governs; the thread check is a stricter reflex-18 layer).
- cmd_merge_ready VERIFIES the verdict before GREEN→MERGE_READY (--no-verify escape).
- New `p9 merge-status <pr> [--json]` subcommand — query the predicate directly,
  exit 0 iff merge-ready.

Validation: 22 new tests (predicate states + fail-safes + the gate) + full suite
130/130 green. Dogfooded live: `p9 merge-status 78` on the merged bstack PR →
NOT-READY; graphql thread count returned 0 against real gh. Dogfooding ALSO
caught the original `reviewThreads`-is-not-a-pr-view-field bug → fixed (moved to
graphql). P20: independent review PASS 9/10, no blockers.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@linear

linear Bot commented Jun 12, 2026

Copy link
Copy Markdown

BRO-1489

@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@broomva, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 36 minutes and 33 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more credits in the billing tab to continue.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: bd94e82b-9fcb-48e2-b46b-05cf7e5b1233

📥 Commits

Reviewing files that changed from the base of the PR and between 7ea6e60 and 0fce2a7.

📒 Files selected for processing (4)
  • SKILL.md
  • scripts/p9.py
  • tests/test_p9_integration.py
  • tests/test_p9_merge_verdict.py
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/bro-1489-merge-ready-verdict

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@broomva broomva merged commit 287d77c into main Jun 12, 2026
4 checks passed
@broomva broomva deleted the feature/bro-1489-merge-ready-verdict branch June 12, 2026 01:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant