Skip to content

feat: auto-decline draft-responses when agent determines no reply needed#5522

Merged
marcusquinn merged 1 commit intomainfrom
feature/auto-decline-draft-responses
Mar 23, 2026
Merged

feat: auto-decline draft-responses when agent determines no reply needed#5522
marcusquinn merged 1 commit intomainfrom
feature/auto-decline-draft-responses

Conversation

@marcusquinn
Copy link
Copy Markdown
Owner

@marcusquinn marcusquinn commented Mar 23, 2026

Summary

  • Change 1 (agent instruction): Added AGENT COMPOSE INSTRUCTION comment block to contribution-watch-helper.sh auto-draft section and to the draft template body in draft-response-helper.sh. When the compose agent determines no reply is needed, it now has explicit guidance to call draft-response-helper.sh reject <draft_id> "No reply needed" immediately instead of leaving the notification issue open.

  • Change 2 (deterministic safety net): Added a second pass in cmd_check_approvals that auto-declines open draft issues where: (1) the draft body contains clear no-reply indicators (e.g. "no reply needed", "no action required", "recommendation: decline"), (2) no user comment exists on the notification issue, and (3) the draft was created more than 24h ago (grace period to avoid premature auto-decline of drafts still being composed).

  • UX improvement: Updated the notification issue "How to respond" section with clearer guidance including a note that the agent will auto-decline no-reply drafts without requiring user input.

  • Help text: Updated cmd_help to document the new auto-decline safety net behaviour.

Root cause addressed

Issues #3, #5, #7 on the draft-responses repo all recommended no reply but required manual closure. The compose step had no mechanism to act on its own "no reply" determination — it wrote the draft text but left the notification issue open. This PR adds both the primary fix (agent instruction) and a fallback (deterministic safety net).

Closes #5520

Summary by CodeRabbit

  • New Features

    • Added automatic decline of draft responses after 24 hours when no reply is needed and no user action is taken.
  • Documentation

    • Enhanced guidance for responding to draft notifications with clearer instructions for approval, revision, or decline actions.
    • Updated help text to document the new auto-decline safety net behavior and trigger conditions.

- Add AGENT COMPOSE INSTRUCTION to contribution-watch-helper.sh auto-draft
  section: after composing, if recommendation is no reply/no action/decline,
  call draft-response-helper.sh reject instead of leaving issue open (t5520)
- Add agent instruction comments to draft template body so compose agent
  knows to call reject for no-reply cases
- Update notification issue 'How to respond' section with clearer guidance
  including note that agent will auto-decline no-reply drafts
- Add deterministic safety net in check-approvals: auto-declines open draft
  issues where body contains no-reply indicators, no user comment exists,
  and 24h grace period has elapsed (catches compose agent failures)
- Update cmd_help to document the new auto-decline safety net behaviour

Closes #5520
@github-actions github-actions Bot added the enhancement Auto-created from TODO.md tag label Mar 23, 2026
@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly improves the efficiency of handling draft responses by automating the closure of issues where no reply is deemed necessary. It introduces both a proactive instruction for the AI agent to reject such drafts immediately and a robust fallback safety net to ensure these drafts are eventually closed without manual intervention, thereby reducing operational overhead and streamlining the workflow for users.

Highlights

  • Agent Instruction for Auto-Decline: The agent now has explicit guidance to immediately reject draft replies if it determines no response is needed, preventing notification issues from remaining open.
  • Deterministic Safety Net: A new mechanism in cmd_check_approvals automatically declines open draft issues after 24 hours if their body indicates 'no reply needed' and no user comment exists, serving as a fallback for the agent instruction.
  • UX Improvement: The 'How to respond' section in notification issues has been updated with clearer instructions, including a note about the agent's ability to auto-decline no-reply drafts.
  • Help Text Update: The cmd_help command now includes documentation for the newly implemented auto-decline safety net behavior.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 23, 2026

Walkthrough

Two shell scripts now include documentation and a deterministic safety net for auto-declining draft responses. The compose agent receives instructions to call reject when determining no reply is needed. A 24-hour grace period check scans open draft issues, verifies no user comments exist, and matches draft bodies against "no reply" indicators before auto-declining.

Changes

Cohort / File(s) Summary
Auto-Draft Compose Guidance
.agents/scripts/contribution-watch-helper.sh
Added explicit AGENT COMPOSE INSTRUCTION comments documenting post-draft behavior and the deterministic safety net fallback for auto-decline when "no reply needed" is recommended.
Auto-Decline Safety Net & CLI Updates
.agents/scripts/draft-response-helper.sh
Implemented deterministic safety net in cmd_check_approvals that scans open draft issues, enforces 24-hour grace period, verifies no user comments, and matches draft body against case-insensitive "no reply" indicators before calling cmd_reject. Updated CLI help text, cmd_draft template with agent instructions, and "How to respond" guidance in notification issues.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

Draft responses open without end,
But now the safety net descends—
When agents say "no action here,"
The auto-decline makes issues clear. 🛡️
No manual toil, no human call,
Just logic catching them all.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main feature: auto-declining draft-responses when no reply is needed, which matches the primary objective of the PR.
Linked Issues check ✅ Passed The PR fully implements both primary (agent instruction to call reject) and secondary (24h safety net in check-approvals) objectives from issue #5520, with documentation updates.
Out of Scope Changes check ✅ Passed All changes are scoped to the two linked scripts and directly address the objectives: agent instructions, safety net logic, user guidance, and CLI help text.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/auto-decline-draft-responses

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

🔍 Code Quality Report

�[0;35m[MONITOR]�[0m Code Review Monitoring Report

�[0;34m[INFO]�[0m Latest Quality Status:
SonarCloud: 0 bugs, 0 vulnerabilities, 483 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Mon Mar 23 00:51:42 UTC 2026: Code review monitoring started
Mon Mar 23 00:51:42 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 483

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 483
  • VULNERABILITIES: 0

Generated on: Mon Mar 23 00:51:45 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

@sonarqubecloud
Copy link
Copy Markdown

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
.agents/scripts/draft-response-helper.sh (1)

861-862: Consider using grep -E for extended regex portability.

The alternation pattern with \| works on GNU grep (macOS Homebrew / Linux default), but isn't POSIX-compliant. For maximum portability across grep implementations, use the -E flag for extended regular expressions.

🔧 Suggested fix for portability
-		if echo "$sa_combined_text" | grep -qi \
-			"no reply needed\|no action needed\|no action required\|recommendation: decline\|no reply is needed\|decline this draft\|not necessary to reply\|no response needed\|no response required\|no reply necessary"; then
+		if echo "$sa_combined_text" | grep -qiE \
+			"no reply needed|no action needed|no action required|recommendation: decline|no reply is needed|decline this draft|not necessary to reply|no response needed|no response required|no reply necessary"; then

Note: The same pattern appears elsewhere in this file (e.g., line 624) without -E, so this is consistent with existing style — just flagging for future consideration.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.agents/scripts/draft-response-helper.sh around lines 861 - 862, The grep
invocation checking sa_combined_text uses backslash-escaped alternation which is
not POSIX-portable; update the command that references the variable
sa_combined_text (the if-block containing the grep check) to use grep -E and
switch the alternation to use unescaped '|' (e.g., "no reply needed|no action
needed|...") so it works across grep implementations; apply the same change to
the other occurrences of the same pattern (such as the similar check earlier in
the script).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @.agents/scripts/draft-response-helper.sh:
- Around line 861-862: The grep invocation checking sa_combined_text uses
backslash-escaped alternation which is not POSIX-portable; update the command
that references the variable sa_combined_text (the if-block containing the grep
check) to use grep -E and switch the alternation to use unescaped '|' (e.g., "no
reply needed|no action needed|...") so it works across grep implementations;
apply the same change to the other occurrences of the same pattern (such as the
similar check earlier in the script).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 43e01d22-73b3-45f5-aeb7-46fbc807484b

📥 Commits

Reviewing files that changed from the base of the PR and between f13aea9 and 9488453.

📒 Files selected for processing (2)
  • .agents/scripts/contribution-watch-helper.sh
  • .agents/scripts/draft-response-helper.sh

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a valuable safety net to auto-decline draft responses that recommend no reply. The implementation is well-structured, particularly the new logic in cmd_check_approvals. I have identified a few areas for improvement. My primary concern is a potentially incorrect jq filter that might cause the safety net to misfire by only checking for comments from a single user, instead of any user. Additionally, I've provided suggestions to enhance the efficiency of date parsing and to simplify the logic for detecting 'no-reply' indicators. The date parsing suggestion also removes the suppression of stderr, which could hide errors. These changes should make the new feature more robust and maintainable.

# Check for user comments on this notification issue
local sa_comments
sa_comments=$(gh api --paginate "repos/${slug}/issues/${sa_issue_number}/comments?per_page=100" \
--jq "[.[] | select(.user.login == \"${username}\") | select(.user.login | test(\"\\\\[bot\\\\]\$\"; \"i\") | not)]" \
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

The jq filter select(.user.login == "${username}") restricts the comment search to a single, specific user (${username}). However, the feature's goal is to act when "no user comment exists", which implies checking for comments from any non-bot user. The current implementation could lead to incorrect auto-declines if a user other than ${username} has commented. To correctly check for comments from any non-bot user, the filter for a specific username should be removed.

Suggested change
--jq "[.[] | select(.user.login == \"${username}\") | select(.user.login | test(\"\\\\[bot\\\\]\$\"; \"i\") | not)]" \
--jq "[.[] | select(.user.login | test("\\[bot\\]$"; "i") | not)]" \

Comment on lines +820 to +825
if date -j -f "%Y-%m-%dT%H:%M:%SZ" "$sa_created" +%s &>/dev/null 2>&1; then
sa_created_epoch=$(date -j -f "%Y-%m-%dT%H:%M:%SZ" "$sa_created" +%s 2>/dev/null) || sa_created_epoch=0
elif date -d "$sa_created" +%s &>/dev/null 2>&1; then
# GNU date fallback (Linux)
sa_created_epoch=$(date -d "$sa_created" +%s 2>/dev/null) || sa_created_epoch=0
fi
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The current date parsing logic calls the date command up to two times for each successful conversion (once to check for command success, and once to capture the output). This can be made more efficient and readable by attempting the conversion, capturing the exit code, and then trying the fallback if needed. This avoids redundant process calls. Also, avoid suppressing stderr with 2>/dev/null on commands that parse configuration files (e.g., date), as it can hide syntax errors and make debugging difficult.

Suggested change
if date -j -f "%Y-%m-%dT%H:%M:%SZ" "$sa_created" +%s &>/dev/null 2>&1; then
sa_created_epoch=$(date -j -f "%Y-%m-%dT%H:%M:%SZ" "$sa_created" +%s 2>/dev/null) || sa_created_epoch=0
elif date -d "$sa_created" +%s &>/dev/null 2>&1; then
# GNU date fallback (Linux)
sa_created_epoch=$(date -d "$sa_created" +%s 2>/dev/null) || sa_created_epoch=0
fi
local sa_created_epoch
# Try macOS `date` first
sa_created_epoch=$(date -j -f "%Y-%m-%dT%H:%M:%SZ" "$sa_created" +%s)
local mac_date_exit_code=$?
# If it fails, try GNU `date` as a fallback
if [[ $mac_date_exit_code -ne 0 ]]; then
sa_created_epoch=$(date -d "$sa_created" +%s)
fi
sa_created_epoch=${sa_created_epoch:-0}
References
  1. Avoid suppressing stderr with 2>/dev/null on commands that parse configuration files (e.g., jq), as it can hide syntax errors and make debugging difficult.
  2. In shell scripts, capture a command's exit code in a variable instead of using $? directly in conditionals. This aligns with ShellCheck SC2181 and improves clarity for multi-way branches.

Comment on lines +860 to +872
local sa_no_reply=false
if echo "$sa_combined_text" | grep -qi \
"no reply needed\|no action needed\|no action required\|recommendation: decline\|no reply is needed\|decline this draft\|not necessary to reply\|no response needed\|no response required\|no reply necessary"; then
sa_no_reply=true
fi

if [[ "$sa_no_reply" == "true" ]]; then
_log_info "check-approvals safety-net: auto-declining draft ${sa_draft_id} (no-reply indicators found, no user comment, grace period elapsed)"
echo " Safety net: auto-declining draft ${sa_draft_id} (no-reply indicators, no user comment, 24h elapsed)"
cmd_reject "$sa_draft_id" "Auto-declined: no-reply indicators in draft body, no user comment after 24h grace period"
auto_declined=$((auto_declined + 1))
actions_taken=$((actions_taken + 1))
fi
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The logic for checking "no-reply" indicators can be simplified. The sa_no_reply variable is set and then immediately checked in the subsequent if statement. These steps can be combined by using the grep command's exit status directly as the condition for the if statement, which makes the code more concise.

Suggested change
local sa_no_reply=false
if echo "$sa_combined_text" | grep -qi \
"no reply needed\|no action needed\|no action required\|recommendation: decline\|no reply is needed\|decline this draft\|not necessary to reply\|no response needed\|no response required\|no reply necessary"; then
sa_no_reply=true
fi
if [[ "$sa_no_reply" == "true" ]]; then
_log_info "check-approvals safety-net: auto-declining draft ${sa_draft_id} (no-reply indicators found, no user comment, grace period elapsed)"
echo " Safety net: auto-declining draft ${sa_draft_id} (no-reply indicators, no user comment, 24h elapsed)"
cmd_reject "$sa_draft_id" "Auto-declined: no-reply indicators in draft body, no user comment after 24h grace period"
auto_declined=$((auto_declined + 1))
actions_taken=$((actions_taken + 1))
fi
# Match no-reply indicators (case-insensitive)
if echo "$sa_combined_text" | grep -qi \
"no reply needed\|no action needed\|no action required\|recommendation: decline\|no reply is needed\|decline this draft\|not necessary to reply\|no response needed\|no response required\|no reply necessary"; then
_log_info "check-approvals safety-net: auto-declining draft ${sa_draft_id} (no-reply indicators found, no user comment, grace period elapsed)"
echo " Safety net: auto-declining draft ${sa_draft_id} (no-reply indicators, no user comment, 24h elapsed)"
cmd_reject "$sa_draft_id" "Auto-declined: no-reply indicators in draft body, no user comment after 24h grace period"
auto_declined=$((auto_declined + 1))
actions_taken=$((actions_taken + 1))
fi

@marcusquinn marcusquinn merged commit e3ad99c into main Mar 23, 2026
46 checks passed
@marcusquinn marcusquinn deleted the feature/auto-decline-draft-responses branch March 23, 2026 01:05
marcusquinn added a commit that referenced this pull request Mar 23, 2026
The safety-net auto-decline logic (t5520) was filtering comments to only
those from the authenticated agent user (`${username}`), then excluding
bots. This meant a comment from any *other* human user was invisible to
the check, causing incorrect auto-declines when a non-agent user had
already engaged on the issue.

Remove the username equality filter; keep only the bot-exclusion test so
the guard correctly fires when *any* non-bot user has commented.

Fixes #5559 (Gemini review feedback from PR #5522)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Auto-created from TODO.md tag

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: auto-decline draft-responses when agent determines no reply needed

1 participant