How no-mistakes Handles Auto-Fixing Findings: Pipeline Execution and Configuration
no-mistakes automatically resolves code-style and lint findings by filtering for the "auto-fix" action, re-executing pipeline steps up to a configurable limit, and persisting each attempt with full audit trails in the database.
The no-mistakes repository implements a deterministic auto-fix workflow that eliminates manual toil for trivial issues. By analyzing step outcomes and re-running executions with fix context, the system resolves problems automatically while respecting guardrails and maintaining complete observability.
Identifying Auto-Fixable Findings
The pipeline distinguishes between findings that require human review and those that can be resolved automatically. In internal/pipeline/findings.go (lines 22‑38), the autoFixableFindingsJSON function filters raw JSON findings to extract only items where the Action field equals "auto-fix".
// internal/pipeline/findings.go
func autoFixableFindingsJSON(raw string) string {
if raw == "" { return "" }
findings, err := types.ParseFindingsJSON(raw)
if err != nil { return raw }
fixable := types.AutoFixableFindings(findings) // keeps only Action=="auto-fix"
if len(fixable.Items) == 0 { return "" }
fixableRaw, err := types.MarshalFindingsJSON(fixable)
if err != nil { return raw }
return fixableRaw
}
If the filtered list contains entries, the executor receives a non-empty payload indicating that automatic remediation is possible.
Configuring Auto-Fix Limits
Each pipeline step type has a default retry limit defined in internal/config/config.go (lines 95‑104). The autoFixDefaults() function returns an AutoFix struct with predefined thresholds:
// internal/config/config.go
func autoFixDefaults() AutoFix {
return AutoFix{
Lint: 3,
Test: 3,
Review: 0,
Document: 3,
CI: 3,
Rebase: 3,
}
}
Users override these defaults via the auto_fix section in YAML configuration files. The merged configuration is accessed at runtime through Config.AutoFixLimit(stepName), which returns the maximum attempts allowed for the current step.
The Auto-Fix Execution Loop
The core orchestration logic resides in Executor.executeStep within internal/pipeline/executor.go (lines 317‑323). After each step execution, the code evaluates whether to trigger an auto-fix pass:
// internal/pipeline/executor.go (excerpt)
autoFixLimit := e.config.AutoFixLimit(stepName)
autoFixAttempts := 0
for {
outcome, err := step.Execute(sctx)
// … (store findings, etc.)
if outcome.AutoFixable && autoFixLimit > 0 && autoFixAttempts < autoFixLimit {
fixableFindings := autoFixableFindingsJSON(outcome.Findings)
if fixableFindings != "" {
autoFixAttempts++
telemetry.Track("fix", e.fixTelemetryFields("auto", stepName,
findingsCount(fixableFindings), autoFixAttempts))
// record selection for DB
if currentRoundID != "" {
idsJSON := findingIDsJSON(fixableFindings)
e.db.SetStepRoundSelection(currentRoundID, &idsJSON,
db.RoundSelectionSourceAutoFix)
}
// mark step as fixing and re‑run
e.db.UpdateStepStatus(sr.ID, types.StepStatusFixing)
sctx.Fixing = true
sctx.PreviousFindings = fixableFindings
nextTrigger = "auto_fix"
continue
}
}
// … proceed to approval or finish
}
The loop continues only when three conditions are met: the step reports outcome.AutoFixable as true, the configured limit is greater than zero, and the current attempt count remains below that limit.
Agent Context and Fix Application
During the auto-fix pass, the executor modifies the step context (sctx) to signal that the current execution is a remediation attempt. The code sets sctx.Fixing = true and populates sctx.PreviousFindings with the filtered JSON payload. Step implementations read these fields to invoke appropriate agent commands—such as linting tools with --fix flags or code formatters—that modify the repository content directly.
Telemetry and Audit Trails
Every auto-fix attempt generates observability data. The executor calls telemetry.Track("fix", …) with metadata including the step name, attempt number, and finding count. Simultaneously, the database records the selection via db.SetStepRoundSelection, associating the finding IDs with the source constant RoundSelectionSourceAutoFix. This persistence enables UI components to display auto-fix statistics—such as "auto-fixed (2)"—in PR summaries and dashboards.
Termination Conditions
The auto-fix loop exits when either no more auto-fixable findings remain (empty fixableFindings payload) or the attempt counter reaches the configured limit (autoFixAttempts >= autoFixLimit). Upon termination, the pipeline proceeds to the standard approval flow for any remaining non-fixable findings, or marks the step as successfully completed if all issues are resolved.
Summary
- Detection:
autoFixableFindingsJSONininternal/pipeline/findings.gofilters for findings withAction: "auto-fix". - Limits: Default caps are defined in
autoFixDefaults(e.g., 3 for Lint, 0 for Review) and overridable via YAML configuration. - Execution: The
Executor.executeSteploop ininternal/pipeline/executor.gore-runs steps up to the limit, passing fix context viasctx.Fixingandsctx.PreviousFindings. - Observability: Each attempt is tracked via
telemetry.Trackand persisted to the database withSetStepRoundSelectionfor audit purposes.
Frequently Asked Questions
What types of findings can no-mistakes auto-fix?
no-mistakes can only auto-fix findings explicitly marked with the Action field set to "auto-fix" in the step's JSON output. Typically these include code-style violations, formatting issues, and certain linting errors that have deterministic, safe corrections.
How does the configuration limit auto-fix attempts?
The system reads Config.AutoFixLimit for each step type, using defaults from autoFixDefaults() in internal/config/config.go. You can override these per-repository or globally in the auto_fix section of your configuration YAML to set custom thresholds or disable auto-fix entirely by setting the value to zero.
Where does no-mistakes store the history of auto-fix attempts?
Each attempt is recorded in the database via db.SetStepRoundSelection with the source identifier RoundSelectionSourceAutoFix, and telemetry events are emitted via telemetry.Track("fix", …). This dual recording provides both an audit trail for compliance and metrics for the UI to display auto-fix counts in pull request summaries.
Can specific pipeline steps disable auto-fixing while others allow it?
Yes. Since limits are configured per step type in the AutoFix struct (Lint, Test, Review, Document, CI, Rebase), you can set individual thresholds such as Review: 0 to disable auto-fixing for code review steps while allowing up to three attempts for linting steps.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →