Skip to content

feat: add fix_ci action to supervisor AI lifecycle for automatic CI repair#2144

Merged
marcusquinn merged 1 commit intomainfrom
feature/fix-ci-lifecycle
Feb 22, 2026
Merged

feat: add fix_ci action to supervisor AI lifecycle for automatic CI repair#2144
marcusquinn merged 1 commit intomainfrom
feature/fix-ci-lifecycle

Conversation

@marcusquinn
Copy link
Owner

@marcusquinn marcusquinn commented Feb 22, 2026

Summary

  • Adds fix_ci action to the supervisor AI lifecycle engine (ai-lifecycle.sh)
  • Closes the gap where CI failures (format, lint, typecheck) left PRs stuck in blocked state
  • Deterministic fast-path routing: when all CI failures are mechanically fixable, runs fix commands without AI

How It Works

Detection (fast-path in fast_path_decision):

  • Extracts failed CI check names from GitHub statusCheckRollup
  • If all failures are in Format, Lint, Typecheck (plus skipped Unit Tests/Merge E2E Reports), routes to fix_ci
  • Requires worktree to exist (can't fix without a working directory)

Execution (tiered in fix_ci_failures):

  1. Tier 1 — Mechanical: Detects package manager (pnpm/yarn/npm), runs format:fix and lint:fix
  2. Tier 2 — Verification: Runs typecheck to check if format/lint fixes resolved type errors
  3. Commit + Push: Commits fixes with conventional commit message, pushes to trigger CI re-run
  4. Fallback: If no changes produced, returns failure → escalation on next cycle

Repo detection:

  • Node.js repos: reads package.json scripts for available fix commands
  • Shell repos: detects linters-local.sh for shellcheck fixes
  • Installs dependencies (pnpm install) before running fixes

Before vs After

Scenario Before After
PR fails Format only Stuck blocked → manual fix or opus dispatch fix_ci runs format:fix, pushes, CI re-runs
PR fails Format + Lint + Typecheck Stuck blocked → expensive diagnostic subtask fix_ci runs fixes mechanically, verifies typecheck
PR fails tests Stuck blocked → escalation Unchanged (test failures need AI judgment)

Testing

  • bash -n: pass
  • shellcheck -S warning: zero violations
  • Verified against current blocked PRs: t004.24 (format only), t004.25 (format+lint+typecheck), t004.29 (typecheck)

Summary by CodeRabbit

  • New Features
    • Added automatic CI fixing for format, lint, and type-check failures.
    • Enhanced visibility into failed CI checks with detailed failure names displayed in task state.
    • Enabled automated decision-making to intelligently trigger mechanical CI fixes when appropriate.

…epair

Closes the gap in the supervisor pipeline where CI failures (format, lint,
typecheck) on PRs caused tasks to get stuck in 'blocked' state indefinitely.

Changes to ai-lifecycle.sh:
- gather_task_state: extract PR_CI_FAILED_CHECKS (names of failed CI checks)
- fast_path_decision: deterministic routing to fix_ci when all failures are
  mechanically fixable (Format, Lint, Typecheck, Unit Tests/E2E skipped)
- execute_lifecycle_action: new fix_ci case that calls fix_ci_failures()
- decide_next_action: added fix_ci to AI action vocabulary and rules
- fix_ci_failures(): new function implementing tiered CI repair:
  Tier 1: Mechanical (pnpm format:fix, pnpm lint:fix, linters-local.sh)
  Tier 2: Typecheck verification after format/lint fixes
  Auto-detects package manager (pnpm/yarn/npm) and available scripts.
  Commits fixes and pushes to trigger CI re-run.
  Falls back to escalation if mechanical fixes produce no changes.

This replaces the previous behavior where blocked PRs required either:
- A full opus worker dispatch (expensive, slow)
- Manual human intervention
- A diagnostic subtask (overkill for format:fix)
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 22, 2026

Caution

Review failed

The pull request is closed.

Walkthrough

This PR extends the AI lifecycle automation script with mechanical CI fixing capabilities, introducing a fix_ci_failures() function to automatically resolve fixable CI failures (formatting, linting, typechecking), tracking failed check names in PR_CI_FAILED_CHECKS state, and integrating fix_ci decision paths into both fast-path and AI-driven decision flows.

Changes

Cohort / File(s) Summary
CI Auto-Fix Core
.agents/scripts/supervisor/ai-lifecycle.sh
Added fix_ci_failures() function for automated format/lint/typecheck fixes with commit/push; extended PR state tracking with PR_CI_FAILED_CHECKS field; integrated fix_ci action into decision logic (fast_path_decision(), decide_next_action()) and execution path (execute_lifecycle_action()); updated action catalog and decision prompts.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

needs-review

Poem

🤖 ✨ When CI fails with a formatting whine,
Our auto-fixer springs to the line,
Format and lint, typecheck too—
Mechanical fixes see it through,
Zero debt maintained, pristine and fine! ✨

✨ 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 feature/fix-ci-lifecycle

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.

@marcusquinn marcusquinn merged commit 36e2355 into main Feb 22, 2026
7 of 10 checks passed
@gemini-code-assist
Copy link

Summary of Changes

Hello @marcusquinn, 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 significantly enhances the supervisor AI lifecycle by introducing an automated mechanism to resolve common CI failures. It streamlines the development workflow by automatically applying fixes for formatting, linting, and type-checking issues, reducing manual intervention and accelerating the progression of pull requests.

Highlights

  • New fix_ci action: Introduced a fix_ci action within the supervisor AI lifecycle to automatically address common CI failures.
  • Automated CI Repair: Enabled automatic repair for format, lint, and typecheck CI failures, preventing pull requests from getting stuck in a blocked state.
  • Fast-path Routing: Implemented deterministic fast-path routing to execute mechanical fixes without AI intervention when all detected CI failures are fixable.
Changelog
  • .agents/scripts/supervisor/ai-lifecycle.sh
    • Declared a new variable pr_ci_failed_checks to store names of failed CI checks.
    • Added logic to parse and extract failed CI check names from GitHub statusCheckRollup using jq.
    • Included PR_CI_FAILED_CHECKS in the task state output for better visibility.
    • Updated the list of available actions with a description for the new fix_ci action.
    • Added a new rule to the AI decision-making process to prioritize fix_ci for fixable CI failures.
    • Implemented the fix_ci action within execute_lifecycle_action, which calls the fix_ci_failures function.
    • Introduced the fix_ci_failures function to mechanically apply fixes (format, lint, shellcheck), install dependencies, commit changes, and push to the branch.
    • Integrated a fast_path_decision rule to automatically select the fix_ci action if all detected CI failures are mechanically fixable and a worktree exists.
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.

@marcusquinn marcusquinn deleted the feature/fix-ci-lifecycle branch February 22, 2026 15:37
@github-actions
Copy link

🔍 Code Quality Report

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

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

�[0;34m[INFO]�[0m Recent monitoring activity:
Sun Feb 22 15:37:21 UTC 2026: Code review monitoring started
Sun Feb 22 15:37:22 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 39

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 39
  • VULNERABILITIES: 0

Generated on: Sun Feb 22 15:37:24 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

@sonarqubecloud
Copy link

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

The pull request introduces a fix_ci action to the AI lifecycle engine, enabling automatic repair of common CI failures like formatting and linting. This is a great addition for reducing manual intervention. My feedback focuses on adhering to the repository's style guide regarding SQLite parameterized queries and following general best practices for JSON construction and error suppression in shell scripts.

IFS="$IFS_SAVE"

if [[ "$all_fixable" == "true" && "$worktree_exists" == "true" ]]; then
echo "{\"action\":\"fix_ci\",\"reason\":\"CI failed on fixable checks: ${ci_failed_checks}\",\"status_tag\":\"ci-failed\"}"

Choose a reason for hiding this comment

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

high

Constructing JSON via string interpolation is fragile and can lead to invalid JSON if variables contain special characters (like quotes or backslashes). Use jq --arg to safely construct the JSON object.

Suggested change
echo "{\"action\":\"fix_ci\",\"reason\":\"CI failed on fixable checks: ${ci_failed_checks}\",\"status_tag\":\"ci-failed\"}"
jq -cn --arg action "fix_ci" --arg reason "CI failed on fixable checks: ${ci_failed_checks}" --arg status_tag "ci-failed" '{action: $action, reason: $reason, status_tag: $status_tag}'
References
  1. Use jq --arg for strings to safely pass variables into a jq filter, avoiding syntax errors if variables contain special characters.


# Extract names of failed checks for fix_ci routing
local failed_check_names
failed_check_names=$(printf '%s' "$check_rollup" | jq -r '[.[] | select((.conclusion | test("FAILURE|TIMED_OUT|ACTION_REQUIRED")) or .state == "FAILURE" or .state == "ERROR") | .name] | join(",")' 2>/dev/null || echo "")

Choose a reason for hiding this comment

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

medium

Avoid using 2>/dev/null for blanket suppression of jq errors. Keeping stderr visible helps diagnose issues with malformed input or syntax errors, while the || echo "" fallback still provides a safe default value.

Suggested change
failed_check_names=$(printf '%s' "$check_rollup" | jq -r '[.[] | select((.conclusion | test("FAILURE|TIMED_OUT|ACTION_REQUIRED")) or .state == "FAILURE" or .state == "ERROR") | .name] | join(",")' 2>/dev/null || echo "")
failed_check_names=$(printf '%s' "$check_rollup" | jq -r '[.[] | select((.conclusion | test("FAILURE|TIMED_OUT|ACTION_REQUIRED")) or .state == "FAILURE" or .state == "ERROR") | .name] | join(",")' || echo "")
References
  1. In shell scripts with 'set -e' enabled, use '|| true' or default values to prevent script exit on optional lookup failures, while keeping stderr visible for debugging.

Comment on lines +756 to +762
local escaped_id
escaped_id=$(sql_escape "$task_id")

# Get worktree and branch from DB
local tworktree tbranch
tworktree=$(db "$SUPERVISOR_DB" "SELECT worktree FROM tasks WHERE id = '$escaped_id';" 2>/dev/null || echo "")
tbranch=$(db "$SUPERVISOR_DB" "SELECT branch FROM tasks WHERE id = '$escaped_id';" 2>/dev/null || echo "")

Choose a reason for hiding this comment

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

medium

The repository style guide requires using parameterized queries for SQLite to prevent SQL injection and improve performance. The db helper should be used with parameters instead of string interpolation.

Suggested change
local escaped_id
escaped_id=$(sql_escape "$task_id")
# Get worktree and branch from DB
local tworktree tbranch
tworktree=$(db "$SUPERVISOR_DB" "SELECT worktree FROM tasks WHERE id = '$escaped_id';" 2>/dev/null || echo "")
tbranch=$(db "$SUPERVISOR_DB" "SELECT branch FROM tasks WHERE id = '$escaped_id';" 2>/dev/null || echo "")
# Get worktree and branch from DB
local tworktree tbranch
tworktree=$(db "$SUPERVISOR_DB" "SELECT worktree FROM tasks WHERE id = ?;" "$task_id" || echo "")
tbranch=$(db "$SUPERVISOR_DB" "SELECT branch FROM tasks WHERE id = ?;" "$task_id" || echo "")
References
  1. All SQLite databases use WAL mode + busy_timeout=5000. Use parameterized queries where possible. (link)

local has_format_fix="false" has_lint_fix="false" has_typecheck="false"
if [[ -n "$pkg_mgr" && -f "$workdir/package.json" ]]; then
local scripts_json
scripts_json=$(jq -r '.scripts // {}' "$workdir/package.json" 2>/dev/null || echo "{}")

Choose a reason for hiding this comment

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

medium

Avoid using 2>/dev/null to suppress errors when the file's existence has already been verified. This can mask permission issues or malformed JSON errors.

Suggested change
scripts_json=$(jq -r '.scripts // {}' "$workdir/package.json" 2>/dev/null || echo "{}")
scripts_json=$(jq -r '.scripts // {}' "$workdir/package.json" || echo "{}")
References
  1. Avoid using 2>/dev/null to suppress errors on file operations if the file's existence has already been verified, as it can mask important issues like permissions problems.

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.

1 participant