Re-poll CI state at delivery to skip superseded failures#195
Re-poll CI state at delivery to skip superseded failures#195subsetpark merged 4 commits intomainfrom
Conversation
By the time a Ci Respond action is dispatched, the failure that triggered it may already have been superseded by a newer run — the agent's orchestrator snapshot is only refreshed once per poll cycle (30s), and the semaphore wait can push actual delivery minutes later. Delivering a stale failure wakes the agent for a problem that's already fixed. The runner now re-polls GitHub just before the delivery slot: if the fetch fails or the fresh state shows no current failures, it logs and short-circuits to Skip_empty; otherwise it writes the fresh list into orchestrator state so respond_delivery reads current agent.ci_checks. The Ci-specific is_empty branch moves out of respond_delivery entirely. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Rate limit exceeded
Your PR has hit rate limit. Contact your admin to purchase credits for running PR reviews or try again in 7 minutes and 4 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the 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 have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Review SummaryThe PR correctly identifies and addresses the staleness problem for Ci deliveries by adding a GitHub re-poll before the claude slot. The design split (freshness gate in the runner, payload building in the pure function) is sound. However there are two correctness issues and one quality concern:
4 comments posted · Model: |
… guard - Move the fresh `set_ci_checks` write from the `ci_skip_reason` binding to inside `with_busy_guard` (within `with_claude_slot`, before the agent re-read). The write now only lands while holding the busy slot, so it can't race with the poller's writes or mutate state on a delivery that `with_busy_guard` then observes as `Respond_stale`. - Distinguish the CI skip reason in the `Skip_empty` log arm so a fetch-failure or "no current failures" short-circuit no longer emits the misleading "Skipped ci — nothing to deliver" line. - Restore the belt-and-suspenders `is_empty` guard in `respond_delivery` for `Ci`: if `agent.ci_checks` has no failure conclusions, return `Skip_empty` instead of an empty `Ci_payload`. Uses `Ci_check.is_failure` (single source of truth). - Re-add RD-2b to cover the pure-function guard. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Review SummaryThe four must-fix issues from Turn 1 are now correctly addressed: Two new should-fix observations on the newly introduced code:
One note about
3 comments posted · Model: |
- Extract [pr_number] to a let binding so the [fresh_pr_state] fetch
and [ci_skip_reason] can both reference it.
- Emit "No PR number yet — skipping CI state fetch" in the no-PR arm
of the fetch (previously silent), and encode a distinct reason
("no PR number" vs "fetch failed") in [ci_skip_reason] via a
[(pr_number, fresh_pr_state)] match. The terminal skip log is now
accurate for the no-PR case.
- Short-circuit the CI skip decision before [with_claude_slot]: when
[ci_skip_reason = Some _] and [is_ci], the [with_busy_guard] lambda
logs and yields [`Skip_empty] without entering the Claude slot,
freeing that slot for another agent doing real work. Normal path
(no skip, or non-CI) keeps all the work under [with_claude_slot].
- Collapses the stale-during-semaphore-wait window on the skip path:
no wait happens at all, so the skip log can't be misattributed.
Removes the now-redundant [ci_skip_reason] check in the [Skip_empty]
arm; inside the slot, [Skip_empty] only means a genuine empty
delivery, so the generic log is accurate.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Review SummaryAll seven issues raised across the two previous review turns have been fully addressed in this diff:
One cosmetic observation remains (new in this diff): the
1 comment posted · Model: |
[ci_skip_reason] is [Some _] iff the CI freshness gate fired (it's bound to [None] in the [else] branch when [not is_ci]), so the [when is_ci] guard on [Some reason when is_ci] is always true when that arm matches. Remove the guard and use [None ->] for the normal path; the match is self-documenting on [ci_skip_reason] alone. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Review SummaryAll seven outstanding issues from the three previous review turns have been fully addressed in this diff:
No new issues were found in this diff. The implementation is correct.
0 comments posted · Model: |
Summary
CiRespondaction finally dispatches, the failure that triggered it may have been superseded by a newer run. The orchestrator snapshot is only refreshed once per poll cycle (30s), and the semaphore wait can push actual delivery minutes later — so we wake agents for failures that have already cleared.Skip_empty; otherwise we write the fresh list into orchestrator state viaset_ci_checkssorespond_deliveryreads a currentagent.ci_checks.is_emptypath moves out ofrespond_deliveryentirely — freshness is the caller's concern (it requires I/O), the pure decision function just builds the payload from current state.Test plan
dune buildcleandune runtest— existing RD-1/2a/2c/3/4/5/6/7 still pass; RD-2b/RD-8/RD-9 removed (tested behavior that moved out of the pure function or a reverted parameter)dune fmtclean🤖 Generated with Claude Code
Summary by cubic
Re-polls GitHub for CI right before delivery and skips superseded failures with precise skip reasons to avoid stale alerts and wasted Claude slots. Fresh CI checks are written under the busy guard so
respond_deliverybuilds from current state.Bug Fixes
Skip_emptybefore taking a Claude slot.ci_checksviaOrchestrator.set_ci_checksinside the busy guard (before the agent re-read) to avoid races with the poller.Refactors
respond_deliveryreads CI checks fromagentand keeps a belt-and-suspenders guard usingCi_check.is_failure; the caller owns freshness and theset_ci_checkswrite. Simplified the CI skip fast path by removing a redundantis_ciguard.Written for commit db3a9de. Summary will update on new commits.