From c992e81a2ccf3c0b8982bb74c7e261537b3c2090 Mon Sep 17 00:00:00 2001 From: Cristian Magherusan-Stanciu Date: Fri, 22 May 2026 22:08:19 +0200 Subject: [PATCH] docs(workflow): re-request CodeRabbit after every push, wait 10 min before triaging MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After every push to an open PR branch, re-request @coderabbitai review and at the same time arm a ~10-minute timer before reading or triaging CR comments, since CodeRabbit needs several minutes to post and triaging earlier just reads a stale or absent review. - cr-watch (§2) now waits ~10 min after the trigger before its first read, then polls 60-120s; arm via ScheduleWakeup or a no-op-until-elapsed cron. - Post-push callout: re-request CR and arm the timer together on every PR-branch push, not only at PR creation. - §3 re-ping: every fix push restarts the same give-CR-time clock. --- CLAUDE.md | 2 +- git-workflow.md | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 52257de..534042f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -216,7 +216,7 @@ Full rules in `~/.claude/git-workflow.md` — **read before every commit, PR, or - **⚠️ Mandatory pre-commit review loop — 3 clean passes**: read `git diff --cached` and check the five review dimensions (§1). Fix in the same changeset, never via follow-up commits. **Run this review on Opus as comprehensively as possible — CodeRabbit's lens is the floor, not the ceiling** (architecture, type design, silent failures, test coverage, security, comment accuracy, performance, convention fit; fan out the `pr-review-toolkit:*` agents for substantial diffs). Goal: land clean for CR AND humans on the first pass. Catching a finding locally costs one pass; catching it after review costs a push + review wait + fix commit + another round. Shipping it well the first time is much faster. - **Post-push CI watcher**: after every `git push`, enumerate all workflow runs for the pushed commit and launch one background `Agent` per run (`run_in_background: true`) named `ci-watch--`. Each fetches failed logs and **fixes failures autonomously**. Coordinate via the `git-push` lock before pushing fixes. Escalate only for decisions. - **PRs**: ≤400 lines, one concern, conventional-commit title, feature branch `type/short-description`. Never `--no-verify`. -- **Post-PR review loop**: after `gh pr create`, trigger CodeRabbit (`@coderabbitai review`) **and spawn `cr-watch-` as ONE atomic action — posting the trigger without arming the watcher is a defect identical in shape to `git push` without a CI watcher; safe ordering is spawn-watcher-then-trigger so a posted trigger always implies a live watcher** (60-120s polling, soft-handle 429s), triage suggestions (actionable / dismiss-with-justification / batch-nitpick), push fixes per the pre-commit loop, then re-ping `@coderabbitai review` and loop until a clean review (**never** `@coderabbitai resolve` or hand-resolving threads to silence the bot), then `merge-watch-` awaits **human merge** (no self-merge by default), then deploy + verify (Chrome MCP for UI, `curl` for API, `terraform plan` for IaC), then post a recommendation-to-close on the originating issue and **file new issues for out-of-scope follow-ups**. **Before declaring PR work done for a session (or any time you spot unaddressed CR comments), run the reconciliation sweep**: every open PR you authored must have a live `cr-watch`, a clean terminal CR state, or be closed — re-arm any that slipped. Full lifecycle in `git-workflow.md`. +- **Post-PR review loop**: after `gh pr create`, trigger CodeRabbit (`@coderabbitai review`) **and spawn `cr-watch-` as ONE atomic action — posting the trigger without arming the watcher is a defect identical in shape to `git push` without a CI watcher; safe ordering is spawn-watcher-then-trigger so a posted trigger always implies a live watcher** (re-request CR after every push to the PR branch and wait ~10 min before triaging so CR has time to post, then 60-120s polling, soft-handle 429s), triage suggestions (actionable / dismiss-with-justification / batch-nitpick), push fixes per the pre-commit loop, then re-ping `@coderabbitai review` and loop until a clean review (**never** `@coderabbitai resolve` or hand-resolving threads to silence the bot), then `merge-watch-` awaits **human merge** (no self-merge by default), then deploy + verify (Chrome MCP for UI, `curl` for API, `terraform plan` for IaC), then post a recommendation-to-close on the originating issue and **file new issues for out-of-scope follow-ups**. **Before declaring PR work done for a session (or any time you spot unaddressed CR comments), run the reconciliation sweep**: every open PR you authored must have a live `cr-watch`, a clean terminal CR state, or be closed — re-arm any that slipped. Full lifecycle in `git-workflow.md`. ## Session Handoff diff --git a/git-workflow.md b/git-workflow.md index 1808b19..1bb9141 100644 --- a/git-workflow.md +++ b/git-workflow.md @@ -96,6 +96,8 @@ After every `git push` that publishes new commits, immediately enumerate **all** > **CI watchers are NOT CodeRabbit watchers.** A CI watcher's check-list ends when GitHub Actions reports the run conclusion. CodeRabbit's inline review comments are invisible to it - CR's "check" goes green once the review is *submitted*, regardless of findings inside. If this push opened a PR (or is on an open PR branch), spawn a separate `cr-watch-` per §"Post-PR review loop" → §"Immediate PR-creation checklist" alongside the CI watchers. The two agent kinds run in parallel with different terminal conditions and different model tiers. +> **After every push to an open PR branch, re-request CodeRabbit and arm the 10-minute timer — do both, at the same time.** Immediately post `@coderabbitai review` (a push without a re-request leaves the new commits unreviewed), and at the same moment arm a ~10-minute timer before reading or triaging CR comments. CodeRabbit needs several minutes to post; triaging earlier just reads a stale or absent review. The cr-watch agent (§2) owns this delay — its first read is ~10 minutes after the trigger — so a live cr-watch already implements the rule. If you are not running a cr-watch for this push, set the timer yourself (`ScheduleWakeup` ~10 min or a cron) and only triage when it fires. + **Setup**: 1. Right after `git push`, run `gh run list --commit --json databaseId,name,status` to list every run for the pushed commit. Wait briefly (a few seconds) and re-list if the run list looks incomplete — workflows can take a moment to register. @@ -152,7 +154,7 @@ Total: **3+ background agents per PR** (one per CI run + cr-watch + merge-watch) Spawn a background `Agent` named `cr-watch-` (`model: haiku` — polling, rate-limit handling, and the §3 triage into Actionable/Stylistic/Nitpick are all rubric-driven; **re-spawn fix commits on Opus** — CR-loop fix commits are an iteration loop per CLAUDE.md §2 and run on Opus regardless of how localised the diff looks, because the triage call about which findings to fix vs. dismiss-with-justification, and whether a "tiny fix" reveals an architectural gap, is the judgement that Sonnet has empirically gotten wrong here. Step down to Haiku/Sonnet only when applying a fully-prescribed diff verbatim with no judgement involved) that: -- Polls `gh api repos///pulls/<#>/comments` and `gh pr view <#> --json reviews` every **60–120s** (never faster — CodeRabbit's own backend rate-limits review processing and aggressive polling won't make the review come faster). +- **Waits ~10 minutes after the `@coderabbitai review` trigger before its first read**, then polls `gh api repos///pulls/<#>/comments` and `gh pr view <#> --json reviews` every **60–120s** (never faster — CodeRabbit's own backend rate-limits review processing and aggressive polling won't make the review come faster). The 10-minute timer matches how long CodeRabbit typically takes to post a review on a non-trivial diff; reading and triaging earlier just sees a stale or absent review and burns a wasted pass. Arm the timer with `ScheduleWakeup` (~10 min) or a `*/2 * * * *` cron that no-ops until 10 minutes have elapsed — don't block the main session spinning. - Treats `429`, `403 secondary rate limit`, or any "rate limit" string in the response body as a **soft** error: log, sleep 120s, retry. Do not escalate. Rate-limit responses are normal during high-traffic windows; a watcher that escalates on every 429 wastes user attention. If the cooldown is long or the agent may be reaped before it clears, also schedule a retry cron per §"Rate-limit handling" so progress resumes even if this watcher dies mid-wait. - **Detect CodeRabbit's posted rate-limit message and honor its stated cooldown exactly.** CodeRabbit signals throttling not only via HTTP `429` but as a *posted comment/review* whose body reads, e.g.: `Rate limit exceeded` / `@ has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 10 minutes and 38 seconds before requesting another review.` When you see this, parse the stated wait (`Xm Ys`) and schedule a retry cron for **that exact duration plus a ~30s buffer** (per §"Rate-limit handling", but use the stated cooldown instead of the default 2-minute tick — the provider told you precisely how long to wait, so honor it rather than polling early and burning more of the quota). When the cron fires, re-post `@coderabbitai review` and confirm a real review actually arrives before proceeding to §3. Do NOT treat the warning comment itself as a review: it carries no findings, so it is not loop-exit and must not be counted as a clean pass. - **`out of usage credits` / billing messages → escalate, do not retry.** If the message says credits are exhausted (e.g. `You've run out of usage credits. Purchase more in the billing tab.`), waiting will not help. Escalate to the user with the verbatim message and pause the CR loop; resume only once the user confirms credits are restored. Distinguish this from a plain rate limit: a rate limit clears on its own after the stated wait, a credit exhaustion does not. @@ -169,7 +171,7 @@ When CodeRabbit's review arrives, the watcher reads each suggestion and triages - **Stylistic preference contrary to project conventions** (or a trade-off that was already considered during implementation): reply on the PR comment with a brief justification linking to the convention in `CLAUDE.md` or the relevant code; do NOT commit a change. - **Genuine nitpick** (minor, unambiguously safe to apply, not contrary to convention): fix it. **Batch nitpicks into one commit** rather than one-commit-per-nitpick — single-line fix commits create review noise and inflate the history without buying anything. -After the response pass, post one PR comment summarising what was addressed vs. dismissed and why. This avoids leaving CodeRabbit's threads silently unaddressed and gives the human reviewer a clean signal that the bot pass is complete. **End that comment with a fresh `@coderabbitai review` ping** so the bot re-reviews the fix push — without the explicit ping CodeRabbit will sometimes process a re-review automatically and sometimes not, depending on configuration; the explicit ping makes the loop deterministic. This re-ping is the most common trigger for CodeRabbit's "exceeded the limit for the number of commits that can be reviewed per hour. Please wait Xm Ys" message — if you get it, do not abandon the round: parse the stated wait and re-ping after exactly that long per §2's stated-cooldown rule. +After the response pass, post one PR comment summarising what was addressed vs. dismissed and why. This avoids leaving CodeRabbit's threads silently unaddressed and gives the human reviewer a clean signal that the bot pass is complete. **End that comment with a fresh `@coderabbitai review` ping** so the bot re-reviews the fix push — without the explicit ping CodeRabbit will sometimes process a re-review automatically and sometimes not, depending on configuration; the explicit ping makes the loop deterministic. **After this re-ping, arm the ~10-minute timer again before reading the new review** (§2) rather than polling immediately — every fix push restarts the same give-CR-time clock. This re-ping is the most common trigger for CodeRabbit's "exceeded the limit for the number of commits that can be reviewed per hour. Please wait Xm Ys" message — if you get it, do not abandon the round: parse the stated wait and re-ping after exactly that long per §2's stated-cooldown rule. **Iterate until CodeRabbit is silent.** Each fresh CR review starts a new triage round — read every Actionable / Nitpick / Outside-diff finding, apply the bucket rules, push a fix commit (or post a justification reply), and ping `@coderabbitai review` again. CR commonly produces 3–6 review passes on a substantive PR before reaching all-clear; "I addressed pass 1" is **not** loop-exit. The loop only exits when the most recent CR review contains zero **Actionable** items AND every **Nitpick** is either fixed or has a justification reply on the inline thread. Dismissing nitpicks silently by ignoring them is not loop-exit — it leaves the threads unresolved and the human reviewer has to re-triage them. If after a fix push CR returns the SAME finding (i.e., the fix didn't actually address the concern), do not just push another best-effort attempt — read the original finding more carefully and either (a) push a real fix that genuinely closes the gap or (b) reply on the inline thread explaining why the fix as-pushed addresses the concern and that CR's re-flag is a duplicate; never let the same finding ping-pong more than 2 rounds without explicit user direction.