t2793: fix pulse external-contributor comment spam — use REST API for labels#2794
Conversation
gh pr edit --add-label fails with GraphQL Projects deprecation warning (exit 1), preventing the external-contributor label from being applied. This broke the idempotency guard, causing duplicate comments on every pulse cycle (17+ on PR #2792). Replace both instances (external-contributor gate and orphaned PR scanner) with gh api repos/<slug>/issues/<number>/labels REST endpoint which works correctly. Closes #2793
Summary of ChangesHello, 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 updates the Highlights
Changelog
Activity
Using Gemini Code AssistThe 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
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 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. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review infoConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
WalkthroughThis change replaces two Changes
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~3 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
🔍 Code Quality Report�[0;35m[MONITOR]�[0m Code Review Monitoring Report �[0;34m[INFO]�[0m Latest Quality Status: �[0;34m[INFO]�[0m Recent monitoring activity: 📈 Current Quality Metrics
Generated on: Wed Mar 4 00:25:25 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
There was a problem hiding this comment.
Code Review
This pull request correctly resolves an issue with comment spam by replacing a failing gh pr edit command with a direct gh api call. This is a solid fix. However, the implementation retains the use of 2>/dev/null, which suppresses all error output and can make debugging difficult. My review includes suggestions to replace this with the gh api command's --silent flag, which aligns better with general scripting guidelines by hiding successful output while still showing important error messages.
Note: Security Review has been skipped due to the limited scope of the PR.
| if ! gh pr view <number> --repo <slug> --json labels --jq '.labels[].name' 2>/dev/null | grep -q '^external-contributor$'; then | ||
| gh pr comment <number> --repo <slug> --body "This PR is from an external contributor (@<author>). Auto-merge is disabled for external PRs — a maintainer must review and merge manually." | ||
| gh pr edit <number> --repo <slug> --add-label "external-contributor" 2>/dev/null || true | ||
| gh api "repos/<slug>/issues/<number>/labels" -X POST -f 'labels[]=external-contributor' 2>/dev/null || true |
There was a problem hiding this comment.
Using 2>/dev/null suppresses all error output, which can hide underlying problems with authentication, network, or API changes, making debugging difficult. The project's scripting guidelines recommend avoiding blanket error suppression.
The gh api command includes a --silent flag that suppresses the successful JSON response on stdout without hiding genuine errors on stderr. Adopting this flag would make the command more robust and easier to debug.
| gh api "repos/<slug>/issues/<number>/labels" -X POST -f 'labels[]=external-contributor' 2>/dev/null || true | |
| gh api --silent "repos/<slug>/issues/<number>/labels" -X POST -f 'labels[]=external-contributor' || true |
|
|
||
| ```bash | ||
| gh pr edit <number> --repo <slug> --add-label "status:orphaned" 2>/dev/null || true | ||
| gh api "repos/<slug>/issues/<number>/labels" -X POST -f 'labels[]=status:orphaned' 2>/dev/null || true |
There was a problem hiding this comment.
As with the other change, using 2>/dev/null is not ideal as it hides all error messages. To improve debuggability and align with project guidelines, please use the --silent flag to suppress successful output while allowing errors to be reported to stderr.
| gh api "repos/<slug>/issues/<number>/labels" -X POST -f 'labels[]=status:orphaned' 2>/dev/null || true | |
| gh api --silent "repos/<slug>/issues/<number>/labels" -X POST -f 'labels[]=status:orphaned' || true |
|
… function (t1391) The LLM supervisor kept re-implementing the inline bash idempotency guard incorrectly on each pulse cycle, causing 15+ duplicate 'external contributor' comments on PR #2792 despite 4 prior fix attempts (PRs #2794, #2796, #2801, #2803) — all in pulse.md prompt text. Root cause: the check is deterministic (one correct answer regardless of context) but was encoded as prompt guidance that the LLM had to re-implement each cycle. Per the 'Intelligence Over Determinism' principle, deterministic logic belongs in the harness, not the prompt. Changes: - Add check_external_contributor_pr() to pulse-wrapper.sh: checks BOTH label AND comment, captures exit codes separately, fails closed on any API error, only posts when confirmed safe - Add check_permission_failure_pr() companion function for the permission API failure case - Add source guard (BASH_SOURCE check) so pulse-wrapper.sh can be sourced for its functions without triggering the full lifecycle - Update pulse.md to call the helper functions instead of inline bash - Update Hard Rule 12 to reference the helper functions Closes #2809
… function (t1391) (#2810) The LLM supervisor kept re-implementing the inline bash idempotency guard incorrectly on each pulse cycle, causing 15+ duplicate 'external contributor' comments on PR #2792 despite 4 prior fix attempts (PRs #2794, #2796, #2801, #2803) — all in pulse.md prompt text. Root cause: the check is deterministic (one correct answer regardless of context) but was encoded as prompt guidance that the LLM had to re-implement each cycle. Per the 'Intelligence Over Determinism' principle, deterministic logic belongs in the harness, not the prompt. Changes: - Add check_external_contributor_pr() to pulse-wrapper.sh: checks BOTH label AND comment, captures exit codes separately, fails closed on any API error, only posts when confirmed safe - Add check_permission_failure_pr() companion function for the permission API failure case - Add source guard (BASH_SOURCE check) so pulse-wrapper.sh can be sourced for its functions without triggering the full lifecycle - Update pulse.md to call the helper functions instead of inline bash - Update Hard Rule 12 to reference the helper functions Closes #2809
Addresses quality-debt review feedback from PR #2794 (Gemini). 2>/dev/null suppresses all stderr, hiding auth, network, and API errors. gh api --silent only suppresses the successful JSON response body on stdout while preserving genuine error output on stderr. The || true already handles non-zero exit codes for resilience. Three call sites updated: - pulse.md:279 (orphaned PR labeling) - pulse-wrapper.sh:660 (external-contributor label re-add) - pulse-wrapper.sh:671 (external-contributor label on first flag) Closes #2819
) Addresses quality-debt review feedback from PR #2794 (Gemini). 2>/dev/null suppresses all stderr, hiding auth, network, and API errors. gh api --silent only suppresses the successful JSON response body on stdout while preserving genuine error output on stderr. The || true already handles non-zero exit codes for resilience. Three call sites updated: - pulse.md:279 (orphaned PR labeling) - pulse-wrapper.sh:660 (external-contributor label re-add) - pulse-wrapper.sh:671 (external-contributor label on first flag) Closes #2819



Summary
gh pr edit --add-labelwithgh api repos/<slug>/issues/<number>/labels -X POSTREST endpoint in two locations inpulse.mdgh pr editfails with "Projects (classic) is being deprecated" warning (exit 1), preventing label application and breaking the idempotency guardChanges
.agents/scripts/commands/pulse.md— two one-line replacements:gh pr edit --add-label "external-contributor"→gh api "repos/<slug>/issues/<number>/labels" -X POST -f 'labels[]=external-contributor'gh pr edit --add-label "status:orphaned"→gh api "repos/<slug>/issues/<number>/labels" -X POST -f 'labels[]=status:orphaned'Both retain the
2>/dev/null || trueerror suppression for resilience.Why REST API
The GitHub REST endpoint
POST /repos/{owner}/{repo}/issues/{number}/labelsis not affected by the GraphQL Projects deprecation. It returns a clean 200 and applies the label reliably. This was already validated manually on PR #2792.Closes #2793
Summary by CodeRabbit