Lint (patch-aware by default)

SkillDev tools

Run golangci-lint and fix findings. Patch-aware by default (only lines changed vs origin/main, matching CI's real gate) — pass full-repo to lint everything instead. Invoke on explicit requests like \"lint this\" / \"run a full lint\", or from within the fix-all skill's cycle.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Lint (patch-aware by default) skill

What this skill tells your AI

The instructions your AI receives, as published by cloudposse/atmos in .claude/skills/lint/SKILL.md and read by ahel’s review.

Runs this repo's real lint gate — the custom golangci-lint binary with the lintroller plugin (.custom-gcl.yml), the same one .github/workflows/codeql.yml's lint-golangci job runs — and fixes what it finds.

Default mode: patch-aware

Run:

atmos fix lint

This delegates to the existing atmos lint --changed (.atmos.d/lint.yaml), which builds go.mod compatibility checks, then builds ./custom-gclstaleness-guarded: it only rebuilds when the binary is missing or older than its build inputs (.custom-gcl.yml or the lintroller plugin sources), so this is cheap in the common case, not a fresh clone-and-compile every cycle. No separate "is it built" precondition needed; atmos fix lint handles that safely on its own.

The underlying lint run is scoped to --new-from-rev=origin/main — only findings on lines changed vs origin/main, exactly matching CI's real gate (.github/workflows/codeql.yml's lint-golangci job).

Zero findings → one-line no-op summary, done.

Full-repo mode (explicit only)

Only when a human explicitly asks for a full lint (e.g. "run a full lint", "lint the whole repo" — never inferred, never run from the automated loop). Run the same staleness-guarded build the patch-aware mode uses (atmos lint custom-gcl — only rebuilds ./custom-gcl when missing or older than its build inputs) before invoking the binary directly, so a fresh checkout or a stale binary after .custom-gcl.yml/lintroller changes doesn't fail outright or silently report wrong findings:

atmos lint custom-gcl
./custom-gcl run --config=.golangci.yml

(no --new-from-rev, so it reports every existing finding, not just new ones — expect this to surface pre-existing issues unrelated to any current patch).

Fixing findings

Delegate to Agent subagent_type: "lint-fix", passing the raw custom-gcl output. The agent fixes what it can, re-runs the same lint command to confirm clean, and reports anything it skipped (with a reason) rather than forcing a fix — e.g. a finding that requires a broader refactor than patch scope. For a skipped finding when called from the automated loop, invoke the say skill with a short message like "PR <number> has a lint finding needing your input."

Follow the loop's existing git-hygiene discipline when committing a fix: verify the commit is signed (git log --show-signature -1), git add only the files actually touched, plain (never force) git push.

Related

  • lint-fix agent — does the actual fixing.
  • fix-all skill — invokes this skill's default (patch-aware) mode at step 6 (and reuses it directly at step 2 for CI-sourced lint findings). Scheduled hourly by pr-maintenance-loop, or run this directly for a one-shot.
  • say skill — invoked when a finding is skipped and needs human input.
  • atmos fix lint (.atmos.d/fix.yaml) — the custom command this skill's default mode runs; delegates to the existing atmos lint --changed (.atmos.d/lint.yaml), also used by the pre-commit hook via go tool mage lint:precommit (magefiles/).

Signals

GitHub stars
1k
Forks
175
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
lint-cloudposse
Source
github.com/cloudposse/atmos