Skip to content

t1392: Fix CodeRabbit sweep unconditional trigger on first run#2833

Closed
alex-solovyev wants to merge 1 commit intomainfrom
bugfix/t1392-coderabbit-sweep-conditional
Closed

t1392: Fix CodeRabbit sweep unconditional trigger on first run#2833
alex-solovyev wants to merge 1 commit intomainfrom
bugfix/t1392-coderabbit-sweep-conditional

Conversation

@alex-solovyev
Copy link
Collaborator

@alex-solovyev alex-solovyev commented Mar 4, 2026

Summary

  • Fixes CodeRabbit @coderabbitai review request firing unconditionally on the first sweep after PR t1390: Make CodeRabbit sweep conditional on quality gate changes #2808 merged
  • Root cause: _load_sweep_state() returns UNKNOWN|0|0 when no state file exists, causing delta computation against zero to treat the entire existing issue count (e.g., 113) as a "spike" (+113 >= threshold of 10)
  • Fix: when prev_gate == "UNKNOWN", treat the sweep as a baseline-setting run — save current metrics and skip delta triggers

Root Cause Analysis

PR #2808 (t1390) added conditional logic correctly, but missed the first-run edge case:

prev_issues = 0  (no state file)
sweep_total_issues = 113  (current SonarCloud count)
issue_delta = 113 - 0 = 113  (>= CODERABBIT_ISSUE_SPIKE of 10)
→ trigger_active = true  (false positive!)

The same applies to high_critical_delta: any existing high/critical issues appear as "new" on first run.

Fix

Added a guard at the top of the CodeRabbit trigger section:

if [[ "$prev_gate" == "UNKNOWN" ]]; then
    # First run — baseline, skip triggers
else
    # Normal delta computation
fi

The _save_sweep_state() call at the end still runs, so the next sweep has a real baseline to compare against.

Verification

  • ShellCheck: zero violations
  • Bash syntax check: passes
  • 10 functional tests pass:
    1. First run returns UNKNOWN baseline
    2. Save/reload state works
    3. First run produces BASELINE (not ACTIVE_TRIGGER) — the bug fix
    4. Stable metrics produce MONITORING
    5. Issue spike (+15) triggers ACTIVE_TRIGGER
    6. Quality gate ERROR triggers ACTIVE_TRIGGER
    7. New high/critical findings trigger ACTIVE_TRIGGER
    8. Exact bug reproduction (113 issues, no state file) → BASELINE

Closes #2832

Summary by CodeRabbit

  • Bug Fixes
    • Fixed baseline metrics initialization on first run to prevent inaccurate delta calculations when no previous state exists.
    • Improved state persistence to ensure proper metric tracking and trigger evaluation across subsequent runs.

…te exists (t1392)

On first run (or after state file deletion), _load_sweep_state() returns
prev_gate=UNKNOWN with prev_issues=0. The delta computation then treats
the entire existing issue count as a 'spike' (e.g., 113 - 0 = +113),
unconditionally triggering @coderabbitai review — the exact regression
reported after PR #2808 merged.

Fix: when prev_gate is UNKNOWN, treat the sweep as a baseline-setting
run — save current metrics and post a passive monitoring line. Delta
triggers only fire from the second sweep onward, when a real previous
state exists to compare against.

Verified: 10 functional tests pass (baseline, stable, spike, gate fail,
high/critical, exact bug reproduction scenario).
@github-actions github-actions bot added the bug Auto-created from TODO.md tag label Mar 4, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 4, 2026

Walkthrough

The change fixes a regression in the CodeRabbit sweep trigger logic by introducing baseline behavior on first run to prevent unconditional trigger posting. When no prior state exists, the script saves current metrics as baseline and skips delta-based triggers. Subsequent runs compute deltas and apply existing trigger conditions only when metrics change significantly.

Changes

Cohort / File(s) Summary
CodeRabbit Sweep Baseline & Trigger Logic
.agents/scripts/pulse-wrapper.sh
Introduced baseline guard when prev_gate is UNKNOWN; conditional delta computation (issue_delta, high_critical_delta) only on non-baseline runs; trigger activation and CodeRabbit posting only when baseline guard passes and metrics warrant it; state persisted via _save_sweep_state after processing each repo to ensure correct deltas on future runs.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • #2808: Introduced the conditional CodeRabbit trigger logic that this PR extends with baseline handling and refined delta computation.
  • #2631: Original PR that added the daily multi-tool sweep and CodeRabbit integration that this fix refines.
  • #2823: Related changes to the same CodeRabbit sweep variables and state persistence logic in pulse-wrapper.sh.

Suggested labels

bug

Poem

🐇 A baseline stands firm on first run's ground,
No phantom deltas where none can be found,
The sweep now stays silent when metrics align,
CodeRabbit won't bark at a perfectly fine line.
State flows through the script like water downstream,
Keeping the DevOps automation pristine! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: fixing an unconditional CodeRabbit trigger on first run, directly addressing issue #2832.
Linked Issues check ✅ Passed The pull request implements all requirements from issue #2832: baseline detection on first run, conditional trigger logic on subsequent runs, and verified testing including the exact bug scenario.
Out of Scope Changes check ✅ Passed All changes in pulse-wrapper.sh are directly scoped to fixing the first-run unconditional trigger issue and implementing baseline logic, with no unrelated modifications.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bugfix/t1392-coderabbit-sweep-conditional

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions
Copy link

github-actions bot commented Mar 4, 2026

🔍 Code Quality Report

�[0;35m[MONITOR]�[0m Code Review Monitoring Report

�[0;34m[INFO]�[0m Latest Quality Status:
SonarCloud: 0 bugs, 0 vulnerabilities, 107 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Wed Mar 4 16:27:02 UTC 2026: Code review monitoring started
Wed Mar 4 16:27:03 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 107

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 107
  • VULNERABILITIES: 0

Generated on: Wed Mar 4 16:27:06 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

@gemini-code-assist
Copy link

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a critical bug in the CodeRabbit integration that caused it to incorrectly trigger an active review on its initial execution within a repository. By correctly identifying and handling the first run as a baseline establishment, the system now accurately monitors for actual quality degradation, preventing unnecessary review requests and improving the efficiency of the automated review process.

Highlights

  • CodeRabbit Trigger Fix: Resolved an issue where CodeRabbit's review request would trigger unconditionally on the first sweep after PR t1390: Make CodeRabbit sweep conditional on quality gate changes #2808 was merged.
  • Root Cause Identified: The problem stemmed from _load_sweep_state() returning 'UNKNOWN|0|0' when no state file existed, leading to a false-positive 'spike' in issue count when calculating deltas against zero.
  • Baseline Handling Implemented: Introduced a fix to treat sweeps where prev_gate is 'UNKNOWN' as a baseline-setting run, saving current metrics and explicitly skipping delta-based triggers.
Changelog
  • .agents/scripts/pulse-wrapper.sh
    • Updated comments to include reference to t1392 and explain the first-run issue.
    • Introduced a conditional block to check for an 'UNKNOWN' previous gate status, designating it as a baseline run.
    • Moved the delta calculation and CodeRabbit trigger conditions into an 'else' block, ensuring they only execute after a baseline has been established.
Activity
  • The pull request includes 10 functional tests that pass, verifying the fix.
  • The fix specifically addresses the exact bug reproduction scenario (113 issues, no state file) resulting in a BASELINE status.
  • ShellCheck and Bash syntax checks passed with zero violations.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@sonarqubecloud
Copy link

sonarqubecloud bot commented Mar 4, 2026

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request effectively addresses a bug causing unconditional CodeRabbit triggers on the first sweep run. The fix, which involves detecting the first run and setting a baseline instead of computing deltas against zero, is logical and well-implemented. The code is clearer and more robust as a result. I have one minor suggestion to improve maintainability by refining variable scope.

Comment on lines 1913 to +1928
local trigger_active=false
local trigger_reasons=""

# Condition 1: Quality gate is failing
if [[ "$sweep_gate_status" == "ERROR" || "$sweep_gate_status" == "WARN" ]]; then
trigger_active=true
trigger_reasons="quality gate ${sweep_gate_status}"
fi
if [[ "$prev_gate" == "UNKNOWN" ]]; then
# First run — no previous state to compare against. Treat as baseline:
# save current metrics and post a passive monitoring line. Without this
# guard, delta computation against zero fires false-positive triggers
# (e.g., 113 existing issues - 0 = +113 "spike"). (t1392)
coderabbit_section="### CodeRabbit

# Condition 2: Issue count spiked by threshold or more
if [[ "$issue_delta" -ge "$CODERABBIT_ISSUE_SPIKE" ]]; then
trigger_active=true
if [[ -n "$trigger_reasons" ]]; then
trigger_reasons="${trigger_reasons}, issue spike +${issue_delta}"
else
trigger_reasons="issue spike +${issue_delta}"
_Baseline run: recording ${sweep_total_issues} issues, gate ${sweep_gate_status}, ${sweep_high_critical} high/critical. Deltas will be computed from next sweep._
"
echo "[pulse-wrapper] CodeRabbit: baseline run for ${repo_slug} — saving state, skipping triggers" >>"$LOGFILE"
else
local issue_delta=$((sweep_total_issues - prev_issues))
local high_critical_delta=$((sweep_high_critical - prev_high_critical))

Choose a reason for hiding this comment

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

medium

To improve readability and limit variable scope, it's a good practice to declare variables as close as possible to where they are first used. The variables trigger_active and trigger_reasons are only used within the else block. Consider moving their declarations inside it.

Suggested change
local trigger_active=false
local trigger_reasons=""
# Condition 1: Quality gate is failing
if [[ "$sweep_gate_status" == "ERROR" || "$sweep_gate_status" == "WARN" ]]; then
trigger_active=true
trigger_reasons="quality gate ${sweep_gate_status}"
fi
if [[ "$prev_gate" == "UNKNOWN" ]]; then
# First run — no previous state to compare against. Treat as baseline:
# save current metrics and post a passive monitoring line. Without this
# guard, delta computation against zero fires false-positive triggers
# (e.g., 113 existing issues - 0 = +113 "spike"). (t1392)
coderabbit_section="### CodeRabbit
# Condition 2: Issue count spiked by threshold or more
if [[ "$issue_delta" -ge "$CODERABBIT_ISSUE_SPIKE" ]]; then
trigger_active=true
if [[ -n "$trigger_reasons" ]]; then
trigger_reasons="${trigger_reasons}, issue spike +${issue_delta}"
else
trigger_reasons="issue spike +${issue_delta}"
_Baseline run: recording ${sweep_total_issues} issues, gate ${sweep_gate_status}, ${sweep_high_critical} high/critical. Deltas will be computed from next sweep._
"
echo "[pulse-wrapper] CodeRabbit: baseline run for ${repo_slug} — saving state, skipping triggers" >>"$LOGFILE"
else
local issue_delta=$((sweep_total_issues - prev_issues))
local high_critical_delta=$((sweep_high_critical - prev_high_critical))
if [[ "$prev_gate" == "UNKNOWN" ]]; then
# First run — no previous state to compare against. Treat as baseline:
# save current metrics and post a passive monitoring line. Without this
# guard, delta computation against zero fires false-positive triggers
# (e.g., 113 existing issues - 0 = +113 "spike"). (t1392)
coderabbit_section="### CodeRabbit
_Baseline run: recording ${sweep_total_issues} issues, gate ${sweep_gate_status}, ${sweep_high_critical} high/critical. Deltas will be computed from next sweep._
"
echo "[pulse-wrapper] CodeRabbit: baseline run for ${repo_slug} — saving state, skipping triggers" >>"$LOGFILE"
else
local issue_delta=$((sweep_total_issues - prev_issues))
local high_critical_delta=$((sweep_high_critical - prev_high_critical))
local trigger_active=false
local trigger_reasons=""

Copy link
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 @.agents/scripts/pulse-wrapper.sh:
- Around line 1916-1934: The baseline branch currently suppresses all triggers;
change it so that while prev_gate == "UNKNOWN" still records state
(coderabbit_section) and skips delta-based triggers, it must NOT suppress
immediate Quality Gate failures: detect sweep_gate_status == "ERROR" or "WARN"
inside that branch and set trigger_active=true and trigger_reasons="quality gate
${sweep_gate_status}" (and append this reason into coderabbit_section) so
CodeRabbit is mentioned for significant gate failures; keep existing baseline
logging and state-save behavior but ensure trigger_reasons/trigger_active are
populated for gate failures even on first run.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 387af45a-c916-41fb-b532-4b49f4d7d0d4

📥 Commits

Reviewing files that changed from the base of the PR and between 4a2fdcb and 3c8dee1.

📒 Files selected for processing (1)
  • .agents/scripts/pulse-wrapper.sh

Comment on lines +1916 to 1934
if [[ "$prev_gate" == "UNKNOWN" ]]; then
# First run — no previous state to compare against. Treat as baseline:
# save current metrics and post a passive monitoring line. Without this
# guard, delta computation against zero fires false-positive triggers
# (e.g., 113 existing issues - 0 = +113 "spike"). (t1392)
coderabbit_section="### CodeRabbit

# Condition 2: Issue count spiked by threshold or more
if [[ "$issue_delta" -ge "$CODERABBIT_ISSUE_SPIKE" ]]; then
trigger_active=true
if [[ -n "$trigger_reasons" ]]; then
trigger_reasons="${trigger_reasons}, issue spike +${issue_delta}"
else
trigger_reasons="issue spike +${issue_delta}"
_Baseline run: recording ${sweep_total_issues} issues, gate ${sweep_gate_status}, ${sweep_high_critical} high/critical. Deltas will be computed from next sweep._
"
echo "[pulse-wrapper] CodeRabbit: baseline run for ${repo_slug} — saving state, skipping triggers" >>"$LOGFILE"
else
local issue_delta=$((sweep_total_issues - prev_issues))
local high_critical_delta=$((sweep_high_critical - prev_high_critical))

# Condition 1: Quality gate is failing
if [[ "$sweep_gate_status" == "ERROR" || "$sweep_gate_status" == "WARN" ]]; then
trigger_active=true
trigger_reasons="quality gate ${sweep_gate_status}"
fi
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Baseline mode currently suppresses real Quality Gate failures.

The prev_gate == "UNKNOWN" branch skips all trigger logic, so a first-run WARN/ERROR gate won’t request CodeRabbit review. That delays actionable alerts by at least one sweep.

Suggested patch
 if [[ "$prev_gate" == "UNKNOWN" ]]; then
-	# First run — no previous state to compare against. Treat as baseline:
-	# save current metrics and post a passive monitoring line. Without this
-	# guard, delta computation against zero fires false-positive triggers
-	# (e.g., 113 existing issues - 0 = +113 "spike"). (t1392)
-	coderabbit_section="### CodeRabbit
+	# First run — no previous state to compare against.
+	# Skip delta-based checks, but still trigger on failing quality gate.
+	if [[ "$sweep_gate_status" == "ERROR" || "$sweep_gate_status" == "WARN" ]]; then
+		coderabbit_section="### CodeRabbit
+
+**Trigger**: quality gate ${sweep_gate_status} (baseline run)
+
+@coderabbitai Please run a full codebase review of this repository. Focus on:
+- Security vulnerabilities and credential exposure
+- Shell script quality (error handling, quoting, race conditions)
+- Code duplication and maintainability
+- Documentation accuracy
+"
+		echo "[pulse-wrapper] CodeRabbit: active review triggered for ${repo_slug} (baseline gate ${sweep_gate_status})" >>"$LOGFILE"
+	else
+		coderabbit_section="### CodeRabbit
 
 _Baseline run: recording ${sweep_total_issues} issues, gate ${sweep_gate_status}, ${sweep_high_critical} high/critical. Deltas will be computed from next sweep._
 "
-	echo "[pulse-wrapper] CodeRabbit: baseline run for ${repo_slug} — saving state, skipping triggers" >>"$LOGFILE"
+		echo "[pulse-wrapper] CodeRabbit: baseline run for ${repo_slug} — saving state, skipping delta triggers" >>"$LOGFILE"
+	fi
 else

Based on learnings: the sweep should mention coderabbitai only for significant changes, including Quality Gate failure.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if [[ "$prev_gate" == "UNKNOWN" ]]; then
# First run — no previous state to compare against. Treat as baseline:
# save current metrics and post a passive monitoring line. Without this
# guard, delta computation against zero fires false-positive triggers
# (e.g., 113 existing issues - 0 = +113 "spike"). (t1392)
coderabbit_section="### CodeRabbit
# Condition 2: Issue count spiked by threshold or more
if [[ "$issue_delta" -ge "$CODERABBIT_ISSUE_SPIKE" ]]; then
trigger_active=true
if [[ -n "$trigger_reasons" ]]; then
trigger_reasons="${trigger_reasons}, issue spike +${issue_delta}"
else
trigger_reasons="issue spike +${issue_delta}"
_Baseline run: recording ${sweep_total_issues} issues, gate ${sweep_gate_status}, ${sweep_high_critical} high/critical. Deltas will be computed from next sweep._
"
echo "[pulse-wrapper] CodeRabbit: baseline run for ${repo_slug} — saving state, skipping triggers" >>"$LOGFILE"
else
local issue_delta=$((sweep_total_issues - prev_issues))
local high_critical_delta=$((sweep_high_critical - prev_high_critical))
# Condition 1: Quality gate is failing
if [[ "$sweep_gate_status" == "ERROR" || "$sweep_gate_status" == "WARN" ]]; then
trigger_active=true
trigger_reasons="quality gate ${sweep_gate_status}"
fi
if [[ "$prev_gate" == "UNKNOWN" ]]; then
# First run — no previous state to compare against.
# Skip delta-based checks, but still trigger on failing quality gate.
if [[ "$sweep_gate_status" == "ERROR" || "$sweep_gate_status" == "WARN" ]]; then
coderabbit_section="### CodeRabbit
**Trigger**: quality gate ${sweep_gate_status} (baseline run)
`@coderabbitai` Please run a full codebase review of this repository. Focus on:
- Security vulnerabilities and credential exposure
- Shell script quality (error handling, quoting, race conditions)
- Code duplication and maintainability
- Documentation accuracy
"
echo "[pulse-wrapper] CodeRabbit: active review triggered for ${repo_slug} (baseline gate ${sweep_gate_status})" >>"$LOGFILE"
else
coderabbit_section="### CodeRabbit
_Baseline run: recording ${sweep_total_issues} issues, gate ${sweep_gate_status}, ${sweep_high_critical} high/critical. Deltas will be computed from next sweep._
"
echo "[pulse-wrapper] CodeRabbit: baseline run for ${repo_slug} — saving state, skipping delta triggers" >>"$LOGFILE"
fi
else
local issue_delta=$((sweep_total_issues - prev_issues))
local high_critical_delta=$((sweep_high_critical - prev_high_critical))
# Condition 1: Quality gate is failing
if [[ "$sweep_gate_status" == "ERROR" || "$sweep_gate_status" == "WARN" ]]; then
trigger_active=true
trigger_reasons="quality gate ${sweep_gate_status}"
fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.agents/scripts/pulse-wrapper.sh around lines 1916 - 1934, The baseline
branch currently suppresses all triggers; change it so that while prev_gate ==
"UNKNOWN" still records state (coderabbit_section) and skips delta-based
triggers, it must NOT suppress immediate Quality Gate failures: detect
sweep_gate_status == "ERROR" or "WARN" inside that branch and set
trigger_active=true and trigger_reasons="quality gate ${sweep_gate_status}" (and
append this reason into coderabbit_section) so CodeRabbit is mentioned for
significant gate failures; keep existing baseline logging and state-save
behavior but ensure trigger_reasons/trigger_active are populated for gate
failures even on first run.

@alex-solovyev
Copy link
Collaborator Author

Closing in favour of PR #2835 (t1392: Fix CodeRabbit sweep first-run baseline detection) which takes a cleaner approach to the same underlying issue. The CodeRabbit feedback here has been incorporated into the newer PR's approach.

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

Labels

bug Auto-created from TODO.md tag

Projects

None yet

Development

Successfully merging this pull request may close these issues.

t1392: Fix CodeRabbit sweep still posting unconditionally after t1390 fix (PR #2808)

1 participant