Skip to content

feat: complexity-gated AI review triggers after CR rounds (#362)#441

Merged
auerbachb merged 15 commits into
mainfrom
cursor/issue-362-complexity-ai-trigger-5429
May 7, 2026
Merged

feat: complexity-gated AI review triggers after CR rounds (#362)#441
auerbachb merged 15 commits into
mainfrom
cursor/issue-362-complexity-ai-trigger-5429

Conversation

@auerbachb
Copy link
Copy Markdown
Owner

@auerbachb auerbachb commented May 1, 2026

User description

Closes #362

Summary

Adds a measurable PR complexity score, CodeRabbit-only round counting (cycle-count.sh --cr-only), and maybe-trigger-ai-review.sh to post three separate PR comments (@codeant-ai review, @cursor review, @graphite-app re-review) when complexity + round + cadence gates pass — without batching mentions. Configuration lives in .claude/pm-config.md under Complexity triggers (env vars override file defaults when set). The polling workflow (cr-github-review.md) documents running the helper when /fixpr is not required that cycle; fixpr/pr-review-help skills note composition with post-push triggers (#370).

Review follow-up (commit b344dfd)

  • Env precedence: read pm-config.md first, then apply COMPLEXITY_THRESHOLD_SCORE, COMPLEXITY_FIRST_CR_ROUND, COMPLEXITY_CADENCE_ROUNDS, COMPLEXITY_FILE_WEIGHT when set (BugBot).
  • Idempotent / fail-closed triggers: require executable session-state.sh; persist per-step ai_review_trigger_steps to state before each gh pr comment with resume; final completion clears steps (CodeRabbit).
  • Remove unused SCRIPT_DIR in complexity-score.sh (CodeRabbit SC2034).

Calibration evidence (threshold 100)

Formula: additions + deletions + 5 × changedFiles (default FILE_WEIGHT=5).

Sample: 25 most recently merged PRs (gh pr list --state merged --limit 25). 18/25 (72%) would exceed score 100 — within the 20–80% band.

Individual scores from that sample included small PRs at 9, 18, 20, 25 (would not trigger) and larger ones 746, 530, 494 (would trigger).

Test plan

  • cycle-count.sh <PR> --cr-only runs and respects mutual exclusion with --exclude-bots
  • complexity-score.sh <PR> --json matches documented formula
  • maybe-trigger-ai-review.sh <PR> --dry-run --json evaluates gates (smoke: open PR skipped when cr_rounds_lt_2)
  • .github/scripts/rule-lint.sh passes (total words ≤ hard cap and ratchet cap)
  • CI green on this PR

Notes

  • coderabbit review --prompt-only not run (CLI not installed in this environment).
Open in Web Open in Cursor 

Summary by CodeRabbit

  • New Features

    • Complexity-gated, round-aware automated reviewer triggers that post up to three reviewer mentions plus an optional "/pr-review-help" comment.
    • New CLI tools: PR complexity scorer (numeric/JSON) and a gated AI-review trigger with dry-run/JSON modes.
    • CR-only round counting option to focus on code-review rounds.
  • Improvements

    • Trigger deduplication, usage logging, clearer exit/status codes, strict config validation, and safer multi-step posting/resume behavior.
  • Documentation

    • Updated docs for scoring, CR-only behavior, trigger flow, CLI usage, and merge verification.

CodeAnt-AI Description

Trigger AI review comments only when PRs are complex enough and have enough CodeRabbit rounds

What Changed

  • PRs can now trigger three separate review comments: @codeant-ai review, @cursor review, and @graphite-app re-review
  • Triggers now depend on a PR’s complexity score and CodeRabbit round count, instead of firing on every poll
  • cycle-count.sh can count only CodeRabbit reviews, so round-based triggering uses CR activity instead of all reviewers
  • Review thresholds and optional /pr-review-help posting can be set in repo config and overridden with environment variables

Impact

✅ Fewer unnecessary AI review comments
✅ More predictable review-trigger timing
✅ Cleaner CodeRabbit round tracking

🔄 Retrigger CodeAnt AI Review

Details

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

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

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:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

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.

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 1, 2026

Your free trial PR review limit of 100 PRs has been reached. Please upgrade your plan to continue using CodeAnt AI.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 1, 2026

@cursor review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 1, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a config-driven complexity-trigger flow: new .claude/pm-config.md, a scoring script and a gating controller (.claude/scripts/complexity-score.sh, .claude/scripts/maybe-trigger-ai-review.sh), a --cr-only mode in cycle-count.sh, integration into per-cycle polling with per-PR session-state deduplication, and supporting docs/skill updates to post deduped reviewer-trigger comments.

Changes

Complexity-triggered AI Review Flow

Layer / File(s) Summary
Configuration
.claude/pm-config.md
Adds PM config with Role, OKRs, Team, Notes and ## Complexity triggers defaults: THRESHOLD_SCORE, FIRST_CR_ROUND, CADENCE_ROUNDS, FILE_WEIGHT, ENABLE_PR_REVIEW_HELP; documents env overrides and validation constraints.
Scoring Implementation
.claude/scripts/complexity-score.sh
New CLI: validates PR number and tools, reads FILE_WEIGHT (config/env), fetches additions,deletions,changedFiles via gh, computes score = additions + deletions + file_weight × changedFiles, supports --json, logs usage, and maps errors to exit codes (including PR-not-found).
Round Counting
.claude/scripts/cycle-count.sh
Adds --cr-only (mutually exclusive with --exclude-bots); when set, reconstructs chronological review stream but treats only coderabbitai[bot] reviews as actionable and restricts inline-comment→review-ID mapping to those CR reviews.
Controller / Gating
.claude/scripts/maybe-trigger-ai-review.sh
New controller: loads pm-config/env overrides, validates constraints, computes CR_ROUNDS (cycle-count.sh --cr-only) and SCORE (complexity-score.sh), consults ~/.claude/session-state.json, enforces first-round/cadence/threshold/state gates, supports --dry-run/--json, posts up to three deduped reviewer-mention comments plus optional /pr-review-help, and persists step/last-fired markers.
Polling / Integration
.claude/rules/cr-github-review.md
Per-cycle polling retains existing /fixpr triggers; when none apply it invokes maybe-trigger-ai-review.sh <PR> (uses pm-config complexity triggers and the new scripts) and records/deduplicates AI-review trigger state under .prs[N].ai_review_trigger_*.
Documentation / Skills
README.md, .claude/scripts/README.md, .claude/skills/fixpr/SKILL.md, .claude/skills/pr-review-help/SKILL.md, .claude/rules/cr-merge-gate.md
Docs updated: scripts table entries, --cr-only semantics, complexity formula and tunable file_weight, optional automated /pr-review-help behavior, and AC re-verification wording clarified.

Sequence Diagram(s)

sequenceDiagram
    participant Poll as Polling Cycle
    participant Gate as maybe-trigger-ai-review.sh
    participant Complexity as complexity-score.sh
    participant Rounds as cycle-count.sh
    participant Config as pm-config
    participant State as session-state.json
    participant GitHub as GitHub API

    Poll->>Gate: invoked when /fixpr does not fire
    Gate->>Config: read thresholds & cadence
    Gate->>Complexity: request SCORE for PR
    Complexity->>GitHub: gh pr view (additions,deletions,changedFiles)
    GitHub-->>Complexity: PR metadata
    Complexity-->>Gate: SCORE
    Gate->>Rounds: compute CR_ROUNDS (--cr-only)
    Rounds->>GitHub: fetch reviews (filter coderabbitai[bot] if cr-only)
    GitHub-->>Rounds: CR_ROUNDS
    Gate->>State: read per-PR trigger state
    alt Gates pass
        Gate->>GitHub: post reviewer mention comments and optional /pr-review-help
        GitHub-->>Gate: comment success
        Gate->>State: update last_head_sha, last_cr_round, clear steps
    else Gates skip
        Gate-->>Poll: emit skipped status
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • codeant-ai

Poem

🐰 I count the rounds and tally score,
Three gentle nudges hop up to your door,
Configured carrots, cadence set right,
Session notes keep each hop polite,
I nibble thresholds, then I leap — review in sight.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: complexity-gated AI review triggers after CR rounds (#362)' directly and clearly describes the main feature addition: gating AI reviewer triggers based on PR complexity and CodeRabbit review rounds, and it corresponds to the primary objective of this PR.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cursor/issue-362-complexity-ai-trigger-5429

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.claude/scripts/complexity-score.sh:
- Line 20: Remove the unused variable assignment SCRIPT_DIR in the script:
locate the line that sets SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" and delete
that assignment since SCRIPT_DIR is never referenced elsewhere; ensure no other
code relies on SCRIPT_DIR (e.g., functions or calls that expect the script
directory) and run a quick lint or shellcheck to verify no leftover references
remain.

In @.claude/scripts/maybe-trigger-ai-review.sh:
- Around line 167-174: post_comments currently posts non-idempotent GH comments
before persisting dedupe state, which can cause duplicate posts on failure;
change the flow in the post_comments function to first call the session-state
persistence helper and abort (exit non-zero) if that helper fails, then only
post comments after persistence succeeds; additionally implement per-trigger
idempotency markers (unique keys per comment type) that are stored/checked via
the same session-state helper so the script skips posting if a marker already
exists, and apply the same persistence-first + idempotency-check pattern to the
other comment-posting block that mirrors post_comments.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: d11b98c1-3649-4e9c-b606-6489e78eb557

📥 Commits

Reviewing files that changed from the base of the PR and between 0c5e7d6 and 6fdedb4.

📒 Files selected for processing (9)
  • .claude/pm-config.md
  • .claude/rules/cr-github-review.md
  • .claude/scripts/README.md
  • .claude/scripts/complexity-score.sh
  • .claude/scripts/cycle-count.sh
  • .claude/scripts/maybe-trigger-ai-review.sh
  • .claude/skills/fixpr/SKILL.md
  • .claude/skills/pr-review-help/SKILL.md
  • README.md

Comment thread .claude/scripts/complexity-score.sh Outdated
Comment thread .claude/scripts/maybe-trigger-ai-review.sh Outdated
Comment thread .claude/scripts/maybe-trigger-ai-review.sh
Comment thread .claude/scripts/maybe-trigger-ai-review.sh
@auerbachb
Copy link
Copy Markdown
Owner Author

@graphite-app re-review

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 1, 2026

User cursoragent@cursor.com does not have a PR Review subscription.

Go to Team management and add this email to the PR Review subscription.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 1, 2026

@cursor review

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
.claude/scripts/maybe-trigger-ai-review.sh (1)

270-277: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Close the remaining idempotency gap after successful comment posts.

If gh pr comment succeeds but the subsequent state write fails, retry can re-post the same trigger because the step flag may still be false. Add a durable idempotency key per step (e.g., marker/comment-id lookup) before attempting a new post.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude/scripts/maybe-trigger-ai-review.sh around lines 270 - 277, The
current flow can re-post a trigger if gh pr comment succeeds but the
STATE_HELPER write fails; add a durable idempotency marker per step so we
check-and-set before posting and persist the marker after posting. Change the
logic in maybe-trigger-ai-review.sh to: 1) before calling gh pr comment, query
the session state
(.prs["${PR_KEY}"].ai_review_trigger_steps["${step_key}"].comment_id or marker)
via STATE_HELPER and skip posting if present; 2) when posting, capture the
created comment id (or response) from gh pr comment (or use gh api to
create/comment and return id); and 3) immediately persist that comment_id/marker
with STATE_HELPER (updating .prs["${PR_KEY}"].ai_review_trigger_steps to include
the marker) and treat a failed state write as a retryable error path (or delete
the created comment) so retries won’t re-post. Use the existing symbols
INIT_STEPS, step_key, PR_KEY, gh pr comment and STATE_HELPER to locate where to
add the pre-check, capture of comment id, and persistent marker write.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.claude/pm-config.md:
- Around line 1-19: Add a top-level heading to the markdown and mark the fenced
config block with a language to satisfy markdownlint (fix MD041 and MD040):
insert a heading like "## Project Management Config" at the top of the file and
change the existing fenced block that contains THRESHOLD_SCORE, FIRST_CR_ROUND,
CADENCE_ROUNDS, FILE_WEIGHT, and ENABLE_PR_REVIEW_HELP to use a language
specifier (e.g., ```ini) so the block is properly highlighted and lint-clean.

---

Duplicate comments:
In @.claude/scripts/maybe-trigger-ai-review.sh:
- Around line 270-277: The current flow can re-post a trigger if gh pr comment
succeeds but the STATE_HELPER write fails; add a durable idempotency marker per
step so we check-and-set before posting and persist the marker after posting.
Change the logic in maybe-trigger-ai-review.sh to: 1) before calling gh pr
comment, query the session state
(.prs["${PR_KEY}"].ai_review_trigger_steps["${step_key}"].comment_id or marker)
via STATE_HELPER and skip posting if present; 2) when posting, capture the
created comment id (or response) from gh pr comment (or use gh api to
create/comment and return id); and 3) immediately persist that comment_id/marker
with STATE_HELPER (updating .prs["${PR_KEY}"].ai_review_trigger_steps to include
the marker) and treat a failed state write as a retryable error path (or delete
the created comment) so retries won’t re-post. Use the existing symbols
INIT_STEPS, step_key, PR_KEY, gh pr comment and STATE_HELPER to locate where to
add the pre-check, capture of comment id, and persistent marker write.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 8ad5d3a9-769f-44f3-bfa0-15203a2148a7

📥 Commits

Reviewing files that changed from the base of the PR and between 6fdedb4 and b344dfd.

📒 Files selected for processing (3)
  • .claude/pm-config.md
  • .claude/scripts/complexity-score.sh
  • .claude/scripts/maybe-trigger-ai-review.sh

Comment thread .claude/pm-config.md
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 2, 2026

@cursor review

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

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 the current code and only fix it if needed.

Inline comments:
In @.claude/pm-config.md:
- Around line 23-27: Update the variable bullets to include the exact validation
rules enforced by the scripts: for FIRST_CR_ROUND (and env alias
COMPLEXITY_FIRST_CR_ROUND) state it must be an integer ≥ 3 (scripts error out
otherwise), for CADENCE_ROUNDS (COMPLEXITY_CADENCE_ROUNDS) state it must be an
integer ≥ 1, and for FILE_WEIGHT (COMPLEXITY_FILE_WEIGHT) state it must be a
positive integer (scripts reject 0 and non-positive values); keep the existing
semantic descriptions but append these hard constraints so readers know the
exact validation behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: d7167ab0-ed55-4074-ab7d-5ec5ca405118

📥 Commits

Reviewing files that changed from the base of the PR and between b344dfd and 64faa8d.

📒 Files selected for processing (1)
  • .claude/pm-config.md

Comment thread .claude/pm-config.md Outdated
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 2, 2026

@cursor review

Comment thread .claude/scripts/maybe-trigger-ai-review.sh
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 4, 2026

CodeAnt AI is running Incremental review

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 4, 2026

@cursor review

@codeant-ai codeant-ai Bot added the size:XL This PR changes 500-999 lines, ignoring generated files label May 4, 2026
@auerbachb
Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@auerbachb
Copy link
Copy Markdown
Owner Author

@graphite-app re-review

@auerbachb
Copy link
Copy Markdown
Owner Author

@CodeAnt-AI review

@auerbachb
Copy link
Copy Markdown
Owner Author

@cursor review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 4, 2026

✅ Actions performed

Full review triggered.

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 4, 2026

CodeAnt AI is running the review.

@auerbachb
Copy link
Copy Markdown
Owner Author

Addressed in a prior commit — env var precedence fixed in b344dfd: env overrides now applied after config-file block (lines 104–111 in current HEAD). Resolving.

@auerbachb
Copy link
Copy Markdown
Owner Author

Addressed in a prior commit — hard exit (exit 4) added at lines 227–229 in b344dfd when STATE_HELPER is not executable, matching the defensive pattern in escalate-review.sh. Resolving.

@auerbachb
Copy link
Copy Markdown
Owner Author

@coderabbitai Fixed in 72180e0: updated FIRST_CR_ROUND, CADENCE_ROUNDS, and FILE_WEIGHT bullets in pm-config.md to document the exact validation constraints enforced by the scripts (≥3, ≥1, positive integer).

@auerbachb
Copy link
Copy Markdown
Owner Author

@coderabbitai Fixed in 72180e0: post_one() now persists dedup state to session-state.sh before calling gh pr comment. If the state write fails, the function aborts (exit 4) without posting. This makes retries idempotent (fail-closed) as recommended.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 4, 2026

Tip

For best results, initiate chat on the files or code changes.

@auerbachb Thanks for the fix! Documenting the exact validation constraints (FIRST_CR_ROUND ≥ 3, CADENCE_ROUNDS ≥ 1, FILE_WEIGHT as a positive integer) directly in pm-config.md makes the configuration much clearer for anyone adjusting the thresholds.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 4, 2026

Tip

For best results, initiate chat on the files or code changes.

@auerbachb Thanks for the update! The fail-closed approach — persisting dedup state before posting and aborting with exit 4 on state-write failure — is the right pattern here. It ensures that a failed state write never silently allows a duplicate comment to be posted on retry, which is exactly what idempotent behavior requires. Looks good! ✅

@codeant-ai codeant-ai Bot removed the size:XL This PR changes 500-999 lines, ignoring generated files label May 4, 2026
@codeant-ai codeant-ai Bot added the size:XL This PR changes 500-999 lines, ignoring generated files label May 6, 2026
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 6, 2026

CodeAnt AI Incremental review completed.

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 8a95393. Configure here.

Cuts:
- cr-github-review.md "Never:" — drop redundant "Ask 'want me to poll?'"
  bullet (already covered by "Always: Enter the polling loop ... do NOT ask")
- cr-github-review.md watermark — drop "(different ID sequences)" parenthetical
- cr-merge-gate.md code-owner bots — trim explanatory aside about GitHub
  not allowing author self-approval

Word count 11023 -> 10994 (hard cap 11000).
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 6, 2026

@cursor review

@auerbachb auerbachb merged commit 09132c6 into main May 7, 2026
5 checks passed
@auerbachb auerbachb deleted the cursor/issue-362-complexity-ai-trigger-5429 branch May 7, 2026 01:05
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 9, 2026

CodeAnt AI is running the review.

@codeant-ai codeant-ai Bot added size:XL This PR changes 500-999 lines, ignoring generated files and removed size:XL This PR changes 500-999 lines, ignoring generated files labels May 9, 2026
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 9, 2026

Sequence Diagram

This PR adds a poll-time helper that combines a PR complexity score and CodeRabbit-only review round count, uses session state to gate and dedupe, and when thresholds are met posts three separate AI review comments (plus optional PR review help) on the PR.

sequenceDiagram
    participant Poller
    participant TriggerScript
    participant CycleCounter
    participant ComplexityScorer
    participant SessionState
    participant GitHub

    Poller->>TriggerScript: Run maybe-trigger-ai-review for PR
    TriggerScript->>CycleCounter: Get CodeRabbit review rounds
    TriggerScript->>ComplexityScorer: Get PR complexity score
    TriggerScript->>GitHub: Fetch current head SHA
    TriggerScript->>SessionState: Load prior trigger state and dedupe

    alt Gates pass for rounds and complexity
        TriggerScript->>SessionState: Init per step trigger flags for this SHA
        TriggerScript->>GitHub: Post separate AI reviewer comments
        TriggerScript->>SessionState: Record last fired round and clear step state
    else Gates fail
        TriggerScript-->>Poller: Return skipped with reason and metrics
    end
Loading

Generated by CodeAnt AI

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 9, 2026

CodeAnt AI finished running the review.

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 9, 2026

CodeAnt AI is running the review.

@codeant-ai codeant-ai Bot added size:XL This PR changes 500-999 lines, ignoring generated files and removed size:XL This PR changes 500-999 lines, ignoring generated files labels May 9, 2026
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 9, 2026

Sequence Diagram

This PR adds a helper that, on each CodeRabbit polling cycle without a fix run, checks PR complexity and CR-only review rounds and then posts separate AI-review trigger comments when gates pass, deduped via session state.

sequenceDiagram
    participant Poller as CR polling workflow
    participant AITrigger as maybe-trigger-ai-review
    participant GitHub as GitHub API
    participant SessionState as Session state store

    Poller->>AITrigger: Run AI review trigger for PR
    AITrigger->>GitHub: Fetch CR-only review rounds and complexity score
    AITrigger->>SessionState: Load prior trigger state for this PR and head

    alt Gates not satisfied or duplicate
        AITrigger-->>Poller: Return skipped with reason
    else Gates satisfied
        AITrigger->>SessionState: Record pending trigger steps for this PR and head
        AITrigger->>GitHub: Post separate AI review trigger comments
        AITrigger->>SessionState: Store last fired round, head, and clear steps
    end
Loading

Generated by CodeAnt AI

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 9, 2026

CodeAnt AI finished running the review.

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 10, 2026

CodeAnt AI is running the review.

@codeant-ai codeant-ai Bot added size:XL This PR changes 500-999 lines, ignoring generated files and removed size:XL This PR changes 500-999 lines, ignoring generated files labels May 10, 2026
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 10, 2026

Sequence Diagram

This PR adds a helper that, on each polling cycle without a /fixpr run, uses PR complexity and CodeRabbit-only review rounds to decide when to post separate AI review trigger comments, while tracking state to avoid duplicate posts.

sequenceDiagram
    participant Poller as Polling workflow
    participant Trigger as maybe-trigger-ai-review.sh
    participant Cycle as cycle-count.sh
    participant Score as complexity-score.sh
    participant State as Session state
    participant GitHub

    Poller->>Trigger: Run maybe-trigger-ai-review.sh for PR
    Trigger->>Trigger: Load complexity config from pm-config and env
    Trigger->>Cycle: Get CodeRabbit-only cycle count
    Cycle-->>Trigger: Return CR rounds
    Trigger->>Score: Compute PR complexity score
    Score-->>Trigger: Return complexity score
    Trigger->>State: Read last trigger state for PR and head sha
    Trigger->>State: Initialize per-step trigger state for this PR and head
    Trigger->>GitHub: Post separate comments for codeant, cursor, graphite and optional pr-review-help
    Trigger->>State: Record completed trigger metadata and clear per-step state
Loading

Generated by CodeAnt AI

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 10, 2026

CodeAnt AI finished running the review.

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 10, 2026

CodeAnt AI is running the review.

@codeant-ai codeant-ai Bot added size:XL This PR changes 500-999 lines, ignoring generated files and removed size:XL This PR changes 500-999 lines, ignoring generated files labels May 10, 2026
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 10, 2026

Sequence Diagram

This PR adds a helper that, on each polling cycle without a /fixpr run, uses PR complexity and CodeRabbit-only review rounds to decide whether to post three separate AI reviewer comments, while deduplicating triggers via session state.

sequenceDiagram
    participant Poller
    participant AITrigger
    participant CycleCounter
    participant ComplexityScorer
    participant SessionState
    participant GitHubPR

    Poller->>AITrigger: maybe-trigger-ai-review for PR
    AITrigger->>CycleCounter: Get CodeRabbit-only cycle count
    CycleCounter-->>AITrigger: Return CR rounds
    AITrigger->>ComplexityScorer: Get PR complexity score
    ComplexityScorer-->>AITrigger: Return score
    AITrigger->>SessionState: Load last trigger state for PR and head

    alt Gates satisfied and not previously triggered
        AITrigger->>SessionState: Initialize step tracking for this PR and head
        AITrigger->>GitHubPR: Post separate AI review comments (codeant, cursor, graphite, optional pr-review-help)
        GitHubPR-->>AITrigger: Confirm comments created
        AITrigger->>SessionState: Persist last trigger round and head, clear step tracking
    else Gates not satisfied or duplicate
        AITrigger-->>Poller: Report skipped with reason (rounds or complexity)
    end
Loading

Generated by CodeAnt AI

PM_CFG=""
[[ -n "$REPO_ROOT" && -f "$REPO_ROOT/.claude/pm-config.md" ]] && PM_CFG="$REPO_ROOT/.claude/pm-config.md"
if [[ -n "$PM_CFG" ]]; then
section=$(awk '/^## Complexity triggers/,/^## / { if (/^## Complexity triggers/) next; if (/^## /) exit; print }' "$PM_CFG" 2>/dev/null || true)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: The section extractor uses an awk range that starts at ## Complexity triggers and also ends on any ## ... header, so it terminates on the same header line and returns an empty section. That makes FILE_WEIGHT from pm-config.md effectively unreadable, so repo config is silently ignored unless env override is set. Change the section parsing to skip the first matching header and stop only on the next header. [incorrect condition logic]

Severity Level: Major ⚠️
- ⚠️ PR complexity score ignores FILE_WEIGHT in pm-config.
- ⚠️ maybe-trigger thresholds rely on default file weight only.
Steps of Reproduction ✅
1. Open `.claude/pm-config.md` and observe the `## Complexity triggers` section with an
`ini` block defining `FILE_WEIGHT`, e.g. at lines 11–21 (`FILE_WEIGHT=5`) in
`/workspace/claude-code-config/.claude/pm-config.md`.

2. Note that `.claude/scripts/complexity-score.sh` attempts to read that section at line
62 via `section=$(awk '/^## Complexity triggers/,/^## / { if (/^## Complexity triggers/)
next; if (/^## /) exit; print }' "$PM_CFG" ...)`.

3. Consider how awk range patterns work: the range `/^## Complexity triggers/,/^## /`
starts on the `## Complexity triggers` header line and ends on the first line matching
`^## `; for this file the *same* header line matches both patterns, so the range is active
only for that single record, and awk's range logic turns the range off immediately after
that record.

4. On the header line, the inner awk block executes `if (/^## Complexity triggers/)
next;`, which skips printing the header, and because the range ends on that same line, no
lines from the fenced `ini` block (including `FILE_WEIGHT=...`) are ever in-range;
`section` is therefore always empty, so `FILE_WEIGHT` from `pm-config.md` is never applied
and the script always uses the default `FILE_WEIGHT=5` unless `COMPLEXITY_FILE_WEIGHT` is
set.

Fix in Cursor | Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** .claude/scripts/complexity-score.sh
**Line:** 62:62
**Comment:**
	*Incorrect Condition Logic: The section extractor uses an awk range that starts at `## Complexity triggers` and also ends on any `## ...` header, so it terminates on the same header line and returns an empty section. That makes `FILE_WEIGHT` from `pm-config.md` effectively unreadable, so repo config is silently ignored unless env override is set. Change the section parsing to skip the first matching header and stop only on the *next* header.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

parse_pm_kv() {
local key="$1"
local section
section=$(awk '/^## Complexity triggers/,/^## / { if (/^## Complexity triggers/) next; if (/^## /) exit; print }' "$PM_CFG" 2>/dev/null || true)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: The same awk range logic for Complexity triggers ends immediately on the section header, so config keys are never actually parsed from pm-config.md. This causes threshold/cadence settings in repo config to be ignored and the script to run with defaults unless environment variables are set. Use a parser that captures lines after the header until the next header. [incorrect condition logic]

Severity Level: Major ⚠️
- ⚠️ AI review gating ignores pm-config thresholds and cadence.
- ⚠️ Dry-run JSON reports default, not configured, thresholds.
Steps of Reproduction ✅
1. Inspect `.claude/pm-config.md` at lines 11–21 and see the `## Complexity triggers`
section with `THRESHOLD_SCORE`, `FIRST_CR_ROUND`, `CADENCE_ROUNDS`, `FILE_WEIGHT`, and
`ENABLE_PR_REVIEW_HELP` defined in an `ini` block.

2. In `.claude/scripts/maybe-trigger-ai-review.sh`, notice `parse_pm_kv` at lines 77–89,
which uses the same awk range expression as `complexity-score.sh`: `section=$(awk '/^##
Complexity triggers/,/^## / { if (/^## Complexity triggers/) next; if (/^## /) exit; print
}' "$PM_CFG" ...)`.

3. Because awk range `/^## Complexity triggers/,/^## /` starts and ends on the same header
line (the line matches both `^## Complexity triggers` and `^## `), the range is active
only for that line; the `if (/^## Complexity triggers/) next;` inside the block skips it,
so no lines from the fenced `ini` block (where `THRESHOLD_SCORE`, etc. are declared) are
ever printed into `section`, leaving `section` empty.

4. When running `./.claude/scripts/maybe-trigger-ai-review.sh <pr> --dry-run --json` with
environment overrides unset, `parse_pm_kv` returns no values (because `section` is empty),
so the main script (lines 91–111) leaves `THRESHOLD_SCORE`, `FIRST_CR_ROUND`, and
`CADENCE_ROUNDS` at their hard-coded defaults instead of using the values from
`.claude/pm-config.md`, meaning repository trigger settings in config are effectively
ignored.

Fix in Cursor | Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** .claude/scripts/maybe-trigger-ai-review.sh
**Line:** 80:80
**Comment:**
	*Incorrect Condition Logic: The same awk range logic for `Complexity triggers` ends immediately on the section header, so config keys are never actually parsed from `pm-config.md`. This causes threshold/cadence settings in repo config to be ignored and the script to run with defaults unless environment variables are set. Use a parser that captures lines after the header until the next header.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented May 10, 2026

CodeAnt AI finished running the review.

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

Labels

size:XL This PR changes 500-999 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Auto-trigger Code Review on complex PRs after 2+ CR rounds

2 participants