Dispatch a submitted review as one unit — batch reviews lost commands - #74
Merged
Merged
Conversation
…#73) Submitting a review fires one pull_request_review_comment event per comment, all at once; the dispatch job's per-PR concurrency group keeps one running + one pending run, so a review carrying several commands silently lost all but ~two (dev#140: two of three /asks evicted). GitHub fires a single pull_request_review (submitted) event for every comment shape — batch, single comment, thread reply — so that event is a complete surface. Per-comment events no longer dispatch (they keep the fast 👀 ack); the review event's one run enumerates the review's own comments (ReviewUnit) and dispatches every command-bearing one sequentially, each through the unchanged per-comment pipeline. Trust: a review is single-author by construction, so the hosted authorize gate on the submitter covers every enumerated comment; a comment by any other author drops fail-closed. The engine can't read comment bodies from the review event, so authorize gains a hosted scan step that detects commands and routes the runner label; bodies ride env vars, never inline expansion. Dispatcher#run now returns success instead of exiting — the review fan-out must reach every comment even when an earlier one failed; bin/dispatch.rb owns the red exit. Co-authored-by: Cursor <cursoragent@cursor.com>
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #73.
Root cause (recap)
Submitting a review fires one
pull_request_review_commentevent per comment, all at once. The dispatch job's per-PR concurrency group admits one running + one pending run, and every newer arrival supersedes the pending one — so a review carrying several commands silently lost all but ~two (dev#140: two of three/asks evicted). One correction to the issue's step 3: skipped jobs don't hold the pending slot — the queued/asks were evicted by each other and by the subsequent/buildon the same PR. Root cause unchanged: queue depth 1 per PR.The dedup axis, verified
The issue asked for a live probe of which events fire per comment shape. The dev#140 run list already answers it: the manual thread replies each fired both a
pull_request_review(submitted, empty body) and apull_request_review_commentrun. Every comment shape — batch submission, single comment, thread reply — is accompanied by exactly one review-submitted event, so command detection moves wholly to the review-level handler.Design
pull_request_review_commentnever dispatches (it keeps the instant 👀 ack). The review-submitted event is the dispatch unit.ReviewUnitexpands a review-summary context into per-comment dispatches: it enumerates the submitted review's own comments (GET /pulls/{n}/reviews/{review_id}/comments— event-sourced, never "latest review"), keeps the command-bearing ones, andbin/dispatch.rbruns each through the unchanged per-comment pipeline, sequentially inside the one run the concurrency group admits. Sibling commands can no longer evict each other.authorizegate on the submitter covers every enumerated comment. Defense-in-depth: a comment by any other author is dropped fail-closed with a log line.authorizegains a hosted scan step (post-permission-gate) that detects commands across review body + comments and routes the runner label (build > learn > split > edit > ask);dispatchgates on itscommandedoutput. Bodies ride env vars, never inline expansion. Cost: every authorized human review submission now runs a hosted authorize job (~10s, free on public repos) — previously only command-matching bodies did.Dispatcher#runreturns success instead of exiting — the fan-out must reach every comment even when an earlier one failed;bin/dispatch.rbowns the red exit.Verification
ReviewUnitfan-out incl. author mismatch, reply-shaped implicit review, prose mentions, invalid batches;GitHub#review_comments; dispatcher soft-failure return),srb tcclean, rubocop clean, every addedlib/line covered (patch target is 100%).Follow-ups (not this PR)
/buildsweep skips threads that start with a command, assuming the command pipeline answered them — with guaranteed delivery that assumption is sound again, but an unanswered command thread is still invisible to the sweep.Made with Cursor