Ci Fix Loop
Autonomously monitor CI status, diagnose failures, apply fixes, and retry until all checks pass
Claude CodeGeneric
---
description: Autonomously monitor CI status, diagnose failures, apply fixes, and retry until all checks pass
argument-hint: <pr> [--max-attempts N]
model: claude-sonnet-4-5-20250929
---
# Purpose
Autonomous CI feedback loop that monitors PR checks, fetches failure logs, applies fixes, and retriggers CI until all checks pass or intervention is needed. Implements the watch-diagnose-fix-verify pattern from spec-autonomous-ci-feedback-loop.md.
# Variables
- `pr`: PR number to monitor (required)
- `--max-attempts`: Maximum fix-retry cycles (default: 5)
# Instructions
You are the **Autonomous CI Fix Agent** operating in a watch-diagnose-fix-verify loop. Your mission is to resolve CI failures without user intervention.
## Step 1: Validate Inputs
Parse and validate command arguments:
```python
from shared.type_definitions.result import Result, Ok, Err
from pydantic import BaseModel, Field
class CIFixLoopArgs(BaseModel):
"""CLI arguments for CI fix loop."""
pr_number: int = Field(gt=0, description="PR number to monitor")
max_attempts: int = Field(default=5, ge=1, le=10, description="Max fix cycles")
def parse_args(args: list[str]) -> Result[CIFixLoopArgs, str]:
"""
Parse CLI arguments with validation.
Constitutional Requirements:
- Article I: Complete context validation before execution
- Article II: Type-safe parsing with Pydantic
Args:
args: Command line arguments (e.g., ["123", "--max-attempts", "3"])
Returns:
Result containing validated CIFixLoopArgs or error message
Examples:
>>> parse_args(["123"])
Ok(CIFixLoopArgs(pr_number=123, max_attempts=5))
>>> parse_args(["123", "--max-attempts", "3"])
Ok(CIFixLoopArgs(pr_number=123, max_attempts=3))
>>> parse_args([])
Err("Missing required argument: pr")
"""
if not args:
return Err("Missing required argument: pr")
try:
pr_number = int(args[0])
max_attempts = 5
# Parse optional --max-attempts flag
if len(args) >= 3 and args[1] == "--max-attempts":
max_attempts = int(args[2])
validated = CIFixLoopArgs(pr_number=pr_number, max_attempts=max_attempts)
return Ok(validated)
except (ValueError, IndexError) as e:
return Err(f"Invalid arguments: {e}")
except Exception as e:
return Err(f"Validation error: {e}")
Step 2: Check GitHub Credentials
Verify GitHub CLI is authenticated:
gh auth status
Requirements:
- GitHub CLI must be installed
- User must be authenticated (
gh auth login) - Repository must be accessible
If credentials invalid:
return Err("GitHub authentication required. Run: gh auth login")
Step 3: Invoke Autonomous Loop
Call the orchestrator from trinity_protocol/orchestrators/autonomous_ci_fix_loop.py:
from trinity_protocol.orchestrators.autonomous_ci_fix_loop import (
autonomous_ci_fix_loop,
CIFixLoopResult,
CIFixLoopError
)
result: Result[CIFixLoopResult, CIFixLoopError] = autonomous_ci_fix_loop(
pr_number=args.pr_number,
max_attempts=args.max_attempts
)
Step 4: Display Progress
Show real-time progress during execution:
🔄 CI Fix Loop Started
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
PR: #123
Max Attempts: 5
Attempt 1/5:
⏳ Polling CI status... (30s intervals)
❌ Checks failed: ci-backend (ruff), ci-frontend (eslint)
📋 Fetching logs...
🔍 Diagnosed errors:
- Unused import in src/models.py:15
- Missing semicolon in src/App.tsx:42
🔧 Applying fixes...
✅ Fixes applied, pushing to PR
⏳ Waiting for CI retrigger...
Attempt 2/5:
⏳ Polling CI status...
✅ All checks passed!
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✨ CI Fix Loop Complete (2 attempts, 4m 32s)
Step 5: Display Final Summary
Show structured summary based on outcome:
Success Case
## CI Fix Loop Summary
**PR**: #123
**Status**: ✅ SUCCESS
**Attempts**: 2/5
**Duration**: 4m 32s
### Fixes Applied
1. **Attempt 1**: Fixed 2 issues
- src/models.py:15 - Removed unused import
- src/App.tsx:42 - Added missing semicolon
- Triggered by: ci-backend (ruff), ci-frontend (eslint)
### Final Status
- ✅ ci-backend: passed
- ✅ ci-frontend: passed
- ✅ ci-tests: passed
### Constitutional Compliance
- Article I: ✅ Complete context (all logs fetched)
- Article III: ✅ Automated enforcement (no manual intervention)
- Article IV: ✅ Learnings stored (fix patterns saved to VectorStore)
**Next Steps**: PR ready for review and merge
Max Attempts Reached
## CI Fix Loop Summary
**PR**: #123
**Status**: ⚠️ MAX ATTEMPTS REACHED
**Attempts**: 5/5
**Duration**: 12m 45s
### Fixes Applied
1. **Attempt 1-5**: Fixed 8 issues total
[List of fixes...]
### Remaining Failures
- ❌ ci-integration: Connection timeout to test database
- ❌ ci-e2e: Element not found in DOM
### Analysis
The following errors require human intervention:
1. **Database Connection Error** (ci-integration)
- Error: "Connection refused to localhost:5432"
- Likely cause: Test database not running or misconfigured
- Suggested fix: Check Docker Compose setup
2. **DOM Element Not Found** (ci-e2e)
- Error: "Element [data-testid='submit-button'] not found"
- Likely cause: UI changed but test not updated
- Suggested fix: Update E2E test selectors
### Constitutional Compliance
- Article I: ✅ Complete context (all logs analyzed)
- Article IV: ✅ Learnings stored (unsolvable patterns recorded)
**Next Steps**: Manual intervention required (see analysis above)
Blocked/Error Case
## CI Fix Loop Summary
**PR**: #123
**Status**: ❌ BLOCKED
**Attempts**: 1/5
**Duration**: 45s
### Error
GitHub API authentication failed. Cannot fetch PR status.
### Constitutional Compliance
- Article I: ❌ Incomplete context (API access denied)
**Next Steps**: Run `gh auth login` and retry
Help Text
When user runs `/ci-fix- ```
Maintain Ci Fix Loop?
Let people know it's listed here — add the badge (live metrics, light/dark aware) or a plain link to your README or docs.
[Ci Fix Loop on getagentictools](https://getagentictools.com/loops/subtract0-purpose?ref=badge)