@mrciphersmith/keryx 0.2.164 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +85355 -56749
- package/dist/core.js +28605 -18901
- package/package.json +2 -2
- package/src/gdgraph/affected-report.ts +141 -0
- package/src/gdgraph/build.ts +170 -23
- package/src/gdgraph/service.ts +6 -0
- package/src/gdgraph/staleness.ts +253 -45
- package/src/gdskills/bundled/agents/codebase-navigator.md +55 -0
- package/src/gdskills/bundled/agents/design-advisor.md +64 -0
- package/src/gdskills/bundled/agents/docs-maintainer.md +56 -0
- package/src/gdskills/bundled/agents/end-to-end-tester.md +56 -0
- package/src/gdskills/bundled/agents/error-path-auditor.md +57 -0
- package/src/gdskills/bundled/agents/go-build-fixer.md +52 -0
- package/src/gdskills/bundled/agents/go-code-auditor.md +49 -0
- package/src/gdskills/bundled/agents/performance-auditor.md +63 -0
- package/src/gdskills/bundled/agents/python-build-fixer.md +52 -0
- package/src/gdskills/bundled/agents/python-code-auditor.md +49 -0
- package/src/gdskills/bundled/agents/refactoring-steward.md +61 -0
- package/src/gdskills/bundled/agents/security-auditor.md +62 -0
- package/src/gdskills/bundled/agents/test-first-driver.md +61 -0
- package/src/gdskills/bundled/agents/work-planner.md +62 -0
- package/src/gdskills/bundled/install-manifest.json +530 -0
- package/src/gdskills/bundled/rules/core/skill-lifecycle.mdc +29 -1
- package/src/gdskills/bundled/rules/core/skills-storage-workflow.mdc +2 -2
- package/src/gdskills/bundled/skills/review/code-style-review/SKILL.md +1 -1
- package/src/gdskills/bundled/skills/review/review-orchestrator/SKILL.md +74 -246
- package/src/gdskills/bundled/skills/review/review-orchestrator/output-contract.schema.json +19 -0
- package/src/gdskills/bundled/skills/review/review-orchestrator/reviewer-finding.schema.json +10 -0
- package/src/gdskills/bundled/skills/review/review-orchestrator/reviewer-input.schema.json +5 -0
- package/src/gdskills/bundled/skills/review/review-orchestrator/templates/pr-comment-backend.md +50 -0
- package/src/gdskills/bundled/skills/review/review-orchestrator/templates/pr-comment-frontend.md +52 -0
- package/src/gdskills/bundled/skills/review/review-orchestrator/templates/review-report.md +143 -0
- package/src/gdskills/bundled/stacks/go/agent-refs.json +3 -0
- package/src/gdskills/bundled/stacks/go/governance/eval.json +1745 -0
- package/src/gdskills/bundled/stacks/go/governance/scout.json +31 -0
- package/src/gdskills/bundled/stacks/go/pack.json +41 -0
- package/src/gdskills/bundled/stacks/go/rules/coding-style.mdc +85 -0
- package/src/gdskills/bundled/stacks/go/rules/patterns.mdc +65 -0
- package/src/gdskills/bundled/stacks/go/rules/security.mdc +73 -0
- package/src/gdskills/bundled/stacks/go/rules/testing.mdc +68 -0
- package/src/gdskills/bundled/stacks/go/skills/go-build-fix/SKILL.md +138 -0
- package/src/gdskills/bundled/stacks/go/skills/go-build-fix/evals.json +75 -0
- package/src/gdskills/bundled/stacks/go/skills/go-code-review/SKILL.md +121 -0
- package/src/gdskills/bundled/stacks/go/skills/go-code-review/evals.json +72 -0
- package/src/gdskills/bundled/stacks/go/skills/go-implementation/SKILL.md +122 -0
- package/src/gdskills/bundled/stacks/go/skills/go-implementation/evals.json +76 -0
- package/src/gdskills/bundled/stacks/go/skills/go-testing/SKILL.md +126 -0
- package/src/gdskills/bundled/stacks/go/skills/go-testing/evals.json +73 -0
- package/src/gdskills/bundled/stacks/python/agent-refs.json +3 -0
- package/src/gdskills/bundled/stacks/python/governance/eval.json +1758 -0
- package/src/gdskills/bundled/stacks/python/governance/scout.json +34 -0
- package/src/gdskills/bundled/stacks/python/pack.json +41 -0
- package/src/gdskills/bundled/stacks/python/rules/coding-style.mdc +63 -0
- package/src/gdskills/bundled/stacks/python/rules/patterns.mdc +88 -0
- package/src/gdskills/bundled/stacks/python/rules/security.mdc +84 -0
- package/src/gdskills/bundled/stacks/python/rules/testing.mdc +77 -0
- package/src/gdskills/bundled/stacks/python/skills/python-build-fix/SKILL.md +144 -0
- package/src/gdskills/bundled/stacks/python/skills/python-build-fix/evals.json +74 -0
- package/src/gdskills/bundled/stacks/python/skills/python-code-review/SKILL.md +155 -0
- package/src/gdskills/bundled/stacks/python/skills/python-code-review/evals.json +72 -0
- package/src/gdskills/bundled/stacks/python/skills/python-implementation/SKILL.md +143 -0
- package/src/gdskills/bundled/stacks/python/skills/python-implementation/evals.json +78 -0
- package/src/gdskills/bundled/stacks/python/skills/python-testing/SKILL.md +132 -0
- package/src/gdskills/bundled/stacks/python/skills/python-testing/evals.json +73 -0
- package/src/gdskills/bundled/stacks/react/agent-refs.json +4 -0
- package/src/gdskills/bundled/stacks/react/governance/eval.json +2188 -0
- package/src/gdskills/bundled/stacks/react/governance/scout.json +40 -0
- package/src/gdskills/bundled/stacks/react/pack.json +42 -0
- package/src/gdskills/bundled/stacks/react/rules/coding-style.mdc +58 -0
- package/src/gdskills/bundled/stacks/react/rules/patterns.mdc +79 -0
- package/src/gdskills/bundled/stacks/react/rules/security.mdc +70 -0
- package/src/gdskills/bundled/stacks/react/rules/testing.mdc +60 -0
- package/src/gdskills/bundled/stacks/react/skills/react-build-fix/SKILL.md +139 -0
- package/src/gdskills/bundled/stacks/react/skills/react-build-fix/evals.json +72 -0
- package/src/gdskills/bundled/stacks/react/skills/react-code-review/SKILL.md +148 -0
- package/src/gdskills/bundled/stacks/react/skills/react-code-review/evals.json +74 -0
- package/src/gdskills/bundled/stacks/react/skills/react-implementation/SKILL.md +140 -0
- package/src/gdskills/bundled/stacks/react/skills/react-implementation/evals.json +74 -0
- package/src/gdskills/bundled/stacks/react/skills/react-testing/SKILL.md +142 -0
- package/src/gdskills/bundled/stacks/react/skills/react-testing/evals.json +83 -0
- package/src/gdskills/bundled/stacks/react/skills/react-upgrade-migration/SKILL.md +155 -0
- package/src/gdskills/bundled/stacks/react/skills/react-upgrade-migration/evals.json +74 -0
- package/src/gdskills/bundled/stacks/ts-js-node/agent-refs.json +4 -0
- package/src/gdskills/bundled/stacks/ts-js-node/governance/eval.json +2155 -0
- package/src/gdskills/bundled/stacks/ts-js-node/governance/scout.json +40 -0
- package/src/gdskills/bundled/stacks/ts-js-node/pack.json +41 -0
- package/src/gdskills/bundled/stacks/ts-js-node/rules/coding-style.mdc +73 -0
- package/src/gdskills/bundled/stacks/ts-js-node/rules/patterns.mdc +61 -0
- package/src/gdskills/bundled/stacks/ts-js-node/rules/security.mdc +71 -0
- package/src/gdskills/bundled/stacks/ts-js-node/rules/testing.mdc +63 -0
- package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-build-fix/SKILL.md +137 -0
- package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-build-fix/evals.json +73 -0
- package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-code-review/SKILL.md +124 -0
- package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-code-review/evals.json +74 -0
- package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-esm-migration/SKILL.md +152 -0
- package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-esm-migration/evals.json +71 -0
- package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-implementation/SKILL.md +127 -0
- package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-implementation/evals.json +72 -0
- package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-testing/SKILL.md +134 -0
- package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-testing/evals.json +70 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"query": "Use when implementing or extending a feature in a Go service or module -- module layout under cmd/ and internal/, interface placement, context propagation, goroutine lifetimes with errgroup or WaitGroup, error wrapping with %w, and log/slog usage.",
|
|
4
|
+
"decision": "create",
|
|
5
|
+
"topMatch": "python/python-implementation",
|
|
6
|
+
"recordedAt": "2026-09-24T12:08:06.318Z",
|
|
7
|
+
"skillName": "go-implementation"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"query": "Use when a Go package's test suite needs writing, extending, or fixing -- table-driven subtests with t.Run, t.Helper/t.Cleanup/t.Context, testdata golden files, httptest, fuzz tests, -race, and b.Loop benchmarks.",
|
|
11
|
+
"decision": "create",
|
|
12
|
+
"topMatch": "ts-js-node/nodejs-testing",
|
|
13
|
+
"recordedAt": "2026-09-24T12:08:08.013Z",
|
|
14
|
+
"skillName": "go-testing"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"query": "Use when reviewing a Go change for concurrency and idiom risks -- ignored errors, goroutine leaks, data races, context misuse (stored on structs or Background() in handlers), defer in loops, nil map writes, and interface pollution. Read-only, no edits.",
|
|
18
|
+
"decision": "create",
|
|
19
|
+
"topMatch": "ts-js-node/nodejs-code-review",
|
|
20
|
+
"recordedAt": "2026-09-24T12:08:09.683Z",
|
|
21
|
+
"skillName": "go-code-review"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"query": "Use when go build/go vet fails, or go.mod/go.sum are out of sync -- resolves module/toolchain mismatches, import cycles, generic type inference errors, staticcheck/golangci-lint failures, and a failing go test -race, with the smallest root-cause fix.",
|
|
25
|
+
"decision": "fork",
|
|
26
|
+
"topMatch": "ts-js-node/nodejs-build-fix",
|
|
27
|
+
"recordedAt": "2026-09-24T12:08:16.513Z",
|
|
28
|
+
"skillName": "go-build-fix",
|
|
29
|
+
"justification": "Nearest matches: ts-js-node/nodejs-build-fix (0.44) fixes tsc type errors, ESM/CJS module resolution, and eslint failures for Node/TS -- not Go's go vet/staticcheck/golangci-lint findings or go.mod/go.sum toolchain mismatches. python/python-build-fix (0.41) resolves pip/pyproject dependency and import errors for Python, not Go's import-cycle-via-internal/ restructuring or generic type-inference errors. react/react-build-fix (0.32) fixes JSX/TSX prop and bundler errors for React, unrelated to Go's compiler/toolchain surface. None share Go-specific vocabulary (go vet, staticcheck, golangci-lint, go.mod/go.sum, internal/) so this is a genuine fork, not a substitute."
|
|
30
|
+
}
|
|
31
|
+
]
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "go",
|
|
3
|
+
"family": "language",
|
|
4
|
+
"modules": ["go-rules", "go-skills"],
|
|
5
|
+
"detectionMarkers": ["go"],
|
|
6
|
+
"provenance": {
|
|
7
|
+
"origin": "authored",
|
|
8
|
+
"sourceRef": "flow 314, Wave 4 batch 1"
|
|
9
|
+
},
|
|
10
|
+
"stability": "stable",
|
|
11
|
+
"skills": {
|
|
12
|
+
"implement": ["go-implementation"],
|
|
13
|
+
"test": ["go-testing"],
|
|
14
|
+
"review": ["go-code-review"],
|
|
15
|
+
"build-fix": ["go-build-fix"],
|
|
16
|
+
"migrate": []
|
|
17
|
+
},
|
|
18
|
+
"agentProfile": {
|
|
19
|
+
"displayName": "Go",
|
|
20
|
+
"auditFocus": [
|
|
21
|
+
"an error return that is discarded or shadowed instead of checked or wrapped with %w",
|
|
22
|
+
"a goroutine started with no owned cancellation path (context, channel close, or WaitGroup) that can leak",
|
|
23
|
+
"a context.Context stored on a struct field, or a fresh context.Background()/TODO() created inside a request handler instead of threading the caller's ctx",
|
|
24
|
+
"concurrent map or slice access with no mutex/sync primitive guarding it",
|
|
25
|
+
"a defer inside a loop body that accumulates resources until the function returns",
|
|
26
|
+
"an exported type whose constructor returns an interface instead of the concrete struct, or an interface defined on the producer side instead of at the consumer"
|
|
27
|
+
],
|
|
28
|
+
"buildCommands": [
|
|
29
|
+
"go build ./...",
|
|
30
|
+
"go vet ./...",
|
|
31
|
+
"go test -race ./...",
|
|
32
|
+
"golangci-lint run ./... (only when the project has a golangci-lint config)"
|
|
33
|
+
],
|
|
34
|
+
"fixGuardrails": [
|
|
35
|
+
"Never silence a vet/lint finding with a blank `_ = err` or a `//nolint` comment instead of fixing the root cause.",
|
|
36
|
+
"Never change `go.mod`'s `go` directive or a dependency's major version just to make an error disappear; fix the code against the declared toolchain.",
|
|
37
|
+
"Never add a `replace` directive to route around a real compile error in a dependency without saying so in the report.",
|
|
38
|
+
"Never delete or skip a failing test to reach a green build."
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
---
|
|
2
|
+
extends: common
|
|
3
|
+
paths: ["**/*.go"]
|
|
4
|
+
metadata:
|
|
5
|
+
origin: authored
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Go coding style
|
|
9
|
+
|
|
10
|
+
Narrows `core-common-rules`' stack-agnostic style rules to modern Go
|
|
11
|
+
(1.23-1.25) idiom. Applies only to `*.go` files — everything not
|
|
12
|
+
Go-specific still comes from the common rules this file `extends`.
|
|
13
|
+
|
|
14
|
+
## Naming and structure
|
|
15
|
+
|
|
16
|
+
- Package names are short, lowercase, no underscores or `mixedCaps`
|
|
17
|
+
(`user`, not `user_service` or `userService`); do not stutter the package
|
|
18
|
+
name in exported identifiers (`user.User`, not `user.UserAccount`).
|
|
19
|
+
- `MixedCaps`/`mixedCaps`, never `snake_case`, for identifiers — exported
|
|
20
|
+
starts with an uppercase letter, unexported with lowercase.
|
|
21
|
+
- Keep `main` thin: business logic lives in packages under `internal/` (or
|
|
22
|
+
a library's own top-level packages), `cmd/<binary>/main.go` only wires
|
|
23
|
+
flags/config and calls into them.
|
|
24
|
+
- An identifier's name shrinks with its scope: a loop index is `i`, a
|
|
25
|
+
package-level exported function gets a full descriptive name.
|
|
26
|
+
|
|
27
|
+
## Interfaces and structs
|
|
28
|
+
|
|
29
|
+
- Accept interfaces, return structs: a function parameter should be the
|
|
30
|
+
narrowest interface the callee needs; a constructor returns the concrete
|
|
31
|
+
`*Thing`, not an interface, so callers get the full method set and the
|
|
32
|
+
compiler catches a missing method at the definition site.
|
|
33
|
+
- Define an interface at the consumer (the package that calls through it),
|
|
34
|
+
not the producer (the package that implements it) — `io.Reader`-sized:
|
|
35
|
+
one or two methods. A producer-side interface with only one
|
|
36
|
+
implementation is usually unnecessary indirection.
|
|
37
|
+
- Prefer a zero-value-useful struct (`var b bytes.Buffer` works with no
|
|
38
|
+
constructor) over requiring `New()` when the zero value is meaningful.
|
|
39
|
+
|
|
40
|
+
## Errors
|
|
41
|
+
|
|
42
|
+
- Every returned `error` is checked or explicitly and visibly discarded
|
|
43
|
+
(`_ = f.Close() // best-effort`) — never silently dropped.
|
|
44
|
+
- Wrap with context using `fmt.Errorf("doing x: %w", err)`, not `%v`, so
|
|
45
|
+
the original error survives for `errors.Is`/`errors.As` up the call
|
|
46
|
+
stack. Wrap once per meaningful layer, not at every call site.
|
|
47
|
+
- Compare sentinel errors with `errors.Is`, and unwrap typed errors with
|
|
48
|
+
`errors.As` — never a string comparison (`err.Error() == "..."` ) or a
|
|
49
|
+
bare `==` against a wrapped error.
|
|
50
|
+
- A package-level sentinel error is `var ErrNotFound = errors.New("...")`,
|
|
51
|
+
named `Err<Reason>`; a custom error type implements `Error() string` and,
|
|
52
|
+
when it wraps another error, `Unwrap() error`.
|
|
53
|
+
|
|
54
|
+
## Concurrency and context
|
|
55
|
+
|
|
56
|
+
- `context.Context` is always the first parameter, named `ctx`, and is
|
|
57
|
+
never stored on a struct field — thread it through call chains instead.
|
|
58
|
+
- Every goroutine a function starts has an explicit owner that knows when
|
|
59
|
+
it exits: joined with `sync.WaitGroup` (or `WaitGroup.Go` on a toolchain
|
|
60
|
+
that has it), bounded by `errgroup.Group`, or cancelled through the
|
|
61
|
+
`ctx` it was given. A goroutine with no join point and no cancellation
|
|
62
|
+
path is a leak, not fire-and-forget.
|
|
63
|
+
- Check `ctx.Err()` / respect `ctx.Done()` in any loop or blocking call
|
|
64
|
+
that should stop when the caller cancels.
|
|
65
|
+
|
|
66
|
+
## Generics and modern idiom
|
|
67
|
+
|
|
68
|
+
- Reach for a type parameter only when it removes real duplication (a
|
|
69
|
+
container, a generic algorithm over `constraints.Ordered`-like sets) —
|
|
70
|
+
do not generify a function with one concrete call site "for the future".
|
|
71
|
+
- Use `log/slog` for structured logging in new code, not `log.Printf` or a
|
|
72
|
+
bespoke logger, unless the project has already standardized on
|
|
73
|
+
something else.
|
|
74
|
+
- A `range-over-func` iterator (`func(yield func(T) bool)`) is fine for a
|
|
75
|
+
package's own lazy sequence API on Go 1.23+; do not introduce it purely
|
|
76
|
+
to look modern when a plain slice-returning function reads more clearly.
|
|
77
|
+
|
|
78
|
+
## Formatting and imports
|
|
79
|
+
|
|
80
|
+
- Format with `gofmt`/`goimports` before finishing a change; do not
|
|
81
|
+
hand-format around a formatter that is already configured (CI enforces
|
|
82
|
+
`gofmt -l` in most Go repos).
|
|
83
|
+
- Group imports stdlib / third-party / local with a blank line between
|
|
84
|
+
groups — `goimports` does this automatically; run it instead of
|
|
85
|
+
hand-ordering.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
extends: common
|
|
3
|
+
paths: ["**/*.go"]
|
|
4
|
+
metadata:
|
|
5
|
+
origin: authored
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Go patterns
|
|
9
|
+
|
|
10
|
+
Narrows `core-common-rules`' stack-agnostic design guidance to idiomatic
|
|
11
|
+
Go design and its common anti-patterns. Applies only to `*.go` files.
|
|
12
|
+
|
|
13
|
+
## Module and package layout
|
|
14
|
+
|
|
15
|
+
- `cmd/<binary>/` holds one `main` package per executable; `internal/`
|
|
16
|
+
holds packages this module's own code may import but nothing outside
|
|
17
|
+
the module can — put anything not meant as a public API surface there.
|
|
18
|
+
- A package should have a clear, single responsibility; a package that
|
|
19
|
+
only holds shared types with no behavior ("models", "types", "common")
|
|
20
|
+
invites import cycles as the project grows — prefer colocating a type
|
|
21
|
+
with the package that owns its behavior.
|
|
22
|
+
- Avoid import cycles by depth, not by breaking them with an `internal`
|
|
23
|
+
workaround package — if package A needs package B's type and B needs
|
|
24
|
+
A's, one of the two owns too much; extract the shared piece into a
|
|
25
|
+
third package both depend on.
|
|
26
|
+
|
|
27
|
+
## Idiomatic concurrency patterns
|
|
28
|
+
|
|
29
|
+
- Fan-out/fan-in: bound the number of concurrent workers (a worker pool or
|
|
30
|
+
`golang.org/x/sync/errgroup`'s `SetLimit`), never spawn one goroutine per
|
|
31
|
+
input item on an unbounded input source.
|
|
32
|
+
- Use `errgroup.Group` when a set of goroutines shares one cancellation
|
|
33
|
+
and you need the first error; use a plain `sync.WaitGroup` when you only
|
|
34
|
+
need to know they finished and errors are handled another way.
|
|
35
|
+
- Prefer channels for signaling and handoff, mutexes for protecting shared
|
|
36
|
+
state — do not build a hand-rolled semaphore out of a channel when
|
|
37
|
+
`sync.Mutex` (or `errgroup.SetLimit`) already says what you mean.
|
|
38
|
+
- Close a channel only from the sender, never the receiver, and only
|
|
39
|
+
once; a `nil` channel blocks forever on send/receive, which is
|
|
40
|
+
occasionally the correct way to disable a `select` case.
|
|
41
|
+
|
|
42
|
+
## Composition over inheritance
|
|
43
|
+
|
|
44
|
+
- Use struct embedding to reuse behavior only when the embedding type
|
|
45
|
+
genuinely "is-a" superset of the embedded one's API; prefer an explicit
|
|
46
|
+
field plus delegation when you would otherwise promote methods the
|
|
47
|
+
caller should not see.
|
|
48
|
+
- Functional options (`func WithTimeout(d time.Duration) Option`) for a
|
|
49
|
+
constructor with many optional parameters, instead of a boolean-heavy
|
|
50
|
+
positional signature or a half-filled config struct.
|
|
51
|
+
|
|
52
|
+
## Anti-patterns to flag
|
|
53
|
+
|
|
54
|
+
- A large `interface{}`/`any`-typed function signature where a generic
|
|
55
|
+
type parameter or a smaller concrete interface would give compile-time
|
|
56
|
+
safety back.
|
|
57
|
+
- A "god package" (`utils`, `helpers`, `common`) that accumulates
|
|
58
|
+
unrelated functions — split by what the code actually does.
|
|
59
|
+
- Returning a pointer to a struct solely to allow a `nil` "not found"
|
|
60
|
+
value where a `(T, bool)` or a named error (`ErrNotFound`) return is
|
|
61
|
+
clearer and avoids nil-pointer-dereference risk at the call site.
|
|
62
|
+
- Panic used for ordinary control flow (a missing map key, a failed
|
|
63
|
+
lookup); reserve `panic` for programmer errors that should crash during
|
|
64
|
+
development (a violated invariant, an unreachable `default` case), and
|
|
65
|
+
return an `error` for everything a caller could reasonably handle.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
extends: common
|
|
3
|
+
paths: ["**/*.go"]
|
|
4
|
+
metadata:
|
|
5
|
+
origin: authored
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Go security
|
|
9
|
+
|
|
10
|
+
Narrows `core-common-rules`' stack-agnostic security rules to Go-specific,
|
|
11
|
+
OWASP-relevant risks and the safe standard-library API to use instead.
|
|
12
|
+
Applies only to `*.go` files.
|
|
13
|
+
|
|
14
|
+
## Command and shell execution
|
|
15
|
+
|
|
16
|
+
- Build an argument list for `os/exec.Command(name, args...)`; never
|
|
17
|
+
interpolate untrusted input into a shell string passed to
|
|
18
|
+
`exec.Command("sh", "-c", cmd)` — that reintroduces shell injection that
|
|
19
|
+
`exec.Command`'s arg-list form avoids by construction.
|
|
20
|
+
- When a shell really is required (globbing, pipelines), validate/allowlist
|
|
21
|
+
every piece of untrusted input that reaches the string before it is
|
|
22
|
+
built, and say so in the change.
|
|
23
|
+
|
|
24
|
+
## Templating and output encoding
|
|
25
|
+
|
|
26
|
+
- Use `html/template` for any output rendered into HTML/JS/CSS/URL
|
|
27
|
+
context — it contextually auto-escapes. `text/template` performs no
|
|
28
|
+
escaping and is an XSS vector the moment its output reaches a browser;
|
|
29
|
+
reserve `text/template` for genuinely non-HTML output (config files,
|
|
30
|
+
emails in plain text).
|
|
31
|
+
|
|
32
|
+
## SQL and data access
|
|
33
|
+
|
|
34
|
+
- Use `database/sql` placeholders (`?` or `$1` depending on driver), never
|
|
35
|
+
`fmt.Sprintf`/string concatenation to build a query with any
|
|
36
|
+
user-influenced value — placeholders are the injection defense, not an
|
|
37
|
+
input-validation substitute for it.
|
|
38
|
+
- An ORM/query builder's raw-SQL escape hatch carries the same rule: pass
|
|
39
|
+
parameters through its placeholder API, not through interpolated
|
|
40
|
+
strings.
|
|
41
|
+
|
|
42
|
+
## Randomness and secrets
|
|
43
|
+
|
|
44
|
+
- Use `crypto/rand` for anything security-sensitive — tokens, session
|
|
45
|
+
IDs, keys, nonces. `math/rand`/`math/rand/v2` is deterministic given a
|
|
46
|
+
seed and unsuitable for secrets even though its API looks similar.
|
|
47
|
+
- Never hard-code a credential, API key, or signing secret in source;
|
|
48
|
+
load it from environment/secret storage the project already uses.
|
|
49
|
+
|
|
50
|
+
## Filesystem and path handling
|
|
51
|
+
|
|
52
|
+
- `filepath.Clean` normalizes a path but does not contain it — a cleaned
|
|
53
|
+
path can still climb outside an intended root via `..` before cleaning,
|
|
54
|
+
or via a symlink. For serving/opening files under a fixed root from an
|
|
55
|
+
untrusted relative path, prefer `os.Root` (Go 1.24+) or
|
|
56
|
+
`filepath.IsLocal` to confirm containment before opening, rather than
|
|
57
|
+
`filepath.Clean` alone.
|
|
58
|
+
|
|
59
|
+
## TLS and network
|
|
60
|
+
|
|
61
|
+
- Never set `InsecureSkipVerify: true` on a `tls.Config` outside of a
|
|
62
|
+
short-lived local test, and never ship it that way — it disables
|
|
63
|
+
certificate validation entirely, including hostname checks.
|
|
64
|
+
- Configure `http.Server` with explicit `ReadHeaderTimeout` (and
|
|
65
|
+
typically `ReadTimeout`/`WriteTimeout`/`IdleTimeout`); a server with no
|
|
66
|
+
timeouts is vulnerable to slow-client resource exhaustion (Slowloris).
|
|
67
|
+
|
|
68
|
+
## Dependency hygiene
|
|
69
|
+
|
|
70
|
+
- Run `govulncheck ./...` when introducing or updating dependencies, or
|
|
71
|
+
when asked to check a module for known vulnerabilities — it correlates
|
|
72
|
+
the Go vulnerability database against actually-reachable code paths,
|
|
73
|
+
not just declared dependency versions.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
extends: common
|
|
3
|
+
paths: ["**/*.go"]
|
|
4
|
+
metadata:
|
|
5
|
+
origin: authored
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Go testing
|
|
9
|
+
|
|
10
|
+
Narrows `core-common-rules`' stack-agnostic testing rules to the standard
|
|
11
|
+
`testing` package and its modern (1.23-1.25) additions. Applies only to
|
|
12
|
+
`*.go` files.
|
|
13
|
+
|
|
14
|
+
## Layout and naming
|
|
15
|
+
|
|
16
|
+
- Tests live beside the code they cover as `<file>_test.go` in the same
|
|
17
|
+
package (or `<pkg>_test` for a black-box test that only exercises the
|
|
18
|
+
exported API) — no separate `tests/` tree.
|
|
19
|
+
- Table-driven tests with `t.Run(tc.name, func(t *testing.T) { ... })`
|
|
20
|
+
subtests are the default shape for anything with more than one case;
|
|
21
|
+
name each case descriptively, not `case1`/`case2`.
|
|
22
|
+
- `testdata/` holds golden files and fixtures a test reads; Go's tooling
|
|
23
|
+
already excludes it from builds — do not invent another fixture
|
|
24
|
+
directory convention.
|
|
25
|
+
|
|
26
|
+
## Test helpers and lifecycle
|
|
27
|
+
|
|
28
|
+
- Mark a helper function `t.Helper()` as its first line so failures report
|
|
29
|
+
the caller's line, not the helper's.
|
|
30
|
+
- Use `t.Cleanup(func() { ... })` for teardown instead of a manual
|
|
31
|
+
`defer` chain scattered across a subtest — it composes correctly with
|
|
32
|
+
`t.Run` and parallel subtests.
|
|
33
|
+
- Use `t.Context()` (Go 1.24+) for a context that is canceled when the
|
|
34
|
+
test completes, instead of hand-rolling `context.WithCancel` plus a
|
|
35
|
+
`defer cancel()` in every test.
|
|
36
|
+
- Call `t.Parallel()` deliberately, only when the subtest's fixtures are
|
|
37
|
+
genuinely independent — a parallel subtest sharing mutable fixture
|
|
38
|
+
state races silently.
|
|
39
|
+
|
|
40
|
+
## Assertions and determinism
|
|
41
|
+
|
|
42
|
+
- Plain `if got != want { t.Errorf(...) }` (or the project's already-
|
|
43
|
+
configured assertion library) — do not introduce a new assertion
|
|
44
|
+
library into a project that has not adopted one.
|
|
45
|
+
- Never synchronize with `time.Sleep` to wait for a goroutine/async result
|
|
46
|
+
— use a channel, `sync.WaitGroup`, `context` deadline, or a polling
|
|
47
|
+
helper with a timeout so the test is deterministic and not flaky under
|
|
48
|
+
load.
|
|
49
|
+
- `httptest.NewServer`/`httptest.NewRecorder` for HTTP handler tests
|
|
50
|
+
instead of binding a real port.
|
|
51
|
+
|
|
52
|
+
## Fuzzing and benchmarks
|
|
53
|
+
|
|
54
|
+
- `func FuzzX(f *testing.F)` with `f.Add(...)` seed corpus entries for
|
|
55
|
+
parsers, decoders, or anything that touches untrusted input formats;
|
|
56
|
+
run locally with `go test -fuzz=FuzzX` before relying on it in CI.
|
|
57
|
+
- Benchmarks use `for b.Loop() { ... }` (Go 1.24+) rather than the older
|
|
58
|
+
`for i := 0; i < b.N; i++`; `b.Loop()` resets the timer automatically
|
|
59
|
+
and keeps loop-body values alive against dead-code elimination, so
|
|
60
|
+
results are not accidentally optimized away.
|
|
61
|
+
|
|
62
|
+
## Race detection and coverage
|
|
63
|
+
|
|
64
|
+
- Run `go test -race ./...` for any change touching goroutines, shared
|
|
65
|
+
state, or channels — the race detector catches data races unit
|
|
66
|
+
assertions cannot see.
|
|
67
|
+
- New behavior gets a new test in the same change; a bug fix gets a
|
|
68
|
+
regression test that fails before the fix and passes after.
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: go-build-fix
|
|
3
|
+
description: "Use when go build/go vet fails, or go.mod/go.sum are out of sync -- resolves module/toolchain mismatches, import cycles, generic type inference errors, staticcheck/golangci-lint failures, and a failing go test -race, with the smallest root-cause fix."
|
|
4
|
+
triggers:
|
|
5
|
+
- "go build is failing"
|
|
6
|
+
- "fix go.mod go.sum mismatch"
|
|
7
|
+
- "resolve this import cycle in Go"
|
|
8
|
+
- "go vet error"
|
|
9
|
+
- "golangci-lint is failing"
|
|
10
|
+
- "go test -race is failing"
|
|
11
|
+
metadata:
|
|
12
|
+
origin: authored
|
|
13
|
+
category: build-fix
|
|
14
|
+
version: "1.0.0"
|
|
15
|
+
compatible_harnesses: "claude,codex,cursor,zed,opencode"
|
|
16
|
+
license: "MIT"
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# Go build fix
|
|
20
|
+
|
|
21
|
+
Resolve a `go build`/`go vet` failure, a `go.mod`/`go.sum` mismatch, an
|
|
22
|
+
import cycle, a generic type-inference error, a `staticcheck`/
|
|
23
|
+
`golangci-lint` failure, or a failing `go test -race` — with the smallest
|
|
24
|
+
change that fixes the actual root cause. `rules/coding-style.mdc` and
|
|
25
|
+
`rules/security.mdc` govern what a "correct" fix looks like; this skill
|
|
26
|
+
never reaches for a suppression instead of a fix.
|
|
27
|
+
|
|
28
|
+
## Workflow
|
|
29
|
+
|
|
30
|
+
### Step 1: Reproduce and classify
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
go build ./...
|
|
34
|
+
go vet ./...
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Run the project's configured linter if present (`golangci-lint run
|
|
38
|
+
./...`, checked via a `.golangci.yml`/`.golangci.toml`). Read the exact
|
|
39
|
+
error text and classify it:
|
|
40
|
+
|
|
41
|
+
- **Compile error** (undefined symbol, type mismatch, wrong arg count).
|
|
42
|
+
- **Module/toolchain** (`go.mod`/`go.sum` mismatch, missing `go mod
|
|
43
|
+
tidy`, a `replace` directive pointing somewhere stale, a `go` /
|
|
44
|
+
`toolchain` directive older than a feature the code uses).
|
|
45
|
+
- **Import cycle** (`import cycle not allowed`).
|
|
46
|
+
- **Generic inference** (`cannot infer T`, a type parameter that cannot
|
|
47
|
+
be resolved from the call site).
|
|
48
|
+
- **Vet/lint finding** (`go vet`'s own checks, or a `staticcheck`/
|
|
49
|
+
`golangci-lint` rule).
|
|
50
|
+
- **Race** (`go test -race` reports a `DATA RACE`).
|
|
51
|
+
|
|
52
|
+
### Step 2: Fix by category
|
|
53
|
+
|
|
54
|
+
**Module/toolchain:** run `go mod tidy` when `go.sum` is simply stale
|
|
55
|
+
against `go.mod`'s requirements. For a genuine version conflict, check
|
|
56
|
+
`go mod why -m <module>` and `go mod graph` before bumping a version by
|
|
57
|
+
hand. Only add/edit a `replace` directive when it points at a real,
|
|
58
|
+
intentional local override (a monorepo sibling, a patched fork) — never
|
|
59
|
+
to paper over a version conflict without understanding it, and say so in
|
|
60
|
+
the report either way.
|
|
61
|
+
|
|
62
|
+
**Import cycle:** find the shared type/function both packages need and
|
|
63
|
+
extract it into a third package both can depend on, or invert one
|
|
64
|
+
dependency by defining the needed interface at the consumer (per
|
|
65
|
+
`rules/patterns.mdc`) instead of importing the concrete producer package.
|
|
66
|
+
Do not "fix" a cycle by merging the two packages into one unless they
|
|
67
|
+
were genuinely one responsibility already.
|
|
68
|
+
|
|
69
|
+
**Generic inference failure:** check whether the call site can supply the
|
|
70
|
+
type argument explicitly (`Func[T](...)`) before restructuring the
|
|
71
|
+
generic signature; if inference is failing because the type parameter
|
|
72
|
+
does not actually vary at the call sites, consider whether generics are
|
|
73
|
+
buying anything here at all.
|
|
74
|
+
|
|
75
|
+
**Vet/lint finding:** fix the underlying issue the finding names (e.g. a
|
|
76
|
+
real `printf`-format mismatch, an unreachable branch, an unused
|
|
77
|
+
`context.Context` parameter meant to be used). Never add `//nolint` or a
|
|
78
|
+
`_ = ` discard whose only purpose is to make the checker stop complaining
|
|
79
|
+
without addressing what it found.
|
|
80
|
+
|
|
81
|
+
**Race:** read the reported access pair (`go test -race`'s output names
|
|
82
|
+
both goroutines and lines). Add the missing synchronization (mutex,
|
|
83
|
+
channel handoff, `sync/atomic`) at the actual shared-state access point —
|
|
84
|
+
do not just serialize the whole test or add a `time.Sleep` to hide the
|
|
85
|
+
timing window.
|
|
86
|
+
|
|
87
|
+
### Step 3: Verify
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
go build ./...
|
|
91
|
+
go vet ./...
|
|
92
|
+
go test -race ./...
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Re-run the project's linter if it was part of the original failure. All
|
|
96
|
+
must exit 0 before reporting done.
|
|
97
|
+
|
|
98
|
+
### Step 4: Report
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
Fixed: go.mod/go.sum toolchain mismatch (ran `go mod tidy`)
|
|
102
|
+
- Root cause: go.sum predated a dependency bump in go.mod
|
|
103
|
+
- go build/vet/test -race all pass
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
State the root cause in one sentence, not just "fixed the error."
|
|
107
|
+
|
|
108
|
+
## Rules
|
|
109
|
+
|
|
110
|
+
- Find and fix the smallest change that addresses the actual root cause —
|
|
111
|
+
never widen a fix beyond what the failure requires.
|
|
112
|
+
- NEVER add `//nolint` or a blank `_ =` discard to silence a vet/lint
|
|
113
|
+
finding instead of fixing what it found.
|
|
114
|
+
- NEVER change the `go` directive or a major dependency version just to
|
|
115
|
+
make an error disappear without understanding why it changed.
|
|
116
|
+
- NEVER add a `replace` directive to route around a real compile error
|
|
117
|
+
without confirming it is an intentional, documented override.
|
|
118
|
+
- NEVER delete or skip a failing test to reach a green build.
|
|
119
|
+
|
|
120
|
+
## Red Flags
|
|
121
|
+
|
|
122
|
+
| Rationalization | Why it is wrong |
|
|
123
|
+
|---|---|
|
|
124
|
+
| "I'll add `//nolint:errcheck` here so the linter stops complaining" | Silences the finding without fixing the ignored error it caught; check the error instead |
|
|
125
|
+
| "Bumping the go directive to 1.25 makes this compile" | Changes the module's declared minimum toolchain for every consumer to dodge one error; understand why the code needs 1.25 first, or fix the code to work at the declared version |
|
|
126
|
+
| "This test is flaky under -race, I'll just run it without -race in CI" | Hides a real data race instead of fixing the missing synchronization; add the mutex/channel instead |
|
|
127
|
+
| "I'll merge these two packages to kill the import cycle" | A cycle usually means a shared piece belongs in a third package, not that the two packages were never separate — check the actual dependency shape first |
|
|
128
|
+
|
|
129
|
+
## Verification
|
|
130
|
+
|
|
131
|
+
Do not report the fix done until all of the following hold:
|
|
132
|
+
|
|
133
|
+
- `go build ./...`, `go vet ./...`, and `go test -race ./...` all exit 0.
|
|
134
|
+
- The project's linter (if configured) exits 0.
|
|
135
|
+
- The change is the smallest one that addresses the stated root cause —
|
|
136
|
+
no unrelated files touched.
|
|
137
|
+
- The report states the root cause in one sentence, not just "build now
|
|
138
|
+
passes."
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"triggers": {
|
|
3
|
+
"positive": [
|
|
4
|
+
"go build is failing with an undefined symbol error",
|
|
5
|
+
"go.mod and go.sum are out of sync, please fix",
|
|
6
|
+
"Resolve this Go import cycle between two internal packages",
|
|
7
|
+
"go vet is reporting a printf format error",
|
|
8
|
+
"golangci-lint is failing on this Go package",
|
|
9
|
+
"go test -race is failing with a data race, fix the build"
|
|
10
|
+
],
|
|
11
|
+
"negative": [
|
|
12
|
+
"npm install is failing with a peer dependency conflict",
|
|
13
|
+
"cargo build is failing for this Rust crate",
|
|
14
|
+
"pip install is failing for this Python project",
|
|
15
|
+
"Implement a new Go feature in the order package",
|
|
16
|
+
"Review this Go diff for concurrency bugs",
|
|
17
|
+
"Write Go tests for this function"
|
|
18
|
+
]
|
|
19
|
+
},
|
|
20
|
+
"scenarios": [
|
|
21
|
+
{
|
|
22
|
+
"id": "module-mismatch",
|
|
23
|
+
"prompt": "go build fails saying go.sum is out of date after I bumped a dependency in go.mod. How do I fix it?",
|
|
24
|
+
"strictness": "high",
|
|
25
|
+
"expected_behavior": [
|
|
26
|
+
{
|
|
27
|
+
"grader": "judge",
|
|
28
|
+
"rubric": "A correct answer identifies that go.sum is stale relative to go.mod's requirements after the dependency bump and fixes it by running `go mod tidy`. For a genuine version conflict it checks `go mod why`/`go mod graph` before bumping a version by hand, rather than routing around the error some other way.",
|
|
29
|
+
"pass_criteria": [
|
|
30
|
+
"Names `go mod tidy`, run from the module root, as the concrete command that resolves the stale go.sum -- not merely 'sync the files' or 'run the tool that fixes this'.",
|
|
31
|
+
"States the root cause: go.sum no longer matches what go.mod now requires after the version bump, not just 'run this command' with no explanation.",
|
|
32
|
+
"Either names a concrete verification step afterward (`go build ./...` and/or `go test ./...`) or does not suggest skipping verification."
|
|
33
|
+
],
|
|
34
|
+
"fail_criteria": [
|
|
35
|
+
"Recommends changing the `go` directive (the module's minimum toolchain version) to make the error go away, or bumping another dependency's version by hand, as a substitute for running `go mod tidy`.",
|
|
36
|
+
"Recommends hand-editing the hash lines in go.sum directly instead of regenerating it with `go mod tidy`."
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
],
|
|
40
|
+
"calibration": {
|
|
41
|
+
"known_right": "This means go.sum no longer matches what go.mod now requires after you bumped the dependency version. The fix is to run `go mod tidy` from the module root -- it recomputes go.sum against go.mod's require block, adding the new entries and dropping stale ones, and will also flag if the bump pulled in a transitive dependency that needs its own version resolved. If `go mod tidy` itself reports a version conflict (rather than a simple stale-sum error), don't just bump another module by hand -- run `go mod why -m <module>` and `go mod graph` first to see what's actually pulling in the conflicting version, so you understand the change before you make it. After `go mod tidy` finishes, re-run `go build ./...` and `go test ./...` to confirm the module is consistent again before considering this done. Avoid hand-editing the hashes in go.sum directly; that file is generated and meant to be regenerated by tooling, not patched by hand.",
|
|
42
|
+
"known_wrong": "Honestly the fastest fix here is to bump the go directive in go.mod to a newer toolchain version -- that usually makes go.sum errors like this go away without you needing to figure out what `go mod tidy` would even change. Just edit the `go 1.21` line to `go 1.25` and re-run the build; if it still complains, bump the specific dependency version in go.mod up a bit further too until the error clears. You don't really need to run `go mod why` or dig into the dependency graph for a simple sum mismatch like this -- that's overkill for what's usually just a version string being out of date.",
|
|
43
|
+
"vague": "This is just a dependency sync issue -- make sure your module files are consistent with each other again and the build should pass.",
|
|
44
|
+
"subtle_wrong": "Bump the dependency's version in go.mod directly to match what your code now needs, then try `go build` again -- if go.sum still complains about a missing sum for that version, add the missing hash lines to go.sum by hand so the two files line up. That gets you to a green build without having to run the whole module through `go mod tidy` and re-resolve everything else it might touch."
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"id": "no-nolint-suppression",
|
|
49
|
+
"prompt": "golangci-lint is flagging an ignored error return in my Go code. How should I fix it?",
|
|
50
|
+
"strictness": "high",
|
|
51
|
+
"expected_behavior": [
|
|
52
|
+
{
|
|
53
|
+
"grader": "judge",
|
|
54
|
+
"rubric": "A correct answer fixes the actual ignored error return -- checks it, wraps it with %w and returns/propagates it, or explicitly discards it with a comment explaining why -- instead of suppressing the linter finding with `//nolint` or a blank `_ =` discard, and instead of merely logging it without propagation.",
|
|
55
|
+
"pass_criteria": [
|
|
56
|
+
"Checks the error explicitly with an `if err != nil` branch (or equivalent) rather than leaving it dropped.",
|
|
57
|
+
"Shows the concrete fix: wraps and returns the error to the caller (e.g. `return fmt.Errorf(\"...: %w\", err)`), or explicitly discards it with a comment naming why that specific discard is safe -- not merely a statement that the error 'should be handled'. The prompt itself names no call site or code, so a concrete illustrative example in either shape (a wrap-and-return snippet, or a `_ = ... // reason` discard snippet) satisfies this requirement; it does not require identifying an 'actual flagged call site' the prompt never supplied.",
|
|
58
|
+
"Does not rely on `//nolint` or a bare `_ =` discard as the fix for the flagged finding."
|
|
59
|
+
],
|
|
60
|
+
"fail_criteria": [
|
|
61
|
+
"Recommends adding a `//nolint` comment (e.g. `//nolint:errcheck`) to silence the finding instead of handling the error.",
|
|
62
|
+
"Handles the error only by logging it (e.g. `log.Printf(...)` or `log.Println(...)`) with no return, no wrap, and no propagation to the caller, and no comment justifying why logging alone is a safe discard."
|
|
63
|
+
]
|
|
64
|
+
}
|
|
65
|
+
],
|
|
66
|
+
"calibration": {
|
|
67
|
+
"known_right": "golangci-lint's errcheck is telling you the returned error from that call is never examined, which usually means a real failure could pass through silently. Add an explicit `if err != nil { ... }` branch: if the error matters to the caller, wrap it with `fmt.Errorf(\"doing x: %w\", err)` and return it so callers can unwrap it with `errors.Is`/`errors.As`; if it genuinely doesn't matter (a best-effort `Close()`, for instance), discard it explicitly with a comment naming why, like `_ = f.Close() // best-effort cleanup, nothing to recover`. Don't reach for `//nolint:errcheck` here -- that just tells the linter to stop looking, it doesn't address whether the error mattered. Once you've handled it one way or the other, re-run golangci-lint to confirm the finding is actually resolved rather than merely hidden.",
|
|
68
|
+
"known_wrong": "The simplest fix is to just add `//nolint:errcheck` on the line above the call -- that error genuinely doesn't matter here, and it stops golangci-lint from flagging it every time CI runs. You don't need to touch the actual logic or add an if-check; the nolint directive is exactly what it's for. If the linter later flags something similar nearby, you can add the same `//nolint:errcheck` comment there too rather than working through each ignored error individually.",
|
|
69
|
+
"vague": "You should handle that error properly instead of suppressing the finding -- make sure it's actually checked and dealt with before you call this done.",
|
|
70
|
+
"subtle_wrong": "That errcheck finding is easy to clear without touching the surrounding logic: wrap the call in `if err != nil { log.Printf(\"unexpected error: %v\", err) }` so it shows up in the logs if it ever happens, and move on. That way you're not silently dropping it anymore, and you don't have to change the function's return signature or work out how the caller should react to it."
|
|
71
|
+
},
|
|
72
|
+
"anti_patterns": ["nolint"]
|
|
73
|
+
}
|
|
74
|
+
]
|
|
75
|
+
}
|