Skip to content

Fixer

@autowright/fixer is the intelligence layer: a long-running worker that polls the service for pending failures and processes each one into either a pull request or a needs-attention notification.

The worker loop

The worker polls GET /api/errors?status=pending every POLL_INTERVAL_MS (default 5 seconds) and runs jobs up to MAX_CONCURRENT_FIXES (default 2) in parallel. Each job is fully isolated — its own temp directory, its own repo clone, its own agent session.

Anatomy of a fix job

  1. Download the evidence bundle from artifact storage into the job’s working directory.
  2. Clone the target repogit clone --depth 1 --filter=blob:none, so even large repos clone in seconds; file contents are fetched only when the agent actually reads them.
  3. Run the agent over the evidence and the source.
  4. Deliver — on a confident fix: commit, push, open a GitHub PR, notify Slack. Otherwise: notify Slack with the diagnosis and evidence link.
  5. Report back — the job PATCHes its status and FixResult (including cost) to the service.

The agent

The agent runs on the Claude Agent SDK with a deliberately narrow toolbox:

SettingValue
Modelclaude-sonnet-4-6
Allowed toolsRead, Edit, Glob, Grep
DisallowedBash, web access — the agent edits code; it cannot execute anything
Max turns50

Its prompt carries the error classification, the failed step, the action log, and pointers to the captured DOM — plus classification-specific fix guidance (a SELECTOR_NOT_FOUND sends it hunting through dom.html for the element that replaced the broken selector).

The sandbox

Every tool call passes through a canUseTool gate that resolves the requested path and confines it to the job’s working directory (repo/ plus artifacts/). Anything outside — or anything unrecognized — is denied conservatively. The agent cannot read your filesystem, other jobs, or the fixer’s own environment.

The confidence gate

The agent must end its final message with an explicit verdict:

  • FIX_OUTCOME: FIXED — a confident, evidence-backed fix → becomes a PR.
  • FIX_OUTCOME: CANNOT_FIX — anything else → becomes triage. No speculative PRs, ever.

Delivery

  • Pull requests are opened through the GitHub REST API using GITHUB_TOKEN. The PR body carries the agent’s summary, the classification, and a link to the evidence bundle.
  • Slack notifications are Block Kit messages to SLACK_WEBHOOK_URL (“Fix proposed” or “Needs attention”), skipped silently when no webhook is configured.

Cost accounting

The fixer extracts the agent’s real usage — total_cost_usd, turn count, duration, and input/output/cache token counts — onto the FixResult, on both success and failure. It surfaces in the Slack message and the dashboard’s fix detail page, so every fix has a price tag.

Configuration

VariableDefaultPurpose
ANTHROPIC_API_KEYRequired — powers the agent
GITHUB_TOKENRequired for cloning private repos and opening PRs
SLACK_WEBHOOK_URLOptional notifications
POLL_INTERVAL_MS5000Queue poll cadence
MAX_CONCURRENT_FIXES2Parallel job limit

The fixer makes outbound calls only (service, storage, GitHub, Anthropic, Slack) — it needs no inbound ports. See Self-Hosting.