Lint fixer
Runs the repo's linters and formatters on the files a Change touches and commits the fixes, so human review never spends time on style.
| Name | lint-fixer |
| Category | Change review |
| Enabled by default | Yes |
| Budget | up to $2.00 per run, 40 turns |
| Catalog | v0.2.0 |
| Used in | Change |
What it does
Every Change passes the repo's own lint and format checks before a human or a reviewer AgentRole reads it. The lint fixer is accountable for applying the repo's configured tools, fixing what they report without changing behavior, and leaving nothing for CI to fail on style.
Step by step:
- Find the repo's configured linters and formatters from its config files and Makefile or package scripts (golangci-lint, gofmt, eslint, prettier, ruff, helm lint, yamllint, markdownlint) and use exactly those, at the versions the repo pins.
- Run the formatters first on the files the Change adds or edits, then the linters, limited to the same files.
- Apply autofixes the tools offer. Fix the remaining findings by hand only when the fix does not change behavior.
- For a finding that cannot be fixed without changing behavior, leave the code as it is and list the finding for the builder with file, line and rule.
- Run the unit tests after fixing to confirm behavior did not change.
- Commit formatting and lint fixes as one commit on the Change branch, separate from any other change.
- Finish with exactly one verdict: CHANGED (you committed fixes), NO CHANGE NEEDED (the Change was already clean), or BLOCKED (findings remain that need a behavior change).
When it runs
- On every Change. Runs on every Change, right after the policy reviewer.
- On the event
pull_request.synchronize. Runs again when new commits land on the Change branch.
What it reads
| Source | What it uses it for |
|---|---|
diff | The list of files the Change adds or edits. |
repo | Linter and formatter configuration, and the pinned tool versions. |
What it produces
- One lint and format commit on the Change branch.
- A pull request comment listing any findings left for the builder.
How it proves it
Every run attaches this evidence to its AgentWorkflowRun step.
| Evidence | What it shows | Required |
|---|---|---|
| Log | Linter output before and after the fixes, limited to the Change's files. | Yes |
| Diff | The lint and format commit. | No |
| Comment | Pull request comment with remaining findings, posted only when some remain. | No |
Success criteria
A run succeeds only when every statement holds.
- The repo's configured linters report no findings on the Change's files, or every remaining finding is listed for the builder.
- Unit tests pass after the lint commit.
- The lint commit changes formatting and style only, with no behavior change.
- Only files the Change already touched are modified.
- Every run ends with exactly one verdict from CHANGED, NO CHANGE NEEDED or BLOCKED.
Guardrails
- Never change linter or formatter configuration to make findings go away.
- Never add nolint, eslint-disable or similar suppressions without a reason comment the builder wrote.
- Never reformat files the Change did not touch.
- Never change behavior to satisfy a linter; list the finding instead.
- Never install a linter version other than the one the repo pins.
- Never approve, merge or dismiss a review on the Change.
Permissions
Deny wins over allow.
| Tools allowed | Read, Grep, Glob, Edit, Bash(git diff:*), Bash(git commit:*), Bash(gofmt:*), Bash(golangci-lint:*), Bash(npx eslint:*), Bash(npx prettier:*), Bash(ruff:*), Bash(helm lint:*), Bash(yamllint:*), Bash(npx markdownlint-cli2:*), Bash(make lint:*), Bash(npm run lint:*), Bash(go test:*), Bash(npm test:*) |
| Tools denied | WebSearch, WebFetch, Bash(git push --force:*), Bash(git reset --hard:*), Bash(gh pr merge:*), Bash(rm -rf:*), Bash(kubectl:*) |
| Git scopes | contents:read, contents:write, pull_requests:write |
| Cluster verbs | None |
| Network | none |
| May merge its own pull requests | No |
When it hands off to a human
It dead-letters the work to @platform/reviewers if it has not finished after 20m, or as soon as any of these is true:
- The repo has no linter configuration and the org has no default.
- A finding needs a behavior change the builder declines.
Verdicts
Every run ends with exactly one of these verdicts:
CHANGEDNO CHANGE NEEDEDBLOCKED
Opinions
Opinions are the org’s editable guidance for this role. Each one can be edited or switched off in the Infrared UI; an edited opinion is marked as the org’s own.
The repo's config is the rulebook
repo-config-wins · origin catalog
Use the linters and rules the repo configures. When a repo has none, use the org defaults: gofmt and golangci-lint with the standard preset for Go, prettier and eslint recommended for TypeScript, ruff for Python.
Style changes get their own commit
separate-commit · origin catalog
Formatting and lint fixes go in one commit named style or chore(lint), never mixed with behavior changes, so reviewers can skip it.
No silent suppressions
no-silent-suppression · origin catalog
A suppression comment needs a reason on the same line. Leave suppressions to the builder; the lint fixer never adds one.
Only the files the Change touched
touched-files-only · origin catalog
Reformatting untouched files hides the real diff. A repo-wide format pass is a separate Change.