ci: adopt the inline pr-agent lane — a public repo cannot call a private reusable workflow

YA
16d ago
+351-6

User description

User description

User description

Part of the fan-out tracked in wave-pen#388, proven first on wave-certify#44 where pr_agent returned success.

The defect

pr-agent.yml here calls wave-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 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 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-agent runs:

failure, failure, failure, failure, failure

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 (150ffae2 resolves, file exists at it), and @main vs a pinned sha (wave-realtime-edge pins @main and fails, wave-pen pins @main and works).

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. 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:

  1. The shared concurrency key. The template carried pr-agent-${{ github.event.pull_request.number || … }}, shared between pull_request and issue_comment, so any bot comment cancelled a live review ~10s in (wave-pen#386). It now keys on github.event_name.
  2. Missing step-level timeouts. The template now carries 6.

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

  • The template is genuinely self-contained. Its only two wave-foundation/ mentions are in comments, not in a uses:. Checked rather than assumed, since that is the whole property this depends on.
  • The job id stays 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.
  • The workflow parses, and the source was read from a fresh clone of 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-agent going 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_agent run returned success on the pull_request event — 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

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.


[!NOTE]
Medium Risk
CI-only, but the job holds OPENAI_KEY and write access to PRs. Fail-closed fork gating and advisory (non-blocking) verdicts reduce blast radius; a workflow bug can still skip reviews or spend the LLM key.

Overview
Replaces the uses: of private wave-foundation reusable pr-agent with an inline Qodo Merge job. Public repos cannot call a private reusable workflow, so the old lane failed with zero jobs and no check log.

Concurrency now keys on event name plus pr-vs-issue, so comments no longer cancel in-flight push reviews and issue comments no longer collide with same-numbered PRs.

Adds a fail-closed fork gate on slash commands (the issue_comment payload has no fork flag), member-only / commands, a 6-minute per-attempt timeout with CONFIG__AI_TIMEOUT at 300s, one retry after 45s, and a verdict step that classifies timeout/cancel/429 and never blocks the PR. /review on fork PRs is now declined.

Reviewed by Cursor Bugbot for commit 6ef66e1b9d6507478e7c293581cc16a0fd489207. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by Sourcery

Adopt a self-contained, guarded PR-agent workflow so public-repository reviews run reliably without exposing credentials or blocking pull requests on advisory-agent failures.

Bug Fixes:

  • Replace the unusable private reusable workflow reference with a self-contained PR-agent lane for public repositories.
  • Prevent fork-originated reviews and untrusted slash commands from using the workflow's credentials.
  • Ensure agent timeouts, retries, and incomplete attempts are classified safely without blocking pull requests.

Enhancements:

  • Separate concurrency for pull requests and issue comments so unrelated events do not cancel active reviews.
  • Improve advisory PR-agent resilience through bounded retries, model timeouts, and neutral handling of reviewer failures.

PR Type

Bug fix, Enhancement


Description

  • Replaced private workflow reference with inline public workflow

  • Fixed fork handling and added explicit fork validation

  • Added retry logic with timeout management

  • Improved error classification and logging


Diagram Walkthrough

flowchart LR
  A[".github/workflows/pr-agent.yml"] --> B["Inline workflow adoption"]
  A --> C["Fork validation improvements"]
  A --> D["Retry logic with timeout management"]
  A --> E["Enhanced error classification"]

File Walkthrough

Relevant files
Enhancement
pr-agent.ymlInline workflow adoption with enhanced fork handling         

.github/workflows/pr-agent.yml

  • Replaced private workflow reference with inline public workflow
  • Added explicit fork validation via pulls endpoint
  • Implemented retry logic with 45s backoff between attempts
  • Added detailed timeout management and error classification
+325/-6 
Documentation
CHANGELOG.mdUpdate changelog with workflow improvements                           

CHANGELOG.md

  • Added entry for pr-agent workflow fixes
  • Documented fork handling improvements
  • Noted timeout configuration changes
  • Recorded retry logic implementation
+26/-0