How Findings Are Categorized in no-mistakes: Understanding Category and actionOrDefault
In the no-mistakes codebase, every Finding is classified by a Category field (documentation or lint) for pipeline routing and an Action field (no-op, auto-fix, or ask-user) for resolution behavior, with the actionOrDefault() method ensuring empty actions default to "ask-user" to prevent silent automatic fixes.
The no-mistakes repository treats every review result, test output, lint error, and PR comment as a Finding defined in internal/types/findings.go. Understanding how these findings are categorized and how their actions are resolved is critical for contributing to or extending the pipeline. The system uses two orthogonal classification mechanisms to determine both which gate processes a finding and how the pipeline ultimately handles it.
Finding Classification Architecture
Every Finding struct carries two distinct classification fields that serve different purposes in the pipeline. The Category field determines which housekeeping gate owns the finding, while the Action field controls the resolution strategy.
Category-Based Gate Routing
The Category field routes findings to the appropriate processing gate during the combined document and lint housekeeping pass. This classification uses two constants defined in internal/types/findings.go (lines 33–39):
FindingCategoryDocumentation(empty string""): Indicates the finding belongs to the documentation gateFindingCategoryLint("lint"): Indicates the finding belongs to the lint gate
When Category is empty, the pipeline treats the finding as a documentation issue. This design allows the housekeeping step in internal/pipeline/steps/housekeeping_test.go to split its work across the two gates efficiently.
Action-Based Resolution Strategy
The Action field determines how the pipeline treats the finding after production. The system defines three action constants:
const (
ActionNoOp = "no-op" // informational only, never fixed
ActionAutoFix = "auto-fix" // safe to apply automatically
ActionAskUser = "ask-user" // requires human intervention
)
These actions control whether a finding is silently ignored, automatically corrected, or parked for human review.
Understanding the actionOrDefault() Method
The actionOrDefault() method implements a safety mechanism to prevent undocumented findings from being auto-fixed. Located in internal/types/findings.go (lines 50–63), this method resolves the effective action for any finding:
func (f Finding) actionOrDefault() string {
if f.Action == "" {
return ActionAskUser // default
}
return f.Action
}
When a finding's Action field is empty, the method supplies the default action "ask-user". This guards against silently auto-fixing legacy or unclassified findings and aligns with the review prompt's principle of "when in doubt, default to ask-user". The internal/pipeline/steps/review.go file utilizes HasAskUserFindings(), which internally calls actionOrDefault(), to determine whether to park a run for human review.
Practical Implementation in the Pipeline
The categorization system manifests across multiple pipeline steps to coordinate processing and resolution.
Housekeeping and Gate Assignment
The housekeeping pass uses the Category field to partition findings between documentation and lint processing. As implemented in the pipeline steps, findings with Category = FindingCategoryLint route to the lint gate, while those with empty categories route to the documentation gate. This separation allows internal/pipeline/steps/lint.go and internal/pipeline/steps/document.go to handle their respective findings independently.
Rendering and UI Representation
The terminal UI in internal/tui/findings.go renders both the category and resolved action for each finding, giving users visibility into how the system classified each issue and how it intends to resolve it.
Working with Findings in Code
When creating findings programmatically, you explicitly set the classification fields or rely on the default behavior:
// Create a lint finding that will be auto-fixed.
f := types.Finding{
Severity: "high",
Description: "Trailing whitespace",
Action: types.ActionAutoFix,
Category: types.FindingCategoryLint,
}
// Create a documentation finding without an explicit action.
// The pipeline will treat it as "ask-user" because actionOrDefault()
// supplies the default.
g := types.Finding{
Severity: "info",
Description: "Missing Javadoc comment",
// Action omitted → defaults to ask-user
Category: types.FindingCategoryDocumentation,
}
// Resolve the effective actions.
fmt.Println(f.Action) // "auto-fix"
fmt.Println(g.Action) // "" (empty)
fmt.Println(g.actionOrDefault()) // "ask-user"
Summary
- Finding categorization in
no-mistakesuses aCategoryfield (empty for documentation,"lint"for lint) to route findings to the appropriate housekeeping gate. - Action resolution relies on three explicit constants:
ActionNoOp,ActionAutoFix, andActionAskUser. - Safety default: The
actionOrDefault()method ininternal/types/findings.goreturns"ask-user"when no action is specified, preventing accidental auto-fixes of unclassified findings. - Pipeline integration: The review step uses
HasAskUserFindings()(which callsactionOrDefault()) to determine if human intervention is required before proceeding.
Frequently Asked Questions
What is the default action for findings in no-mistakes?
When a finding has no explicit Action field set, the actionOrDefault() method defaults to "ask-user". This ensures that any unclassified or legacy finding requires human review rather than being automatically fixed or silently ignored.
How does no-mistakes differentiate between documentation and lint findings?
The system uses the Category field defined in internal/types/findings.go. An empty Category (represented by FindingCategoryDocumentation) indicates a documentation finding, while the string "lint" (represented by FindingCategoryLint) indicates a lint finding. The housekeeping pass uses this distinction to split processing across the two gates.
What happens if a finding has no explicit Category assigned?
If the Category field is empty, the pipeline treats the finding as belonging to the documentation gate. This is the default state for findings produced by the document processing step, while the lint step explicitly sets Category = FindingCategoryLint.
Where is the actionOrDefault() method defined?
The actionOrDefault() method is defined in internal/types/findings.go at lines 50–63. This method checks if f.Action is empty and returns ActionAskUser as the default, otherwise returning the explicitly set action value.
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 →