Skip to content

fix(triggers): pr-opened trigger respects reviewTrigger author modes#524

Merged
zbigniewsobiecki merged 1 commit intodevfrom
fix/pr-opened-respect-review-trigger-config
Feb 24, 2026
Merged

fix(triggers): pr-opened trigger respects reviewTrigger author modes#524
zbigniewsobiecki merged 1 commit intodevfrom
fix/pr-opened-respect-review-trigger-config

Conversation

@zbigniewsobiecki
Copy link
Copy Markdown
Member

Summary

  • Gate PROpenedTrigger.matches() on ownPrsOnly/externalPrs — same pattern as CheckSuiteSuccessTrigger. When neither mode is active, the trigger won't match even if prOpened: true.
  • Replace blanket isCascadeBot skip in handle() with author-based filtering — implementer-authored PRs fire only when ownPrsOnly is enabled; external PRs fire only when externalPrs is enabled.
  • Add --pr-opened flag to review-trigger-set CLI — all review-adjacent triggers manageable from one command.
  • Update dashboard trigger description to note that PR Opened respects Own PRs / External PRs modes.

Motivation

PR #522 (a human-authored dev → main merge) triggered respond-to-review even though reviewTrigger was configured as { ownPrsOnly: true, externalPrs: false }. Root cause: PROpenedTrigger was gated only by the prOpened boolean and ignored reviewTrigger entirely.

Test plan

  • 20 unit tests (9 matches + 11 handle) covering all mode combinations
  • Full suite: 183 files, 3049 tests passing
  • npm run typecheck clean
  • npm run lint clean

🤖 Generated with Claude Code

PROpenedTrigger was gated only by the `prOpened` boolean, ignoring the
`reviewTrigger` config entirely. This caused respond-to-review to fire
on every non-bot PR — even when `externalPrs: false`.

Gate matches() on ownPrsOnly/externalPrs (same as CheckSuiteSuccessTrigger)
and replace the blanket isCascadeBot skip in handle() with author-based
filtering that respects both modes.

Also adds --pr-opened flag to the review-trigger-set CLI command so all
review-adjacent triggers can be managed from one place.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@aaight
Copy link
Copy Markdown
Collaborator

aaight commented Feb 24, 2026

🤔 Just a sec, looking into that pr-opened trigger fix now

@aaight
Copy link
Copy Markdown
Collaborator

aaight commented Feb 24, 2026

Thanks for taking a look! Let me know if you have any questions or feedback on the implementation.

The key changes are:

  • PROpenedTrigger.matches() now gates on reviewTrigger config (same pattern as CheckSuiteSuccessTrigger)
  • handle() filters PRs by author based on ownPrsOnly/externalPrs modes
  • Added --pr-opened flag to the review-trigger-set CLI command
  • 20 new unit tests covering all mode combinations

All tests passing and the implementation follows the existing patterns from the review trigger refactor.

@aaight
Copy link
Copy Markdown
Collaborator

aaight commented Feb 24, 2026

🤔 Just a sec, looking into that PR review now

Copy link
Copy Markdown
Collaborator

@nhopeatall nhopeatall left a comment

Choose a reason for hiding this comment

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

Summary

LGTM — Clean bug fix that aligns PROpenedTrigger with the existing CheckSuiteSuccessTrigger pattern for respecting reviewTrigger author modes.

What I verified:

  1. Pattern consistency: The matches() gate (!ownPrsOnly && !externalPrs → false) and handle() author filtering logic are structurally identical to CheckSuiteSuccessTrigger (lines 72–76 and 102–121 respectively). No new patterns introduced.

  2. Legacy compatibility: The legacy fallback in resolveReviewTriggerConfig defaults ownPrsOnly: true when no reviewTrigger is present (via checkSuiteSuccess ?? true), so existing projects with { prOpened: true } and no explicit reviewTrigger continue to match. Covered by the "legacy config" test.

  3. Behavioral change — personaIdentities undefined: Previously, missing personaIdentities caused the trigger to fire for all PRs (graceful degradation). Now it returns null. This is intentionally more conservative and matches CheckSuiteSuccessTrigger's behavior. Correct tradeoff — silent trigger fires when identity resolution fails were the root cause of the bug described in PR #522.

  4. Reviewer persona handling: The old isCascadeBot check would skip PRs from both implementer AND reviewer personas. The new code only checks against the implementer login — reviewer-authored PRs are treated as "external" when externalPrs is enabled. This is correct: the reviewer persona authoring a PR is not the implementer, so the respond-to-review agent should fire on it. Test coverage exists for this case.

  5. CLI change: --pr-opened correctly sends prOpened as a top-level key in the triggers payload (not nested under reviewTrigger), matching the GitHubTriggerConfigSchema structure. The updateTriggers mutation's z.record(z.union([z.boolean(), z.record(z.boolean())])) schema accepts this shape.

  6. Tests: 20 tests all pass, covering all mode combinations including both-modes, neither-mode, legacy, and missing identities.

@zbigniewsobiecki zbigniewsobiecki merged commit a6ca287 into dev Feb 24, 2026
5 checks passed
@zbigniewsobiecki zbigniewsobiecki deleted the fix/pr-opened-respect-review-trigger-config branch March 16, 2026 16:43
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.

3 participants