Skip to content

fix(pr-review): do not restart completed reviews on delayed submitted events - #647

Open
all-hands-bot wants to merge 1 commit into
mainfrom
openhands/fix-delayed-submitted-review
Open

all-hands-bot wants to merge 1 commit into
mainfrom
openhands/fix-delayed-submitted-review

Conversation

@all-hands-bot

@all-hands-bot all-hands-bot commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

HUMAN:
No human has tested these changes. The checkbox below is intentionally left unchecked, and all evidence in this description comes from agent-run automated tests and generated-artifact checks. This description was written by an AI agent at the maintainer's request.

  • A human has tested these changes.

AGENT:

Why

_finish_completed_review() in the reusable github-pr-reviewer extension decided completion by comparing each exact-head bot review's submitted_at against the selected trigger's created_at. In event mode the selected trigger is the latest review_requested issue event, and a pull_request_review.submitted delivery is naturally created after the review it reports. The review the event announced was therefore rejected by that window and never recognized as completion, so the configured maintainer handoff did not run for it. When no review_requested issue event was visible at all, the run also skipped completion entirely.

Summary

skills/github-pr-reviewer/scripts/worker.py:

  • run() now extracts the review object from a submitted event payload and passes it into the completion path. When no reviewer-request event is selected, a submitted delivery is still evaluated (with an empty trigger) instead of being skipped, because the submitted review is its own completion signal.
  • New _review_completes_request(review, triggered_at, submitted_review) accepts the exact review a submitted event names (matched by review id) regardless of timing, so a decisive exact-head bot review is recognized whether its submitted_at is before or after the selected review_requested timestamp. Non-submitted runs keep the previous timestamp comparison.
  • The existing "a submitted review is never a fresh trigger" guard is retained, so a non-decisive or wrong-head review neither dispatches nor hands off, and a later explicit review_requested event still starts a new exact-head review. Scheduled label mode is untouched.

automations/bundle-index.js regenerated with npm run build:automations; no manifest or fixture drift.

Diff is limited to the reusable extension, its tests, and the generated bundle:

 automations/bundle-index.js                 |   2 +-
 skills/github-pr-reviewer/scripts/worker.py |  37 +++++++++++++++++++++++++++++++++----
 tests/test_github_reviewer_delivery.py      | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 3 files changed, 153 insertions(+), 10 deletions(-)

Issue Number

Closes #646

How to Test

tests/test_github_reviewer_delivery.py gained:

  • test_reviewer_delayed_submitted_event_completes_prior_request — a review whose submitted_at predates the selected review_requested event is recognized, and the configured maintainer handoff (request_maintainer_review with the roster) runs once.
  • test_reviewer_submitted_event_completes_without_request_event — a submitted review completes even when no review_requested issue event is visible.
  • test_reviewer_delayed_submitted_event_without_roster_is_a_noop — the no-roster path stays a no-op.
  • test_reviewer_subsequent_review_request_starts_new_review — a later explicit review_requested still dispatches a new review.
  • The non-decisive and superseded-head cases now carry the submitted review id, so they pin the id-matching path.

Focused results

$ uv run pytest -q tests/test_github_reviewer_delivery.py tests/test_maintainer_handoff.py
29 passed in 7.71s

Full results

$ uv run pytest -q
986 passed, 23 skipped in 29.20s

$ uv run python scripts/sync_extensions.py --check
(clean; only the pre-existing non-blocking coverage warning for ./plugins/issue-duplicate-checker)

$ npm run build:automations
(no drift)

Video/Screenshots

Not applicable: this changes automation worker logic, not a GUI.

Notes

No live deployment or human verification was performed for this change; the behavior is covered by the unit tests above. The human-test checkbox is intentionally unchecked.

Generated by OpenHands AI on behalf of the user.

A pull_request_review.submitted delivery is created after the review it
reports, so comparing that review's submitted_at against the selected
review_requested timestamp rejected the very review the event announced.
The submitted event then fell through without completing the review, so
the configured maintainer handoff never ran for it.

Accept the exact review a submitted delivery names (matched by id)
regardless of timing, and evaluate a submitted delivery even when no
review_requested issue event is in the window. A submitted review still
never acts as a fresh trigger, so a later explicit review_requested event
starts a new exact-head review.
@neubig

neubig commented Sep 22, 2026

Copy link
Copy Markdown
Member

@all-hands-bot Please update this PR description so the repository's Validate PR description check passes. Preserve the substantive problem/change/test evidence, use the required HUMAN/AGENT markers and section headings, do not claim human testing, and then verify the check is green.

@all-hands-bot

Copy link
Copy Markdown
Contributor Author

Done — the PR description is updated and the Validate PR description check is now green.

What the check was failing on: the PR body used ## Problem / ## Change / ## Tests headings and had no linked issue, so the validator (.github/scripts/check_pr_description.py, run from the base SHA) reported three errors: Keep the '## Why' section from the PR template., Keep the '## Summary' section from the PR template., and Keep the '## How to Test' section from the PR template.

What I changed in the description:

  • Restored the required template headings: ## Why, ## Summary, ## Issue Number (Closes #646), and ## How to Test, keeping the substantive problem, change, and test evidence intact.
  • Added the required HUMAN: and AGENT: markers. HUMAN: is the first visible line and carries a short note; AGENT: precedes the technical summary.
  • Left the "A human has tested these changes" checkbox unchecked and stated explicitly that no human tested the change. All evidence is agent-run automated test output (29 passed focused, 986 passed, 23 skipped full, sync_extensions.py --check clean, npm run build:automations no drift).
  • Kept ## Video/Screenshots as "not applicable: automation worker logic, not a GUI".

Verification: I ran the base-SHA validator locally against the new body first (PR description validation passed.), then updated the PR and confirmed the CI check flipped to pass in run 35732628899. All other checks remain green.

Generated by OpenHands AI on behalf of the user.

@smolpaws smolpaws left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am an AI agent helping my human, Engel Nyst (@enyst), with repository maintenance.

Taste: good. Reviewed head 71b5028. No material correctness, security, compatibility, or acceptance-criterion findings.

Acceptance criteria for #646:

  • Submitted events select the reported review by ID while retaining the bot-author and current-head checks, including when no request event is available.
  • Decisive completion retains the configured maintainer handoff and no-roster behavior; non-decisive and wrong-head submissions do not dispatch work or hand off.
  • Later explicit review requests can dispatch a new review, and scheduled label behavior remains covered.
  • Generated automation bundle matches its source.

Validation: independently ran python -m pytest -q tests/test_github_reviewer_delivery.py tests/test_maintainer_handoff.py in a fresh test environment: 29 passed. npm run build:automations produced no tracked diff; scripts/sync_extensions.py --check passed with the existing non-blocking marketplace coverage warning. Current-head test and extension checks passed, and the later successful PR-description check supersedes its earlier failure. Tests exercise the shipped worker with mocked GitHub/dispatch boundaries; I did not perform a live deployment or webhook test.

[RISK ASSESSMENT]
[Overall PR] Risk Assessment: 🟢 LOW. This is a bounded completion-selection fix using existing identity checks and handoff behavior, with no dependency or runtime-contract changes.

Architectural insight: the submitted review's identity supplies the completion signal, while explicit review requests retain timestamp-based selection for new work.

✅ APPROVED

@enyst enyst left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: fix A bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(pr-review): do not restart completed reviews on delayed submitted events

5 participants