AACWorkflow Docs

GitHub CI Checks Fix Trigger

Automatically trigger agents to fix CI check failures on pull requests.

The GitHub CI Checks Fix Trigger feature lets you automatically assign a "fixer" agent to a pull request when its CI checks fail. The agent analyzes the failure logs and attempts to fix the issues (e.g., failing tests, lint errors, type mismatches) with a follow-up commit.

How it works

Flow overview

  1. PR opened → agent creates or updates a PR
  2. CI checks run → GitHub Actions, CircleCI, or other CI runs tests
  3. Check fails → (lint, tests, security scan, etc.)
  4. Trigger fires → AACWorkflow detects the failure
  5. Fixer assigned → a "fixer" agent is auto-assigned to fix the issues
  6. Agent analyzes → reads failure logs and error messages
  7. Agent implements fix → commits changes to the PR branch
  8. CI re-runs → checks run again on the new commit
  9. Success or escalate → if checks pass, PR is ready to merge; if still failing, escalate to human

Approval policies

You control which CI failures trigger auto-fixes:

  • All failures — any failed check triggers the fixer
  • Specific checks — only certain checks (e.g., "tests" but not "security")
  • Trusted checks only — only checks that are known-fixable (e.g., linting, formatting)

Dangerous checks (security, compliance) can be configured to require human approval before auto-fix is attempted.

Setup

Enable CI fix trigger

Go to Settings → GitHub → CI Checks Policy.

  1. Toggle Auto-fix CI check failures → ON

  2. Select which checks are auto-fixable:

    • ✓ Lint errors (fixable via eslint --fix, gofmt, etc.)
    • ✓ Type mismatches (often fixable via TypeScript inference)
    • ✓ Formatting (auto-fixable via Prettier, formatters)
    • ✗ Security scans (review before fix)
    • ✗ Custom workflows (often require manual intervention)
  3. Choose a fixer agent (or leave blank to use default "code-fixer")

  4. Set max retry attempts (default: 2)

  5. Click Save

Assign a fixer agent

By default, AACWorkflow uses an auto-provisioned "code-fixer" agent. To use a specific agent:

  1. Go to Settings → GitHub → CI Checks Policy
  2. Dropdown Fixer agent → select an agent (e.g., "Frontend Fixer", "Backend Fixer")
  3. Save

The selected agent must:

  • Have write access to the repo (via GitHub token)
  • Know how to fix the types of issues your CI checks for
  • Be available (not overloaded with other tasks)

How the fixer works

Step 1: Detect failure

When a PR's CI check fails, AACWorkflow reads the failure logs from GitHub (via the GitHub API):

{
  "check_run": "tests",
  "conclusion": "failure",
  "title": "Run tests",
  "output": {
    "title": "2 test failures",
    "summary": "packages/views/components/button.test.tsx:42 - expect....",
    "annotations": [
      {
        "path": "packages/views/components/button.test.tsx",
        "start_line": 42,
        "message": "Timeout: test 'renders with onClick handler' did not complete"
      }
    ]
  }
}

Step 2: Analyze & plan

The fixer agent:

  1. Clones the PR branch locally
  2. Reads the failure logs and error annotations
  3. Categorizes the failures:
    • Fixable: syntax errors, lint violations, missing types, test timeouts
    • Escalate: permission denied, infrastructure failures, test logic issues
  4. Plans a fix (e.g., "Add await to async test", "Remove unused variable")

Step 3: Implement fix

The fixer commits changes to the PR branch:

git checkout feature/aac-42-oauth
# Fix the issues (syntax, types, lint, tests)
git add .
git commit -m "fix: resolve CI check failures

- packages/views/components/button.test.tsx:42 - add await for async test
- server/cmd/server/main.go:18 - gofmt formatting
"
git push

GitHub triggers a new CI run automatically (since the branch was updated).

Step 4: Retry or escalate

After the fix commit:

  • CI passes ✅ → PR is now ready to merge (human review still required)
  • CI fails again ❌ → if max_retry_attempts not exceeded, retry logic kicks in:
    • Analyze the new failure
    • Plan another fix
    • Commit again
  • Max retries exceeded → escalate to human:
    • Post a comment: "I've attempted 2 fixes but CI still fails. See details below."
    • Leave the PR branch in the best state possible
    • Assign to human reviewer

Examples

Example 1: Lint error (auto-fixable)

CI failure: ESLint reports unused variable in apps/web/app/page.tsx:15

Fixer action:

  1. Detects: unused variable 'tempUser'
  2. Runs: eslint --fix apps/web/app/page.tsx
  3. Commits: fix: remove unused variable
  4. Pushes
  5. CI re-runs and passes ✅

Result: PR is now green; human reviews the code.

Example 2: Test timeout (usually fixable)

CI failure: Test times out in packages/core/agents/agents.test.ts:120

Fixer action:

  1. Reads error: "Test 'should handle concurrent requests' did not complete"
  2. Opens file, sees await is missing on async operation
  3. Adds await before the async call
  4. Commits: fix: add missing await in concurrent test
  5. Pushes
  6. CI re-runs; test completes in 500ms ✅

Result: PR is green.

Example 3: Type mismatch (varies in fixability)

CI failure: TypeScript reports type error in packages/core/api/client.ts:45

Fixer action:

  1. Reads: Type 'undefined' is not assignable to type 'string'
  2. Examines context; can't infer the correct value
  3. Tries: Add a type guard (e.g., ?? '')
  4. Commits and pushes
  5. CI re-runs; type check passes ✅

Result: PR is green (but human should review the type guard to ensure it's correct).

Example 4: Security check (escalates)

CI failure: Snyk detects a vulnerable dependency in package.json

Fixer action:

  1. Reads Snyk output: "lodash < 4.17.21 is vulnerable"
  2. Checks if it's safe to upgrade: npm update lodash
  3. Tests: npm test — all pass ✅
  4. BUT: Security checks have require_approval: true
  5. Posts comment: "Found vulnerable dependency; attempting upgrade."
  6. Waits for human approval before pushing the fix

Result: Escalated to human; fixer waits for OK to commit.

Approval & safety

Trust levels

Configure trust levels per check type:

CheckTrust levelBehavior
Lint (ESLint, gofmt)HighAuto-fix without approval
Type checking (TypeScript)HighAuto-fix without approval
Formatting (Prettier)HighAuto-fix without approval
TestsMediumAuto-fix, but escalate if > 2 failures
Security (Snyk, OWASP)LowRequire approval before fixing
Custom workflowsLowRequire approval before attempting fix

Max retry attempts

Set how many times the fixer should retry before escalating:

  • 1 — one attempt; escalate on any failure
  • 2 (default) — two attempts; escalate after second failure
  • 3 — three attempts; most issues are fixable by the third try

API & automation

Trigger fix manually

If auto-fix is disabled, you can trigger it manually:

POST /api/workspaces/{ws}/github/pr/{pr_number}/trigger-fix

Body:

{
  "check_run_id": 12345,
  "agent_id": "550e8400-e29b-41d4-a716-446655440000"
}

Disable fix for a specific PR

If you want to disable auto-fix for one PR (e.g., to investigate manually):

PATCH /api/workspaces/{ws}/github/pr/{pr_number}

Body:

{
  "auto_fix_ci_enabled": false
}

Re-enable:

{
  "auto_fix_ci_enabled": true
}

Query fix attempts

GET /api/workspaces/{ws}/github/pr/{pr_number}/fix-history

Returns:

{
  "pr_number": 123,
  "fix_attempts": [
    {
      "attempt": 1,
      "triggered_at": "2025-06-22T15:30:00Z",
      "check_run": "tests",
      "failure_summary": "2 tests failed (timeouts)",
      "agent_id": "550e8400-e29b-41d4-a716-446655440000",
      "fix_commit": "abc123def456",
      "result": "success"
    },
    {
      "attempt": 2,
      "triggered_at": "2025-06-22T15:35:00Z",
      "check_run": "lint",
      "failure_summary": "3 ESLint violations",
      "agent_id": "550e8400-e29b-41d4-a716-446655440000",
      "fix_commit": "def456abc123",
      "result": "escalated"
    }
  ]
}

Best practices

  1. Start with high-trust checks — lint and formatting are safest to auto-fix
  2. Review the first few auto-fixes — verify the fixer's judgment before trusting it fully
  3. Use dedicated fixer agents — agents trained for error analysis and remediation
  4. Monitor escalations — if the fixer escalates often, it may be due to unclear CI errors; improve your CI logs
  5. Set reasonable retry limits — 2-3 attempts usually catches fixable issues

Troubleshooting

"Fixer is making wrong fixes"

  1. Check the fixer agent's instructions (Settings → Agents)
  2. Review past fix attempts to see patterns
  3. Add more specific context to CI check logs (better error messages help)
  4. Consider using a different fixer agent or adding an approval gate

"Fixer keeps escalating instead of fixing"

  1. The check failures may not be fixable (e.g., security, infrastructure)
  2. The fixer agent may lack context; check its instructions and capabilities
  3. Increase max_retry_attempts if it's too low
  4. Add examples in the agent's system prompt to guide decision-making

"Manual fix needed but auto-fix ran first"

  1. Go to the PR in GitHub
  2. Set auto_fix_ci_enabled: false (via API or Settings)
  3. Investigate and manually fix the underlying issue
  4. Re-enable auto-fix once the issue is clear