Skip to content

ci: enroll this repo in its own cursor-review and unreviewed-merge gates#37

Merged
mattmillerai merged 2 commits into
mainfrom
self-enroll-ci-gates
Jul 19, 2026
Merged

ci: enroll this repo in its own cursor-review and unreviewed-merge gates#37
mattmillerai merged 2 commits into
mainfrom
self-enroll-ci-gates

Conversation

@mattmillerai

@mattmillerai mattmillerai commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

What

github-workflows ships the org's cursor-review panel, its unreviewed-merge detector, and (since #34) the AGENTS.md integrity check — and consumed none of them on itself. PRs here (e.g. #34, #36) merge with no AI review, no approval requirement, and no compliance trail, in the one repo whose files become every other repo's required checks. This enrolls the repo in its own gates:

  • ci-cursor-review.yml — SHA-pinned to this repo's own merged main, exactly like an external consumer. A local uses: ./… path would run the PR's own copy of the reviewer, letting a PR weaken the panel judging it — pinning keeps the reviewer tamper-proof. Label-triggered for now (the pinned gate only honors label events — verified live on this PR's first push, where a direct trigger ran the shell and skipped the panel).
  • cursor-review.yml gains an opt-in run_without_label input (default false — zero change for existing callers): plain PR events fire the panel, with the fork skip, skip-cursor-review veto, and same-commit dedupe still applying. Once the auto-bump advances this repo's own pin past this merge, the bump PR should flip the caller to run_without_label: true and widen its trigger types (noted in the caller header) — this repo has no labeling automation.
  • ci-detect-unreviewed-merge.yml — verbatim copy of the canonical template from Comfy-Org/unreviewed-merges/detector/, renamed because the canonical filename is occupied here by the reusable itself. Operator step remaining: provision secrets.UNREVIEWED_MERGES_TOKEN — until then the job fails loudly on pushes to main (deliberate: enrollment should never be silently inert).

Housekeeping already done outside this PR: CURSOR_API_KEY repo secret provisioned; repo added to CURSOR_REVIEW_CALLERS (13 entries).

🤖 Generated with Claude Code

github-workflows ships the org's review panel, unreviewed-merge detector,
and AGENTS.md integrity check — and until now consumed none of them: PRs
here merged with no AI review and no compliance trail, in the one repo
whose files become every other repo's required checks.

Adds two thin callers, SHA-pinned like any external consumer (a local
uses: path would run the PR's own copy of the reviewer — pinning keeps
the panel tamper-proof):

- ci-cursor-review.yml — direct pull_request trigger (no label dance;
  every non-draft PR here is worth a review). CURSOR_API_KEY is already
  provisioned.
- ci-detect-unreviewed-merge.yml — verbatim template copy, renamed
  because the canonical path hosts the reusable itself. Needs
  UNREVIEWED_MERGES_TOKEN before it goes green; fails loudly until then.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 22 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: d14b97ba-8275-4405-bbd6-55e83b9dc94d

📥 Commits

Reviewing files that changed from the base of the PR and between fe6b08e and f301ba6.

📒 Files selected for processing (3)
  • .github/workflows/ci-cursor-review.yml
  • .github/workflows/ci-detect-unreviewed-merge.yml
  • .github/workflows/cursor-review.yml
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch self-enroll-ci-gates
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch self-enroll-ci-gates

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

@mattmillerai mattmillerai added the cursor-review Multi-model cursor review label Jul 19, 2026
… reusable gate

The gate only honors label events, so the self-caller's direct
pull_request trigger ran the shell and skipped the panel (verified live
on this PR's first push). Two-step fix, pin-ordering aware:

- cursor-review.yml gains an opt-in `run_without_label` input (default
  false — zero behavior change for existing callers): plain PR events
  (opened/reopened/ready_for_review/synchronize) fire the panel, with
  the fork skip, skip-cursor-review veto, and same-commit dedupe all
  still applying. For repos with no labeling automation.
- ci-cursor-review.yml switches to the sibling label-triggered shape,
  which works at its current pin (the pinned SHA predates the new
  input, so passing it would be an invalid-input error). When the
  auto-bump advances the pin past this commit, the bump PR should add
  `run_without_label: true` and widen the trigger types — noted in the
  file header.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@mattmillerai mattmillerai added cursor-review Multi-model cursor review and removed cursor-review Multi-model cursor review labels Jul 19, 2026
@mattmillerai
mattmillerai merged commit 377f7e1 into main Jul 19, 2026
14 of 20 checks passed
@mattmillerai
mattmillerai deleted the self-enroll-ci-gates branch July 19, 2026 02:02

@github-actions github-actions 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.

🔍 Cursor Review — Consolidated panel

Triggered by @mattmillerai.

Found 7 finding(s).

Severity Count
🟡 Medium 5
🟢 Low 2

Panel: 6/8 reviewers contributed findings.

Reviewers that did not contribute: kimi-k2.5:adversarial (empty), kimi-k2.5:edge-case (empty)

# veto — and the same-commit dedupe below still prevents re-reviews.
if [ "$RUN_WITHOUT_LABEL" = "true" ]; then
case "$GH_EVENT_ACTION" in
opened|reopened|ready_for_review|synchronize)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Medium — In run_without_label mode the gate matches opened/synchronize (plus reopened/ready_for_review) with no github.event.pull_request.draft check, and GitHub fires opened/synchronize for draft PRs. Enrolled repos will run the full 8-cell panel + judge on every draft and every push to a draft, burning paid CURSOR_API_KEY quota and contradicting the caller comment's stated 'every non-draft PR' intent. Add a draft guard (or force callers to trigger only on ready_for_review). Raised by 5 of 8 reviewers (claude-opus-4-8-thinking-max adversarial, gemini-3.1-pro adversarial, gpt-5.6-sol-max edge-case, claude-opus-4-8-thinking-max edge-case, gemini-3.1-pro edge-case).

# removed or re-applied. Scoping by label name ensures that removing an
# unrelated label does not kill a running cursor review.
concurrency:
group: cursor-review-pr-${{ github.event.pull_request.number }}-${{ github.event.label.name }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Medium — The concurrency group embeds github.event.label.name, so a run started by the cursor-review label (group ...-cursor-review) and the labeled event adding skip-cursor-review (group ...-skip-cursor-review) fall into different groups. With cancel-in-progress: true the veto label therefore cannot cancel an already-running review, which keeps consuming secrets and posts anyway. In run_without_label mode it is worse: non-label events like synchronize produce an empty label segment (...-) that won't serialize against label events either. Raised by 3 of 8 reviewers (gpt-5.6-sol-max adversarial, gemini-3.1-pro edge-case, gpt-5.6-sol-max edge-case).

# label events. Once the pin advances past the commit adding the reusable's
# `run_without_label` input, the auto-bump PR for this file should also add
# `run_without_label: true` under `with:` and widen the trigger types to
# [opened, reopened, ready_for_review, labeled, unlabeled] — this repo has no

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Medium — The recommended future trigger list [opened, reopened, ready_for_review, labeled, unlabeled] omits synchronize, yet the reusable's run_without_label gate and the run_without_label input description both explicitly support synchronize. Because specifying types overrides GitHub's defaults, an auto-bump PR that applies this guidance would never re-review new commits pushed to an open PR, leaving the latest code unanalyzed. Raised by 3 of 8 reviewers (gpt-5.6-sol-max adversarial, gemini-3.1-pro edge-case, gpt-5.6-sol-max edge-case).

# labeling automation opt in to running on plain PR events. Sits
# BELOW the fork skip and skip-cursor-review checks — those still
# veto — and the same-commit dedupe below still prevents re-reviews.
if [ "$RUN_WITHOUT_LABEL" = "true" ]; then

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Medium — Same-repo Dependabot PRs pass the fork check, but GitHub withholds Actions secrets and downgrades GITHUB_TOKEN for Dependabot events. When a caller enables run_without_label, this branch sets should_run=true for Dependabot opened/synchronize events, so the panel runs with an empty CURSOR_API_KEY and the review job fails on every Dependabot update — blocking merges if it is a required check. Raised by 1 of 8 reviewers (gpt-5.6-sol-max adversarial).

:!**/*-lock.json
:!**/dist/**
secrets:
CURSOR_API_KEY: ${{ secrets.CURSOR_API_KEY }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Medium — CURSOR_API_KEY is handed to a cursor-agent --trust process that ingests attacker-controlled same-repository PR content; the fork check only blocks forks, not same-repo contributors. A contributor who can push a branch (and, in label mode, apply the trigger label) could use prompt injection or a malicious workspace config to execute commands and exfiltrate the key — a risk run_without_label broadens by auto-triggering on any same-repo PR. Raised by 1 of 8 reviewers (gpt-5.6-sol-max adversarial).

# BELOW the fork skip and skip-cursor-review checks — those still
# veto — and the same-commit dedupe below still prevents re-reviews.
if [ "$RUN_WITHOUT_LABEL" = "true" ]; then
case "$GH_EVENT_ACTION" in

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟢 Low — In run_without_label mode this case handles only opened/reopened/ready_for_review/synchronize, so an unlabeled event (e.g. removing skip-cursor-review to unblock a PR) falls through to the legacy check that requires labeled + the trigger label and no-ops. Since the recommended trigger types include unlabeled, removing the veto label silently fails to re-trigger a review until another qualifying event occurs. Raised by 3 of 8 reviewers (gpt-5.6-sol-max adversarial, gemini-3.1-pro edge-case, gpt-5.6-sol-max edge-case).

# labeling automation opt in to running on plain PR events. Sits
# BELOW the fork skip and skip-cursor-review checks — those still
# veto — and the same-commit dedupe below still prevents re-reviews.
if [ "$RUN_WITHOUT_LABEL" = "true" ]; then

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟢 Low — run_without_label lets multiple activity types fire on one HEAD SHA (e.g. opened then synchronize, or open-as-draft then ready_for_review); the same-commit dedupe is a separate, non-atomic step, so two near-simultaneous events can both pass it (neither has posted yet) and emit duplicate reviews. The reusable defines no concurrency of its own and the example caller group keyed on github.event.label.name is empty for these non-label events, so rapid synchronize pushes can also queue unbounded expensive panels — run_without_label callers need explicit concurrency guidance. Raised by 2 of 8 reviewers (claude-opus-4-8-thinking-max adversarial, claude-opus-4-8-thinking-max edge-case).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cursor-review Multi-model cursor review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant