feat(toolchain): add Go ecosystem batch entry + format hook plugin - #908
Closed
kyle-sexton wants to merge 1 commit into
Closed
feat(toolchain): add Go ecosystem batch entry + format hook plugin#908kyle-sexton wants to merge 1 commit into
kyle-sexton wants to merge 1 commit into
Conversation
Adds Go coverage in both lanes per docs/topics/lint-static-analysis-gaps/PLAN.md Brief item 2: a `go` batch ecosystem default (golangci-lint v2 lint, gofmt check/format, a go-mod-tidy gate) in the toolchain plugin, and a new go-format hook plugin for fast per-file formatting on edit. Formatter selection followed a pick-for-the-problem field survey across gofmt/goimports/gofumpt/golangci-lint fmt: gofmt is the only candidate safe to run unconditionally on every edit (goimports deletes unreferenced imports with no unfixable-style escape hatch; gofumpt is third-party and stricter-than- canonical; golangci-lint fmt runs zero formatters with no repo config, verified empirically against golangci-lint v2.12.2). Import-organizing and stricter formatting stay available as an opt-in through the batch ecosystem's golangci-lint fmt route once a repo configures it. toolchain bumped 0.6.0 -> 0.7.0; go-format ships as a new 0.1.0 plugin. Closes #832 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This was referenced Jul 22, 2026
Contributor
Author
|
Superseded by #910 — same issue (#832), independently and more completely implemented by another actor (full green CI including both review passes, non-draft, richer design rationale). This lane's claim on #832 has been released; see the issue comment for the cross-actor-collision context (second occurrence this session of the pattern tracked in #920). Closing as this lane's own redundant work, not touching #910. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes Brief item 2 in
docs/topics/lint-static-analysis-gaps/PLAN.md(PR #829): Go coverage inboth lanes.
plugins/toolchain/reference/ecosystems/go.yaml):golangci-lint run ./...for lint (package-scope by design — golangci-lint's own FAQ/architecture rules out per-file use,
so it always applies with no opt-in gate),
gofmt -l/-w <files>for the zero-config format leg,and a default
go-mod-tidygate (go mod tidy -diff, non-mutating)./toolchain:checkand/toolchain:lintnow covergo(build + test + lint + format), with agolangalias.govulncheck is intentionally not part of the default (its vulnerability-database fetch and
scan time don't fit the batch entry's contract) — documented as a consumer-added
gatesentry.go-formathook plugin (new,plugins/go-format/): aPostToolUsehook that runsgofmt -wunconditionally on every.goedit.Formatter choice — pick-for-the-problem field survey (gofmt vs goimports vs gofumpt vs
golangci-lint fmt): gofmt is the only candidate safe to run unconditionally on every edit.goimports removes unreferenced imports — the same hazard
ruff-format's--unfixable F401guardexists to prevent for Python, but Go imports have no per-tool "unfixable" escape hatch, so
goimports would delete an import added one edit before the code that uses it. gofumpt
(
mvdan.cc/gofumpt) is third-party and stricter-than-canonical, an opinion this plugin does notship unconditionally.
golangci-lint fmtrequires an explicitformatters.enablein the repo'sown golangci-lint v2 config — verified empirically against golangci-lint v2.12.2 source
(
pkg/config/config.go'sNewDefaultleavesFormatters.Enableempty with no config file) andby running it in a throwaway repo (
golangci-lint fmt --diffexits 0 with no output — a silentno-op) that it cannot serve as a zero-config unconditional default either. Import-organizing and
stricter formatting stay available as an opt-in through the batch ecosystem's
golangci-lint fmtroute once a repo configures it (documented in
go.yaml'sopt-infield).Per-plugin version bumps:
toolchain0.6.0 → 0.7.0 (CHANGELOG entry added);go-formatships asa new 0.1.0 plugin (CHANGELOG seeded). Both registered in
.claude-plugin/marketplace.json, theroot README catalog (regenerated via
scripts/generate-catalog.mjs), and the go-format telemetrydata schema registered in
docs/conventions/hook-telemetry/README.md's Implementers table.Fix
plugins/toolchain/reference/ecosystems/go.yaml— new bundled default ecosystem file.plugins/toolchain/skills/check/context/go.md— new gotchas/reference file.plugins/toolchain/skills/check/SKILL.md,skills/lint/SKILL.md— addedgoto the coveredecosystem enumerations, argument-hints, per-project walking notes, and the lint/format
two-column table.
plugins/go-format/— new hook plugin:hooks/go-format.sh(mirrorsruff-format's shellshape; unconditional per
typos-format's pattern since gofmt has no config surface),hooks/go-format.test.sh(35-case black-box contract test),hooks/hook-utils.sh(syncedverbatim from
lib/hook-utils.sh),hooks/hooks.json,skills/setup/SKILL.md(mirrorstypos-format's check/apply contract — gofmt is a standalone toolchain binary, no per-repodependency-manager install path).
docs/conventions/hook-telemetry/data/go-format.schema.json— new per-hook telemetry dataschema, registered in the Implementers table.
.claude-plugin/marketplace.json, rootREADME.md— newgo-formatcatalog entry.Verification
Ran locally (Go 1.26.5, golangci-lint v2.12.2, gofmt, shellcheck 0.11.0, shfmt v3.13.1, jq
1.8.2, node v24.17.0,
claudeCLI 2.1.217 all present on this machine):End-to-end sanity check of the ecosystem's exact commands against a throwaway
go.modrepo(build-cmd, test-cmd, check-cmd's
golangci-lint run ./...andgofmt -l, thego-mod-tidygate,and
golangci-lint fmt --diff's documented zero-config no-op) — all behaved as documented ingo.yaml.Not run: the fleet-wide
scripts/run-plugin-tests.sh(every*.test.shacross all ~50 plugins)was not executed in full — only the new
go-format.test.sh(directly relevant) and the targetedgates above, which is what CI actually gates on for this class of change.
Related
Source issue: #832. Spec:
docs/topics/lint-static-analysis-gaps/PLAN.mdBrief item 2 (from #829).Closes #832
Claude-Session: https://claude.ai/code/session_01K1V3gkrfSf75isB8MiDy3o
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com