diff --git a/skills/git-workflow/evals/evals.json b/skills/git-workflow/evals/evals.json index 24833e4..648492b 100644 --- a/skills/git-workflow/evals/evals.json +++ b/skills/git-workflow/evals/evals.json @@ -305,5 +305,27 @@ "pattern": "(CLEAN is not sufficient|CLEAN isn.t sufficient|CLEAN alone|CLEAN can be stale|CLEAN doesn.t mean|not sufficient to merge|review_on_push|empty reviewRequests doesn|reviewRequests is not)" } ] + }, + { + "name": "old_head_review_clean_timeline_check", + "prompt": "PR has all checks green and mergeStateStatus CLEAN, but the only Copilot review is on the previous commit; I pushed a docs-only commit afterwards. Can I merge?", + "assertions": [ + { + "type": "content", + "pattern": "(?i)timeline" + }, + { + "type": "content", + "pattern": "(?i)review.?request" + }, + { + "type": "content", + "pattern": "(?i)(after|since|following).{0,50}(push|commit|head)" + }, + { + "type": "content", + "pattern": "(?i)(mergeable|safe to merge|can merge|merge it).{0,160}(no (new |further )?review|nothing (was )?announced|not.{0,20}announced)|((no (new |further )?review|nothing (was )?announced).{0,160}(mergeable|safe to merge|can merge))" + } + ] } -] +] \ No newline at end of file diff --git a/skills/git-workflow/references/pull-request-workflow.md b/skills/git-workflow/references/pull-request-workflow.md index 2df4cc7..824ae6d 100644 --- a/skills/git-workflow/references/pull-request-workflow.md +++ b/skills/git-workflow/references/pull-request-workflow.md @@ -784,6 +784,26 @@ Arm auto-merge / enqueue **only when all three hold**: Bot reviews (Copilot, Gemini) land 2–5 minutes after each push — wait that window out before concluding "no threads". +**Review on an earlier head + `CLEAN`: decide via the timeline, not the +review list.** After a follow-up push (docs-only changes often do not +re-trigger Copilot), the only review on record may sit on a previous commit +while `mergeStateStatus` reports `CLEAN` off it. Whether that is mergeable +depends on one question: was any review (re)announced *after* the latest +push? The reviews list cannot answer it — query the timeline events: + +```bash +R=; PR= +gh api repos/$R/issues/$PR/timeline --jq \ + '[.[] | select(.event=="review_requested" or .event=="reviewed") + | {event, actor: (.actor.login // .user.login), at: (.created_at // .submitted_at)}]' +``` + +- Last `review_requested` is **before** the latest push and a matching + `reviewed` followed it, no newer request → no review is in flight; the + old-head review + `CLEAN` is mergeable. +- A `review_requested` **after** the latest push with no `reviewed` yet → + a review is in flight; wait (see *Never merge over an announced review*). + **Recovery when armed too early:** ```bash