Skip to content

ci: sync Antigravity reviewer to the fixed comment-selection version - #259

Merged
doublegate merged 1 commit into
mainfrom
ci/agy-reviewer-comment-selection-fix
Aug 3, 2026
Merged

ci: sync Antigravity reviewer to the fixed comment-selection version#259
doublegate merged 1 commit into
mainfrom
ci/agy-reviewer-comment-selection-fix

Conversation

@doublegate

Copy link
Copy Markdown
Owner

Summary

Brings the agy PR reviewer up to the fixed version already on RustySNES main (via its #270 template-hardening sync + #273 comment-selection fix + a self-test), superseding the stale sync PR in this repo — which carried an earlier version with a real self-deletion bug agy flagged.

Fix over the prior sync

  • Comment id from the POST, not a re-query. gh pr comment prints the new comment's URL (…#issuecomment-<id>); that id is used directly. The old approach re-queried the comment list to find "the newest with our marker", which raced GitHub's read replication — right after posting, the list could still omit the new comment, so the "delete all but the newest" exclusion matched nothing and the run deleted the review it had just published (publish-before-delete turning into publish-then-destroy).
  • SELECT_STALE_JQ — the delete-selection jq filter is now a named readonly constant (the author + id-exclusion selects), exercised directly by a new offline test.
  • scripts/agy-review-selftest.sh — a network-free, gh-free test of that filter against fixtures (it has been wrong twice, both times invisibly — the review still posted, so nothing observed it). 6 checks, all passing.
  • Fail-closed flock (exit rather than run two agy processes unserialized) + an empty-AGY_LOCK guard; the URL-only OAuth-leak guard (oauth_url_present) is unchanged.

Verification

  • Byte-identical (same sha256 eabd2571…) with RustySNES main and the shared reviewer template.
  • bash -n clean; bash scripts/agy-review-selftest.sh → all 6 checks pass.

🤖 Generated with Claude Code

Bring the agy PR reviewer up to the version already on RustySNES main (via
its #270 template-hardening sync + #273 comment-selection fix),
superseding the stale sync PR, which carried an earlier version with a
real self-deletion bug that agy flagged.

What this version adds over the prior sync:
  - The just-posted review comment's id now comes from the POST itself
    (`gh pr comment` prints the new comment's URL; its trailing
    `#issuecomment-<id>` is authoritative), NOT from re-querying the
    comment list. The re-query raced GitHub's read replication -- right
    after posting, the list could still omit the new comment, so the
    "delete all but the newest" exclusion matched nothing and the run
    deleted the review it had just published (publish-before-delete
    turning into publish-then-destroy).
  - SELECT_STALE_JQ: the delete-selection jq filter is now a named,
    readonly constant (author + id-exclusion selects), exercised directly
    by a new offline self-test.
  - scripts/agy-review-selftest.sh: a network-free, gh-free test of that
    filter against fixtures (the filter has been wrong twice, both times
    invisibly -- the review still posted, so nothing observed it). Six
    checks, all passing.
  - Fail-closed flock (exit rather than run two agy processes
    unserialized) plus an empty-AGY_LOCK guard.
  - Keeps the URL-only OAuth-leak guard (oauth_url_present) unchanged.

Byte-identical with RustySNES main and the shared reviewer template.
bash -n clean; the self-test passes all six checks.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 3, 2026 20:32
@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes
    • Improved review comment replacement so older automated comments are removed only after a new comment is successfully posted.
    • Preserved existing comments when posting or comment identification fails.
    • Added safeguards to prevent review actions when required authentication or locking conditions are not met.
  • Tests
    • Added offline checks covering comment selection, exclusion rules, failure scenarios, and regression cases.

Walkthrough

The review script now enforces locking, validates generated comments, publishes before cleanup, and safely selects older bot comments. A new offline self-test validates the jq filter and API argument handling.

Changes

Review comment replacement hardening

Layer / File(s) Summary
Comment selection contract and self-test
scripts/agy-review.sh, scripts/agy-review-selftest.sh
SELECT_STALE_JQ selects older matching bot comments. The self-test validates marker extraction, jq compilation, filtering, regression cases, and gh api argument handling.
Execution safety checks
scripts/agy-review.sh
Lock setup and acquisition now fail closed. Generated comments are rejected when they contain a live Google OAuth authorisation URL.
Publish and stale-comment cleanup
scripts/agy-review.sh
The script publishes before deletion, extracts the new comment ID, and preserves existing comments when publication, ID extraction, or comment listing fails.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

Suggested reviewers: copilot

Sequence Diagram(s)

sequenceDiagram
  participant ReviewScript
  participant GitHubAPI
  participant JQ
  ReviewScript->>GitHubAPI: publish new review comment
  GitHubAPI-->>ReviewScript: return new comment ID
  ReviewScript->>GitHubAPI: list review comments
  GitHubAPI-->>ReviewScript: return comment data
  ReviewScript->>JQ: select older matching bot comments
  JQ-->>ReviewScript: return stale comment IDs
  ReviewScript->>GitHubAPI: delete selected comments
Loading
🚥 Pre-merge checks | ✅ 8 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Title check ⚠️ Warning The title uses the allowed type and imperative subject, but it omits the required scope in the Conventional Commits format. Add a scope, for example: "ci(agy): sync Antigravity reviewer to the fixed comment-selection version".
Changelog Entry For User-Visible Changes ⚠️ Warning The CHANGELOG rule fails: scripts/agy-review.sh changes PR comment posting/deletion behaviour, but [Unreleased] has no entry for this user-facing fix. Add a concise entry under CHANGELOG.md [Unreleased] describing the reviewer fix, including safe comment replacement and fail-closed locking.
✅ Passed checks (8 passed)
Check name Status Explanation
Description check ✅ Passed The description clearly explains the reviewer synchronisation, comment-selection fix, locking changes, self-test, and verification results.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Oracle Number Is Stated ✅ Passed The commit changes only reviewer tooling scripts and contains no emulation or n64-systemtest behaviour change; the rule explicitly passes tooling changes.
Docs-As-Spec Sync ✅ Passed The commit diff contains only scripts/agy-review.sh and scripts/agy-review-selftest.sh; no rustyn64 chip crate behaviour changes, so the documentation-sync rule does not apply.
Measured, Never Tuned ✅ Passed The PR changes only GitHub/agy shell automation. It adds no emulated hardware constant, hardware timing value, or emulated behaviour, so the accuracy-ledger rule does not apply.
Unsafe Stays Out Of The Chip Crates ✅ Passed The PR changes only two shell scripts. The Rust diff is empty, with no added unsafe or removed forbid(unsafe_code) attributes; chip crates and rustyn64-core retain the required forbids.

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

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown

Antigravity review (Gemini via Ultra)

This PR refactors agy-review.sh to post new review comments before deleting stale ones, hardens the concurrency lock to fail closed, and adds an offline self-test script (scripts/agy-review-selftest.sh) to validate comment-selection logic.

Blocking issues

None found.

Suggestions

  • scripts/agy-review-selftest.sh: The file mode in the git index is 100644 (non-executable). If a developer or runner executes ./scripts/agy-review-selftest.sh directly, execution will fail with permission denied. Grant executable permissions (chmod +x).
  • scripts/agy-review.sh:L608-L612: Inside the while read -r cid loop fed by herestring (<<< "$stale_ids"), explicitly pass < /dev/null to gh api -X DELETE to guard against any potential stdin consumption by subshell invocations.
  • scripts/agy-review-selftest.sh:L119: The line-folding regex construct (sed -e ':a' -e '/\\$/{N;s/\\\n//;ba' -e '}') relies on GNU sed behavior and fails on BSD sed (macOS). Consider using awk or perl if local execution across macOS host environments is expected.

Nitpicks

  • scripts/agy-review-selftest.sh:L31-L34: extract_filter relies on exact single-quote multi-line formatting of SELECT_STALE_JQ in agy-review.sh, which will break if the assignment style changes.
  • scripts/agy-review.sh:L430: Ensure AGY_LOCK has a fallback default assigned earlier in agy-review.sh so an empty or unset variable does not trigger an unintentional exit when running outside standard CI environments.

Automated first-pass review by agy on a self-hosted runner -- not a human review.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Updates the Antigravity (agy) GitHub PR reviewer script to the fixed “post-then-delete” implementation that avoids self-deleting the freshly posted review comment, and adds an offline self-test to keep the deletion-selection logic correct over time.

Changes:

  • Introduces a named, readonly SELECT_STALE_JQ filter and uses the posted comment’s ID from gh pr comment output to safely exclude the new comment from deletion.
  • Hardens serialization around agy execution by requiring flock and failing closed if locking can’t be established.
  • Adds scripts/agy-review-selftest.sh to validate the jq deletion-selection logic offline against fixtures and to prevent regressions around --arg/--argjson usage.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
scripts/agy-review.sh Fixes comment replacement ordering and ID selection to prevent deleting the newly posted review; hardens locking behavior; factors deletion selection into SELECT_STALE_JQ.
scripts/agy-review-selftest.sh Adds a network-free regression test for the jq-based stale-comment selection logic and the gh api/jq flag split.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/agy-review.sh`:
- Around line 576-614: Pin the GitHub CLI version used by scripts/agy-review.sh,
or add an explicit version assertion before the comment-posting flow that parses
post_output and new_comment_id. Ensure the workflow fails or stops safely when
the installed gh version is unsupported, preserving deterministic extraction of
the created comment URL.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: a546d1b1-8911-4691-a168-83ce68629473

📥 Commits

Reviewing files that changed from the base of the PR and between 8dcd1f0 and 4a26792.

📒 Files selected for processing (2)
  • scripts/agy-review-selftest.sh
  • scripts/agy-review.sh

Comment thread scripts/agy-review.sh
Comment on lines +576 to +614
new_comment_id="$(printf '%s\n' "$post_output" | sed -n 's/.*#issuecomment-\([0-9][0-9]*\).*/\1/p' | tail -n 1)"

# A failed delete is logged, not swallowed: silently ignoring it would let a transient API/perms
# error leave the old comment in place alongside the new one, so runs accumulate duplicates.
# The author filter is load-bearing, not cosmetic: without it, ANY user could put the
# marker (an HTML comment) in a PR comment and have this bot delete arbitrary comments on
# the next run. Only ever delete OUR OWN bot's prior review comments -- and only ones from
# BEFORE this run (the just-posted comment's own id is excluded so it can never delete itself).
if [ -z "$new_comment_id" ]; then
# FAIL CLOSED. Without a known id there is no way to tell the new comment from the old ones,
# and the safe direction is unambiguous: a leftover duplicate is noise, deleting the review
# that was just posted is data loss.
log "warning: could not determine the posted comment id; leaving prior review comments in place"
else
# `--arg`/`--argjson` rather than shell interpolation into the filter: the marker is an HTML
# comment today, but a quote or a backslash in it would otherwise break the jq program itself
# rather than simply not matching.
#
# Those are JQ flags, so the JSON is fetched raw and piped into a real `jq` — `gh api` has no
# `--arg`/`--argjson` of its own and rejects them. Handing them to `gh api --jq` made it exit
# non-zero on every run; with the old `2>/dev/null` swallowing the message and `set -o pipefail`
# in force, the script then died *after* posting, so the stale comments were never deleted and
# the job went red for a reason nothing printed. stderr is kept this time for exactly that
# reason. (`--paginate` without `--jq` emits one JSON array per page; `jq` reads that stream
# fine, applying `.[]` to each.)
stale_ids="$(
gh api "repos/${REPO}/issues/${PR}/comments" --paginate \
| jq -r --arg marker "$MARKER" --argjson new_id "$new_comment_id" "$SELECT_STALE_JQ"
)" || {
log "warning: could not list prior review comments; leaving them in place"
stale_ids=""
}
while read -r cid; do
[ -n "$cid" ] || continue
if ! gh api -X DELETE "repos/${REPO}/issues/comments/${cid}" >/dev/null 2>&1; then
log "warning: could not delete prior review comment ${cid}; a duplicate may result"
fi
done <<< "$stale_ids"
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.

🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Does gh pr commentprint the new comment's URL (with#issuecomment-<id>) to stdout on success?

💡 Result:

No, the gh pr comment command does not print the URL of the newly created comment to stdout upon success [1][2]. While gh pr comment is designed to add a comment to a pull request, the official GitHub CLI documentation and manual pages do not list the output of a comment URL as part of its standard behavior [1][2]. In many cases, the command executes silently on success, or may provide minimal feedback depending on the terminal environment, but it does not return the structured URL (such as ...#issuecomment-<id>) that some users might expect for automation or scripting purposes [1][2]. If you require the URL of a newly created comment, you may need to use an alternative approach, such as: 1. Using gh api to perform the request directly, which allows you to inspect the full JSON response containing the html_url field [3][4]. 2. Listing the comments after the command has executed to retrieve the most recent one [5][6]. For programmatic workflows where the URL is needed, leveraging the gh api command with the appropriate REST API endpoint (typically /repos/{owner}/{repo}/issues/{pull_number}/comments) is the recommended way to retrieve the created comment's metadata, including its URL [3][7][8].

Citations:


🏁 Script executed:

#!/bin/bash
set -eu

printf '%s\n' '--- workflow references ---'
rg -n -C 3 'gh |gh-version|GH_VERSION|setup-gh|cli/cli|antigravity-review' .github/workflows/antigravity-review.yml .github 2>/dev/null || true

printf '%s\n' '--- script context ---'
sed -n '520,630p' scripts/agy-review.sh

printf '%s\n' '--- comment-posting calls ---'
rg -n -C 4 'gh pr comment|post_output|new_comment_id|SELECT_STALE_JQ' scripts/agy-review.sh

Repository: doublegate/RustyN64

Length of output: 18075


🏁 Script executed:

#!/bin/bash
set -eu

printf '%s\n' '--- complete review workflow ---'
cat -n .github/workflows/antigravity-review.yml | sed -n '1,110p'

printf '%s\n' '--- local gh availability ---'
if command -v gh >/dev/null 2>&1; then
  gh --version
else
  printf '%s\n' 'gh is not installed in the verifier sandbox'
fi

printf '%s\n' '--- repository references to gh versioning ---'
rg -n -i 'gh([ _-]?cli)?|github[ /]cli|cli/cli' \
  .github/workflows scripts README.md .tool-versions .github 2>/dev/null || true

Repository: doublegate/RustyN64

Length of output: 18191


🌐 Web query:

site:github.com/cli/cli gh pr comment source output URL NewComment

💡 Result:

The gh pr comment command does not natively output the URL of a newly created comment to standard output in a simple, direct format by default [1]. However, you can obtain the URL of a newly created comment by using the command in combination with shell utilities or by capturing its output if the specific version of gh you are using supports it [2]. 1. Capture the output: Recent updates to gh have improved the behavior of command output. When running gh pr comment, you can often pipe or capture the output to verify the URL [2]. For example, in automated environments, you might see the URL printed to stdout if the command is executed successfully [2]. 2. Alternative Approach (Manual Retrieval): If the command does not provide the URL directly in your environment, you can retrieve it by querying the pull request's comments immediately after creation using gh pr view combined with jq [3][4]. Example using jq to find the most recent comment: gh pr view --json comments --jq '.comments[-1].url' 3. Best Practice for Automation: If you are working in CI/CD or scripts, the most reliable way to get the URL is to use the gh JSON output capabilities to inspect the PR state or to use the GitHub API directly via gh api to create the comment, which returns the full comment object including the html_url [3][5][1]. If you find that the command is not outputting the URL as expected, it is recommended to check your version of the GitHub CLI (gh --version) and use the gh pr view method for deterministic results in scripts [3][4].

Citations:


🌐 Web query:

site:cli.github.com/manual/gh_pr_comment "URL" output

💡 Result:

gh pr comment accepts a pull-request URL as its argument:

gh pr comment https://github.com/OWNER/REPO/pull/123 --body "Comment text"

The command’s output behavior is not documented as returning a URL; it adds, edits, or deletes a comment. (cli.github.com)

Citations:


🏁 Script executed:

#!/bin/bash
set -eu

printf '%s\n' '--- gh 2.96.0 command help ---'
gh pr comment --help | sed -n '1,120p'

printf '%s\n' '--- gh 2.96.0 source references ---'
for path in \
  pkg/cmd/pr/comment/comment.go \
  pkg/cmd/pr/comment/comment_test.go
do
  url="https://raw.githubusercontent.com/cli/cli/v2.96.0/${path}"
  printf '%s\n' "--- ${url} ---"
  curl -fsSL "$url" | rg -n -C 5 'Print|URL|html_url|NewComment|comment' | sed -n '1,180p' || true
done

Repository: doublegate/RustyN64

Length of output: 10533


Pin or assert the GitHub CLI version

gh v2.96.0 prints the created comment URL on stdout. The workflow does not pin gh, so this output format is not guaranteed on the self-hosted runner. Pin or assert the CLI version to preserve determinism.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/agy-review.sh` around lines 576 - 614, Pin the GitHub CLI version
used by scripts/agy-review.sh, or add an explicit version assertion before the
comment-posting flow that parses post_output and new_comment_id. Ensure the
workflow fails or stops safely when the installed gh version is unsupported,
preserving deterministic extraction of the created comment URL.

@doublegate
doublegate merged commit ed3dd3e into main Aug 3, 2026
14 checks passed
@doublegate
doublegate deleted the ci/agy-reviewer-comment-selection-fix branch August 3, 2026 20:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants