Add stale approval reminder notifications - #54
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c5772f1d-ff6f-498e-9eae-ca09c02ae6da
There was a problem hiding this comment.
Pull request overview
This PR adds a new “stale approval reminder” terminal flow to the PR monitor state machine: when CI is green after new commits invalidate prior approvals, the user is prompted and can optionally trigger a provider-neutral reminder message, while suppressing duplicates per reviewer + commit.
Changes:
- Introduce a new terminal state
StaleApprovalCiGreenand corresponding state-machine actions/choices to send or skip reminders. - Track reminder suppression and in-flight reminder recipients in
MonitorState. - Add unit tests and update skill/docs to describe handling of the new
send_messagetask.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| README.md | Documents the new stale approval reminder capability. |
| PrCopilot/tests/PrCopilot.Tests/StateMachineTests.cs | Adds tests for stale-approval detection, prompting, and duplicate suppression. |
| PrCopilot/src/PrCopilot/StateMachine/TerminalStateType.cs | Adds StaleApprovalCiGreen terminal state enum value. |
| PrCopilot/src/PrCopilot/StateMachine/MonitorTransitions.cs | Implements detection, prompting, and reminder-execution action for stale approvals. |
| PrCopilot/src/PrCopilot/StateMachine/MonitorState.cs | Adds state to suppress duplicate reminders and track pending reminder recipients. |
| PrCopilot/skills/pr-monitor/SKILL.md | Documents how agents should handle the new send_message task provider-neutrally. |
Suppressed comments (3)
PrCopilot/src/PrCopilot/StateMachine/MonitorTransitions.cs:1165
- This message says CI is “fully passing” but displays
{Passed}/{Total};Totalcurrently includes legacyPendingstatuses (and other non-passing conclusions), so the text can be misleading (e.g.5/6 passed). Consider using an “effective” total that excludesPending(and aligns with the terminal-state condition).
Action = "ask_user",
Question = $"[{timestamp}] 🔄 PR #{state.PrNumber} has fully passing CI ({state.Checks.Passed}/{state.Checks.Total} passed), but the approval from {names} is stale after new commits.",
Choices = ["Send approval reminder", "Skip reminder", "I'll handle it myself"],
Context = new { approvers, state.PrUrl }
PrCopilot/src/PrCopilot/StateMachine/MonitorTransitions.cs:1178
- The reminder text also claims CI is “fully passing”, but it doesn’t include the same “effective total” logic (and may not actually be fully passing depending on how
Totalis computed). Aligning the wording/metrics with the terminal-state condition will prevent confusing reminders.
var message = $"CI is fully passing on PR #{state.PrNumber} ({state.PrTitle}), but your previous approval became stale after new commits. Could you take another look and re-approve? {state.PrUrl}";
PrCopilot/src/PrCopilot/StateMachine/MonitorTransitions.cs:1208
GetUnnotifiedStaleApproversdoesn’t filter out blank/whitespace authors.FetchReviewsAsynccan produceAuthor = ""when the API returns null/missing user logins, which would lead to empty recipients and notification keys like"{sha}:".
private static List<string> GetUnnotifiedStaleApprovers(MonitorState state)
=> state.StaleApprovals
.Select(a => a.Author)
.Where(author => !state.StaleApprovalNotifications.Contains(GetStaleApprovalNotificationKey(state.HeadSha, author)))
.Distinct(StringComparer.OrdinalIgnoreCase)
.ToList();
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c5772f1d-ff6f-498e-9eae-ca09c02ae6da
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c5772f1d-ff6f-498e-9eae-ca09c02ae6da
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c5772f1d-ff6f-498e-9eae-ca09c02ae6da
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c5772f1d-ff6f-498e-9eae-ca09c02ae6da
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 10 out of 10 changed files in this pull request and generated no new comments.
Suppressed comments (1)
PrCopilot/src/PrCopilot/StateMachine/MonitorTransitions.cs:19
- The XML doc comment for
DetectTerminalState’s priority order is now incorrect: the method checksReviewerRepliedbefore merge conflicts (and before the other states listed). Keeping this list accurate helps future edits avoid unintentionally changing precedence.
/// <summary>
/// Evaluate terminal states from current PR status.
/// Returns the highest-priority terminal state, or null if none detected.
/// Priority order: comment → merge conflict → CI failure → CI cancelled → approved+green → stale approval+green
/// </summary>
Summary
Testing