ci: adopt the inline pr-agent lane — a public repo cannot call a private reusable workflow - #30
Conversation
🤖 CodeAnt AI — Review Status
|
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_233d1f62-db85-44f4-85e7-0e833a0e3645) |
Reviewer's GuideReplaces the broken pr-agent reusable workflow call with a fully inline, self-contained workflow tailored for public repos, while re-syncing it with the current reusable lane behavior (event-keyed concurrency, timeouts, retry, and non-blocking verdict classification). Sequence diagram for the resilient PR-Agent review workflowsequenceDiagram
participant GitHub
participant Workflow
participant Agent as PR-Agent
participant Verdict
GitHub->>Workflow: Trigger pull_request or issue_comment
Workflow->>Workflow: Evaluate event-specific concurrency and job conditions
Workflow->>Agent: Run attempt 1 with 6-minute timeout
alt Attempt 1 succeeds
Agent-->>Verdict: success
else Attempt 1 fails
Workflow->>Workflow: Sleep 45 seconds
Workflow->>Agent: Run retry attempt with 6-minute timeout
Agent-->>Verdict: success or failure
end
Verdict->>Verdict: Classify success, cancellation, timeout, or reviewer failure
Verdict-->>GitHub: Advisory result, workflow faults remain visible
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Team Run ID: 📒 Files selected for processing (1)
📝 SummarySummary by CodeRabbit
WalkthroughThe unreleased changelog documents fixes for fork-triggered commands, AI timeout limits, skipped timeout attempts, and fork pull-request reviews. ChangesPR-Agent fixes
Estimated code review effort: 1 (Trivial) | ~2 minutes ✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
Comment |
PR Summary by QodoFix pr-agent workflow for public repos by inlining lane and adding retries/timeouts
AI Description
Diagram
High-Level Assessment
Files changed (1)
|
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — The PR turns a previously nonfunctional reusable-workflow reference into an active, secret-bearing PR automation lane with external LLM calls, PR write permissions, comment triggers, retries, and fork/concurrency gating. Although the author owns the affected files and has relevant CI history, the resulting runtime and security-sensitive workflow behavior warrants human review. Not approved because:
Review your spending limits in Billing settings. You can add or adjust custom eligibility rules. Learn more. |
PR Reviewer Guide 🔍(Review updated until commit 03cb6b5)Here are some key observations to aid the review process:
|
PR Code Suggestions ✨No code suggestions found for the PR. |
|
Note Automatic reviews are paused because your team has used its included automatic processing for this billing period (headroom scales with your seat count). You can still comment "Gitar review" to run one anytime, and automatic reviews resume on their own by September 1. Add seats for more headroom. Code Review ✅ ApprovedAdopts the self-contained inline PR-Agent workflow for public repositories to resolve private workflow invocation errors. No issues found. OptionsDisplay: compact → Showing less information. Comment with these commands to change the behavior for this request:
Was this helpful? React with 👍 / 👎 | Gitar |
There was a problem hiding this comment.
Hey - I've reviewed your changes and they look great!
Sourcery assessment
Needs a human reviewer. This makes a pinned external action run with the repository's OpenAI secret and pull-request write permission, so a faulty configuration could post unwanted reviews or suggestions and those artifacts would remain after a revert. The workflow can be reverted to stop future runs, but already-published comments or suggestions would need separate cleanup.
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
Code Review by Qodo
1.
|
Qodo Fixer✅ Merged (0) · ☑ Fixed (0) Process
|
…ate reusable workflow This repo's pr-agent.yml calls `wave-av/wave-foundation/.github/workflows/reusable-pr-agent.yml`, and wave-foundation is PRIVATE. GitHub does not permit a PUBLIC repository to call a reusable workflow from a private one, so the `uses:` never resolves: the run dies before any job is created — conclusion: failure, total_count: 0, no log, and no check run on the head sha to read. Every PR here has carried a red check that reports nothing, and external contributors see it. Measured across the org 2026-08-22: 7 public repos / 176 runs / 100% failure; 9 private repos / zero failures — a clean 16/16 split on visibility alone. Three competing hypotheses (missing OPENAI_KEY, dead pinned ref, @main vs a pinned sha) were each tested and refuted. THE FIX already existed and was never adopted: wave-foundation-public/.github/workflows/pr-agent.yml is an INLINE copy of the same lane with no reference to the private repo. This adopts it verbatim. PROVEN BEFORE FANNING OUT. wave-certify#44 took this exact change first and its pr_agent run returned SUCCESS on the pull_request event — a job with a real log, where the broken form produced no job at all. 27 repos were not changed on hope. Two prerequisites named in wave-pen#388 are cleared as of wave-foundation-public#71: the shared concurrency key that let any bot comment cancel a live review ~10s in (wave-pen#386) now keys on github.event_name, and the lane carries step-level timeouts. The job id stays `pr_agent`, so the check-run context is unchanged and no branch protection rule needs touching. Refs wave-pen#388 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
7a7d15b to
03cb6b5
Compare
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_78e6be17-2772-4581-b169-a571aed1a928) |
|
Persistent review updated to latest commit 03cb6b5 |
…t classification Picks up wave-foundation-public#72, which landed after this PR was opened. The template this PR originally copied classified timeouts on TOTAL job time (attempt 1 + 45s backoff + attempt 2) against STEP_BUDGET_S=360, a PER-ATTEMPT budget. Two healthy-but-slow attempts (~180s each) were therefore reported as "TIMED OUT ... A hang, NOT a rate limit", and the else-branch claimed the run was "well inside the budget" from the same misused total. Found by qodo review on wave-monitor#48 and confirmed against the file. Now stamps each attempt separately and classifies on the LONGEST attempt, with if: always() end stamps so an attempt killed BY its step timeout still records one. Verified by dry-running both cases before the template landed. Updated in place rather than as a follow-up PR because this has not merged yet — cheaper, and it keeps the repo from ever carrying the defective version. Refs wave-av/wave-pen#417, wave-av/wave-pen#388
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_a40868a8-bb64-4916-9ef5-4f12f8295bf3) |
…s step cap Re-syncs this PR to the hardened template before it merges, so it cannot land carrying the two defects it was opened with (wave-pen#418, wave-foundation-public#73). 1. Fork status is now RESOLVED, not assumed. The job-level `if:` refuses forks on the `pull_request` arm; it structurally cannot on `issue_comment`, because fork status is absent from that payload — measured, with a positive control: `issues/<n>.pull_request` carries exactly [diff_url, html_url, merged_at, patch_url, url], while `pulls/<n>.head.repo.fork` answers. A `fork gate` step asks the pulls endpoint and FAILS CLOSED: only a literal `false` proceeds; a 404, a revoked token, a rate limit and `.head.repo = null` all skip. Scope: this lane runs no `actions/checkout`, so fork code is never fetched or executed and no exfiltration path existed. The durable defect was the comment claiming "Forks skipped (no secrets there)" — true of one arm, false of the other, and exactly what would mislead whoever adds a checkout step later. 2. CONFIG__AI_TIMEOUT 600 -> 300, in both env blocks. 600s inside a 360s step is unreachable: the runner killed the step first, so pr-agent never reached its own timeout and never fell back to CONFIG__FALLBACK_MODELS. 3. A latent classifier bug the gate exposed: `stamp attempt 2 end` runs under `if: always()`, so when attempt 2 never ran the arithmetic subtracted from zero and reported a 1787580408-second attempt as a confident TIMED OUT. Fixed at the arithmetic; the verdict also gains an explicit `skipped` branch. The job id stays `pr_agent`, so the check-run context is unchanged and no branch protection rule needs touching. Refs wave-pen#418, wave-pen#417, wave-pen#388 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_06ef41ad-b3d0-4ea3-aa02-b97c95f16f4c) |
|
Both qodo findings on this PR are fixed, and the branch here has been re-synced to the corrected template — the diff above now includes them.
Fixing the first one also exposed a third defect neither review caught: Upstream: wave-av/wave-foundation-public#73 · tracked as wave-pen#418. Thanks — the first finding was worth the catch. |
…ce of a true
Review of this wave found the fail-closed gate had a fail-OPEN consumer. Two
reviewers flagged it independently, on two different repos, and they were right.
if: steps.gate.outputs.fork != 'true' # grants when the output is EMPTY
The gate could only fail closed if it always wrote an output. It did, on every
path — so this did not fail open today, and the implicit success() on the
consumer covers a gate that errors outright. But the safety rested on an
argument rather than on the structure, and it is the very argument this change
exists to delete: absence must not read as permission.
Two independent changes, so neither carries the invariant alone:
- the gate now assigns a shell variable that STARTS at `true` and writes ONCE
at the end, so no future edit adding an early exit can emit nothing;
- the consumer requires `== 'false'`, an explicit affirmative, so an empty or
missing output skips the agent.
Also braces both sides of the A2 subtraction in the verdict step. The bare
`ATTEMPT2_START` was CORRECT — POSIX arithmetic expansion evaluates a bare name
as a variable, verified identical (180 == 180) — but a reviewer read it as a
literal token and filed it High. An expression that reads wrong on 27 repos gets
re-filed on 27 repos, so it is normalised rather than defended.
RECEIPTS. actionlint clean; zizmor clean; shellcheck clean. The gate was driven
through all six branches plus the reviewers' no-output scenario: only a literal
`false` reaches AGENT RUNS. The verdict was re-run across all six states and is
unchanged on the five that already worked.
LIVE: wave-av/api-spec merged the previous revision and its pull_request run
executed `fork gate (issue_comment only) -> success` in production, then ran the
agent — so the gate does not wrongly refuse a legitimate same-repo PR.
Upstream: wave-av/wave-foundation-public#73. Refs wave-pen#418, wave-pen#417.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_4e8ab551-3482-44bf-811e-b68ad2423559) |
…mber space Review found a SECOND concurrency collision, on a different axis from the one this template already documents (wave-pen#386). `issue_comment` fires for ISSUES as well as PRs, and GitHub draws both from ONE number sequence. So a comment on Issue #30 and a `/review` on PR #30 entered the same concurrency group. Concurrency is evaluated at WORKFLOW level, BEFORE the job-level `if:` runs — so the Issue comment cancelled the PR review already in flight, and was then skipped itself, having done nothing. That is the identical shape as the #386 defect the block above exists to fix, one axis over: a run that will not review taking the lane from the run that would have. #386 separated the two EVENTS; it did not separate the two number spaces inside one event. pull_request PR 433 -> pr-agent-pull_request-pr-433 issue_comment on PR 30 -> pr-agent-issue_comment-pr-30 issue_comment on ISSUE 30 -> pr-agent-issue_comment-issue-30 The last two used to be one group. actionlint and zizmor clean. Upstream: wave-av/wave-foundation-public#73. Refs wave-pen#418, wave-pen#417. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_c110ad18-b56f-4e36-bb05-c44752829620) |
A reviewer flagged the missing entry on wave-modules#41. 25 of the 28 repos in this wave keep the same Keep-a-Changelog convention, so the entry lands in all of them rather than only the repo whose review happened to catch it — fixing the reported instance and leaving the class is the pattern this wave keeps undoing. The change IS user-visible, which is why it belongs here: a maintainer's `/review` on a fork PR is now declined with a warning instead of silently running, so contributors on forks see different behaviour. Refs wave-pen#418, wave-av/wave-foundation-public#73 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_34b7461f-ef40-4852-afb1-134a02091ead) |
Conflict: modify/delete on .github/workflows/pr-agent.yml — this branch repoints the reusable-workflow pin, origin/main deleted the file entirely (f767191, "ci: remove pr-agent OSS workflow (100% failing for 30 days, redundant with the review plane)", same author, dated after this PR's last update). Resolution: accept origin/main's deletion. The file called wave-av/wave-foundation/.github/workflows/reusable-pr-agent.yml, a PRIVATE repo — per PR #30's measured root-cause analysis (7 public repos / 176 runs / 100% failure calling that private reusable workflow), no pin value fixes that call for a public repo; GitHub cannot resolve a public->private reusable-workflow reference regardless of SHA vs @main. Re-adding this file with a newer pin would resurrect a structurally-broken lane that main's own later, same-author commit already retired for the same documented cause. This branch is now content-identical to origin/main on this file; this PR's change is moot post-merge.
Two conflicts: 1. .github/workflows/pr-agent.yml (modify/delete) — this branch replaces the file with a 325-line inline copy that drops the call to the private wave-foundation reusable workflow (the actual root cause this PR diagnoses: a public repo cannot resolve a `uses:` reference into a private repo). origin/main instead deleted the file outright (f767191, "ci: remove pr-agent OSS workflow (100% failing for 30 days, redundant with the review plane)"), same author, dated after this PR's last update. Resolution: accept origin/main's deletion — the maintainer's own later call was to retire the OSS pr-agent lane entirely (other review tooling already covers PRs per the checks list: cubic, Devin, Sourcery, Macroscope, semgrep), not merely to fix the private-repo reference. This branch is now content-identical to origin/main on this file; this PR's headline change is superseded. 2. CHANGELOG.md (content) — composed both sides under `## [Unreleased]`: kept this branch's "### Fixed" entry (pr-agent fork-gate + AI-timeout fixes, tracked upstream at wave-foundation-public#73) AND origin/main's "### Added" entry (`wave compose`), sequenced together rather than dropping either.
Thanks for using CodeAnt! 🎉We're free for open-source projects. if you're enjoying it, help us grow by sharing. Share on X · |
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_ca874a98-a8ea-48c7-bdce-d8f3da3b5f8f) |
User description
User description
User description
User description
Part of the fan-out tracked in wave-pen#388, proven first on wave-certify#44 where
pr_agentreturned success.The defect
pr-agent.ymlhere callswave-av/wave-foundation/.github/workflows/reusable-pr-agent.yml@main, and wave-foundation is private. GitHub does not permit a public repository to call a reusable workflow from a private one, so theuses:never resolves: the run dies before any job is created —conclusion: failure,total_count: 0, no log, and no check run on the head sha at all.That is worse than a normal failure. There is nothing to click through to. Every PR on this repo has been carrying a red check that reports nothing, and external contributors see it.
Measured on this repo today — the last 5
pr-agentruns:Measured across the org on 2026-08-22: 7 public repos / 176 runs / 100% failure; 9 private repos / zero failures. A clean 16/16 split on visibility alone. Three competing hypotheses were each tested and refuted — missing
OPENAI_KEY(present in both populations), a dead pinned ref (150ffae2resolves, file exists at it), and@mainvs a pinned sha (wave-realtime-edgepins@mainand fails,wave-penpins@mainand works).The fix already existed and was never adopted
wave-foundation-public/.github/workflows/pr-agent.ymlis an inline copy of the same lane with no reference to the private repo. Its own header says it was written for exactly this. This PR adopts it verbatim.So this is an adoption gap, not a design gap.
Why now, and not when #388 was filed
#388 named two blockers, and both are cleared as of wave-foundation-public#71:
pr-agent-${{ github.event.pull_request.number || … }}, shared betweenpull_requestandissue_comment, so any bot comment cancelled a live review ~10s in (wave-pen#386). It now keys ongithub.event_name.Fanning out before those landed would have traded a red-with-no-log lane for a cancelled-on-every-comment lane — a different failure, not a fix.
Verified before opening this
wave-foundation/mentions are in comments, not in auses:. Checked rather than assumed, since that is the whole property this depends on.pr_agent. A job's id is its check-run context and branch protection matches on(context, app_id), so nothing needs touching on the protection side.wave-foundation-public's default branch — not from a local checkout that might be parked on another branch.The receipt is this PR, not the diff
A red lane and a working lane are indistinguishable until one actually runs — that is the whole reason 176 failures went unexamined. So the proof is
pr-agentgoing green on this PR. If it does, the remaining 27 repos get the same change with evidence behind it. If it does not, we learn that here, on one low-traffic repo, instead of across the org's entire public surface.Proven before fanning out. wave-certify#44 took this exact change first and its
pr_agentrun returned success on thepull_requestevent — a job with a real log, where the broken form produced no job at all. The other repos were not changed on hope.Refs wave-pen#388
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.Note
Medium Risk
Touches CI behavior for PR reviews and fork-triggered slash commands (secret-adjacent gating), though the lane still does not checkout fork code.
Overview
Replaces the broken
pr-agentcheck that called a private reusable workflow (unresolvable from this public repo, so runs failed with no job log) with the self-contained inline lane fromwave-foundation-public, restoring a realpr_agentcheck on PRs.The adopted lane also closes three
pr-agentdefects documented in the changelog: a fail-closed fork gate onissue_commentslash commands (fork status isn’t in that payload, so job-levelif:couldn’t block forks—maintainer/reviewon fork PRs is now declined with a warning),CONFIG__AI_TIMEOUTreduced from 600s to 300s so the AI step can finish inside the step’s 360s cap, and verdict math when attempt 2 never runs (analways()end stamp no longer produces a bogus multi-year TIMED OUT).Reviewed by Cursor Bugbot for commit a2ff6f8. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by Sourcery
Restore the public repository’s pr-agent lane and harden its handling of forks, concurrency, timeouts, retries, and reviewer failures.
Bug Fixes:
Enhancements:
CI:
Documentation:
PR Type
Bug fix
Description
Replaced private workflow reference with inline pr-agent configuration
Fixed concurrency group logic to prevent job cancellation conflicts
Added fork detection mechanism for issue_comment events
Implemented retry logic with timeout management
Enhanced verdict classification for failed attempts
Diagram Walkthrough
File Walkthrough
pr-agent.yml
Complete workflow reimplementation with reliability improvements.github/workflows/pr-agent.yml
CHANGELOG.md
Updated changelog with workflow improvementsCHANGELOG.md
CodeAnt-AI Description
Make forked PR review commands safe and report timeouts correctly
What Changed
Impact
✅ Safer forked PR reviews✅ Fewer interrupted AI reviews✅ Accurate timeout results💡 Usage Guide
Checking Your Pull Request
Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.
Talking to CodeAnt AI
Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
Preserve Org Learnings with CodeAnt
You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
Check Your Repository Health
To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.