Skip to main content

The Fix Loop

The CI-Native Agent is a state machine driven entirely by GitHub webhooks. No polling, no hosted sandbox.


Lifecycleโ€‹

1. Alert receivedโ€‹

A SquireX scan (proactive or PR-triggered) uploads SARIF to GitHub Advanced Security. GHAS emits a code_scanning_alert webhook. The agent:

  • Skips the alert if its ref starts with squirex-autofix/ (loop prevention)
  • Skips if AUTOFIX_ENABLED is not set for the installation
  • Otherwise opens an autofix job keyed by squirex-autofix/alert-{alertId}

2. Context buildโ€‹

The repository is shallow-cloned and scanned to produce the semantic graph. The agent discovers related files โ€” test classes, parent classes, referenced metadata โ€” and optionally enriches context from a platform MCP server (ServiceNow ATF suites, MuleSoft Exchange assets). Context is token-budgeted (capped at 10 files / 40K tokens).

3. LLM fix generationโ€‹

A platform-aware system prompt is selected automatically:

FilesPlatformPrompt focus
.cls, .triggerApexgovernor limits, SOQL injection, sharing, FLS
sn_aia_*.xml, sys_script pathsServiceNowGlideRecordSecure, ACL enforcement, sn_aia_* security
src/main/mule/*.xml, anypoint pathsMuleSoftOAuth2 enforcement, DataWeave safety, Agent Fabric trust zones

The provider is pluggable via LLM_PROVIDER โ€” Anthropic Claude (with prompt caching to reduce retry cost) or GitHub Copilot via the GitHub Models API.

4. Tier 1 validation (local, free)โ€‹

The SquireX scanner re-runs against the patched files. If the original violation is not resolved, the agent retries (up to 2 times) with the failure fed back into the conversation. No branch is created until Tier 1 passes.

5. Branch + draft PRโ€‹

On Tier 1 pass, the patched file is committed to squirex-autofix/alert-{alertId} and a draft PR is opened immediately, linked to the originating alert.

6. Tier 2 validation (your CI)โ€‹

Your existing GitHub Actions pipeline runs against the branch. The agent waits for the check_run.completed webhook:

  • Green: the agent comments on the existing PR โ€” "Fixed. Tests green. Ready to merge." No duplicate PR.
  • Red: the CI failure log is tailed and replayed into the conversation; a new commit is pushed to the same branch (up to 3 CI retries).
  • Exhausted: the agent posts a transparent explanation comment and stops at zero charge.

7. Merge โ†’ billingโ€‹

When a human merges the draft PR, an autofix_billings record is created for transparent monthly reconciliation. Unmerged and exhausted fixes are never billed.


Conversation chaining (memory-hardened retry)โ€‹

The retry loop is chained, not stateless. Every retry โ€” Tier 1 or Tier 2 โ€” replays the full multi-turn conversation history: the original alert, every prior patch attempt, and every validation or CI failure log, in order.

alert โ”€โ–บ attempt 1 โ”€โ–บ CI fail โ”€โ”
โ”œโ”€โ–บ attempt 2 (sees alert + attempt 1 + its failure)
CI fail โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ””โ”€โ–บ attempt 3 (sees the entire chain) โ”€โ–บ green โœ…

This chain is persisted in the autofix_jobs record (conversation_history column) and survives across webhook events, so the model never repeats a failed approach blindly. Combined with prompt caching on the Anthropic provider, replaying the chain stays cheap on every retry.

LLM provider choiceโ€‹

The provider is selected per installation via LLM_PROVIDER:

ValueProviderNotes
anthropicClaude SonnetPrompt caching โ€” cheap chained retries (default)
copilotGitHub CopilotVia the OpenAI-compatible GitHub Models API

Where alerts come fromโ€‹

Alerts can be raised by a PR-triggered scan or โ€” more often โ€” by the proactive scan, which also files a human-readable issue announcing the incoming silent PR.