# How the Auto-Fix System Categorizes and Applies Fixes in no-mistakes

> Discover how the no-mistakes auto-fix system categorizes and applies fixes. Learn about pipeline filtering, validation, and automated patch generation for safe, efficient code correction.

- Repository: [Kun Chen/no-mistakes](https://github.com/kunchenguid/no-mistakes)
- Tags: internals
- Published: 2026-07-13

---

**The auto-fix system filters pipeline findings for auto-fixable flags, validates per-step limits against database state, and dispatches AI agents to generate and commit patches automatically when safe.**

The no-mistakes CLI includes a built-in auto-fix system that automatically resolves failures discovered during pipeline runs, such as lint errors, CI failures, and merge conflicts. The system operates through a structured decision pipeline that categorizes findings and respects configurable safety limits. According to the source code in `kunchenguid/no-mistakes`, the implementation spans multiple layers from JSON filtering to agent invocation.

## How the Auto-Fix System Processes Failures

The auto-fix system operates through four distinct phases that transform raw pipeline failures into committed fixes.

### Step 1: Finding Generation and JSON Filtering

Each pipeline step emits findings as JSON objects describing detected issues. The system distinguishes auto-fixable problems from those requiring human review by inspecting the `auto_fixable` boolean flag.

In [`internal/pipeline/findings.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/findings.go), the helper function `autoFixableFindingsJSON` filters the raw findings to extract only those marked with `"auto_fixable": true`. This filtered subset determines whether the auto-fix loop activates.

### Step 2: Executor Decision Logic

The executor evaluates whether to trigger an auto-fix attempt based on the step outcome and remaining quota. In [`internal/pipeline/executor.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/executor.go) approximately lines 680-690, the code checks three conditions: `outcome.AutoFixable` must be true, the global auto-fix setting must be enabled, and the `autoFixAttempts` counter must remain below the configured `autoFixLimit`.

When these conditions pass, the executor increments the attempt counter and logs the operation via `slog.Info`, capturing the step name, current attempt number, and maximum limit.

```go
// executor.go (excerpt)
if outcome.AutoFixable && autoFixLimit > 0 && autoFixAttempts < autoFixLimit {
    fixableFindings := autoFixableFindingsJSON(outcome.Findings)
    autoFixAttempts++
    slog.Info("auto-fixing step", "step", stepName,
        "attempt", autoFixAttempts, "max", autoFixLimit)
    // Launch agent...
}

```

### Step 3: Agent Invocation and Patch Application

For eligible steps, the system launches an AI agent (such as Codex or Claude) with a prompt encoding the filtered findings. The concrete implementation resides in [`internal/pipeline/steps/ci_fix.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/ci_fix.go) within the `autoFixCI` function.

If the agent produces a patch that applies cleanly, the system commits the changes and re-executes the step. The database persists the current `auto_fix_limit` and attempt count via `gate.autoFixes`, ensuring subsequent runs respect the configured ceiling. When patches fail to apply or the limit exhausts, the pipeline falls back to manual approval.

## Categorization of Findings

The auto-fix system categorizes all pipeline findings into three distinct types to determine resolution paths.

### Auto-Fixable Findings

**Auto-fixable findings** are issues the system can resolve without human intervention, such as simple lint violations or single-line test fixes. These must carry the `"auto_fixable": true` flag in their JSON representation. Only findings passing through `autoFixableFindingsJSON` enter the auto-fix loop.

### Ask-User Findings

**Ask-user findings** lack the auto-fixable flag or explicitly set it to false, covering complex refactorings or security issues. These trigger the **NeedsApproval** status, pausing the pipeline until human review occurs.

### Outcome Flags

After execution, the executor creates an `Outcome` struct containing:
- `AutoFixable`: A boolean indicating whether any auto-fixable findings exist
- `Findings`: The complete JSON list for potential filtering

The executor considers the auto-fix path exclusively when `Outcome.AutoFixable` evaluates to true.

## Configuration and Limits

Users control auto-fix behavior through global defaults and per-step overrides. In [`internal/config/config.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/config/config.go), the `autoFixDefaults()` function establishes:
- `autoFix.enabled`: Master switch defaulting to `true`
- `autoFix.limit`: Per-step maximum attempts defaulting to `1`
- `autoFix.rounds`: Tracking for summary output

The `AutoFixLimit(stepName)` function reads effective limits, while `StartStepWithAutoFixLimit` initializes the database state for each execution.

Repository-specific [`.no-mistakes.yaml`](https://github.com/kunchenguid/no-mistakes/blob/main/.no-mistakes.yaml) files override these defaults:

```yaml
steps:
  lint:
    auto_fix:
      enabled: true
      limit: 2
  test:
    auto_fix:
      enabled: false

```

This configuration disables auto-fix for the test step while allowing two attempts for lint fixes.

## Summary

- The auto-fix system filters findings using `autoFixableFindingsJSON` in [`internal/pipeline/findings.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/findings.go) to isolate JSON objects marked with `auto_fixable: true`.
- The executor in [`internal/pipeline/executor.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/executor.go) validates limits and increments `autoFixAttempts` before dispatching agents.
- The `autoFixCI` function in [`internal/pipeline/steps/ci_fix.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/ci_fix.go) handles agent invocation and merge-conflict resolution.
- Configuration resides in [`internal/config/config.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/config/config.go) with defaults overridable via [`.no-mistakes.yaml`](https://github.com/kunchenguid/no-mistakes/blob/main/.no-mistakes.yaml) per-step settings.
- Findings categorize as either auto-fixable (processed automatically) or ask-user (requiring manual approval).

## Frequently Asked Questions

### How does the auto-fix system determine which findings to fix automatically?

The system inspects the `auto_fixable` boolean field within each finding's JSON object. The `autoFixableFindingsJSON` helper in [`internal/pipeline/findings.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/findings.go) extracts only findings where this flag is true, filtering out security issues or complex changes that require human judgment.

### What happens when the auto-fix limit is reached?

When `autoFixAttempts` meets or exceeds `autoFixLimit` (tracked in the database via `gate.autoFixes`), the executor stops the auto-fix loop and marks the step as **NeedsApproval**. The pipeline pauses for manual intervention rather than attempting further automatic repairs.

### Can I disable auto-fix for specific pipeline steps?

Yes. Create a [`.no-mistakes.yaml`](https://github.com/kunchenguid/no-mistakes/blob/main/.no-mistakes.yaml) file in your repository and set `auto_fix.enabled` to `false` for the specific step. For example, disabling auto-fix for tests while keeping it for linting requires configuring the `test` step with `auto_fix.enabled: false` as shown in the configuration examples.

### Where does the auto-fix system store attempt counts and limits?

The system persists auto-fix state in the database using the `gate.autoFixes` field. The executor calls `StartStepWithAutoFixLimit` to initialize limits at step start, and increments counters during execution to enforce per-step ceilings across multiple runs.