@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.
Files changed (100) hide show
  1. package/dist/cli.js +85355 -56749
  2. package/dist/core.js +28605 -18901
  3. package/package.json +2 -2
  4. package/src/gdgraph/affected-report.ts +141 -0
  5. package/src/gdgraph/build.ts +170 -23
  6. package/src/gdgraph/service.ts +6 -0
  7. package/src/gdgraph/staleness.ts +253 -45
  8. package/src/gdskills/bundled/agents/codebase-navigator.md +55 -0
  9. package/src/gdskills/bundled/agents/design-advisor.md +64 -0
  10. package/src/gdskills/bundled/agents/docs-maintainer.md +56 -0
  11. package/src/gdskills/bundled/agents/end-to-end-tester.md +56 -0
  12. package/src/gdskills/bundled/agents/error-path-auditor.md +57 -0
  13. package/src/gdskills/bundled/agents/go-build-fixer.md +52 -0
  14. package/src/gdskills/bundled/agents/go-code-auditor.md +49 -0
  15. package/src/gdskills/bundled/agents/performance-auditor.md +63 -0
  16. package/src/gdskills/bundled/agents/python-build-fixer.md +52 -0
  17. package/src/gdskills/bundled/agents/python-code-auditor.md +49 -0
  18. package/src/gdskills/bundled/agents/refactoring-steward.md +61 -0
  19. package/src/gdskills/bundled/agents/security-auditor.md +62 -0
  20. package/src/gdskills/bundled/agents/test-first-driver.md +61 -0
  21. package/src/gdskills/bundled/agents/work-planner.md +62 -0
  22. package/src/gdskills/bundled/install-manifest.json +530 -0
  23. package/src/gdskills/bundled/rules/core/skill-lifecycle.mdc +29 -1
  24. package/src/gdskills/bundled/rules/core/skills-storage-workflow.mdc +2 -2
  25. package/src/gdskills/bundled/skills/review/code-style-review/SKILL.md +1 -1
  26. package/src/gdskills/bundled/skills/review/review-orchestrator/SKILL.md +74 -246
  27. package/src/gdskills/bundled/skills/review/review-orchestrator/output-contract.schema.json +19 -0
  28. package/src/gdskills/bundled/skills/review/review-orchestrator/reviewer-finding.schema.json +10 -0
  29. package/src/gdskills/bundled/skills/review/review-orchestrator/reviewer-input.schema.json +5 -0
  30. package/src/gdskills/bundled/skills/review/review-orchestrator/templates/pr-comment-backend.md +50 -0
  31. package/src/gdskills/bundled/skills/review/review-orchestrator/templates/pr-comment-frontend.md +52 -0
  32. package/src/gdskills/bundled/skills/review/review-orchestrator/templates/review-report.md +143 -0
  33. package/src/gdskills/bundled/stacks/go/agent-refs.json +3 -0
  34. package/src/gdskills/bundled/stacks/go/governance/eval.json +1745 -0
  35. package/src/gdskills/bundled/stacks/go/governance/scout.json +31 -0
  36. package/src/gdskills/bundled/stacks/go/pack.json +41 -0
  37. package/src/gdskills/bundled/stacks/go/rules/coding-style.mdc +85 -0
  38. package/src/gdskills/bundled/stacks/go/rules/patterns.mdc +65 -0
  39. package/src/gdskills/bundled/stacks/go/rules/security.mdc +73 -0
  40. package/src/gdskills/bundled/stacks/go/rules/testing.mdc +68 -0
  41. package/src/gdskills/bundled/stacks/go/skills/go-build-fix/SKILL.md +138 -0
  42. package/src/gdskills/bundled/stacks/go/skills/go-build-fix/evals.json +75 -0
  43. package/src/gdskills/bundled/stacks/go/skills/go-code-review/SKILL.md +121 -0
  44. package/src/gdskills/bundled/stacks/go/skills/go-code-review/evals.json +72 -0
  45. package/src/gdskills/bundled/stacks/go/skills/go-implementation/SKILL.md +122 -0
  46. package/src/gdskills/bundled/stacks/go/skills/go-implementation/evals.json +76 -0
  47. package/src/gdskills/bundled/stacks/go/skills/go-testing/SKILL.md +126 -0
  48. package/src/gdskills/bundled/stacks/go/skills/go-testing/evals.json +73 -0
  49. package/src/gdskills/bundled/stacks/python/agent-refs.json +3 -0
  50. package/src/gdskills/bundled/stacks/python/governance/eval.json +1758 -0
  51. package/src/gdskills/bundled/stacks/python/governance/scout.json +34 -0
  52. package/src/gdskills/bundled/stacks/python/pack.json +41 -0
  53. package/src/gdskills/bundled/stacks/python/rules/coding-style.mdc +63 -0
  54. package/src/gdskills/bundled/stacks/python/rules/patterns.mdc +88 -0
  55. package/src/gdskills/bundled/stacks/python/rules/security.mdc +84 -0
  56. package/src/gdskills/bundled/stacks/python/rules/testing.mdc +77 -0
  57. package/src/gdskills/bundled/stacks/python/skills/python-build-fix/SKILL.md +144 -0
  58. package/src/gdskills/bundled/stacks/python/skills/python-build-fix/evals.json +74 -0
  59. package/src/gdskills/bundled/stacks/python/skills/python-code-review/SKILL.md +155 -0
  60. package/src/gdskills/bundled/stacks/python/skills/python-code-review/evals.json +72 -0
  61. package/src/gdskills/bundled/stacks/python/skills/python-implementation/SKILL.md +143 -0
  62. package/src/gdskills/bundled/stacks/python/skills/python-implementation/evals.json +78 -0
  63. package/src/gdskills/bundled/stacks/python/skills/python-testing/SKILL.md +132 -0
  64. package/src/gdskills/bundled/stacks/python/skills/python-testing/evals.json +73 -0
  65. package/src/gdskills/bundled/stacks/react/agent-refs.json +4 -0
  66. package/src/gdskills/bundled/stacks/react/governance/eval.json +2188 -0
  67. package/src/gdskills/bundled/stacks/react/governance/scout.json +40 -0
  68. package/src/gdskills/bundled/stacks/react/pack.json +42 -0
  69. package/src/gdskills/bundled/stacks/react/rules/coding-style.mdc +58 -0
  70. package/src/gdskills/bundled/stacks/react/rules/patterns.mdc +79 -0
  71. package/src/gdskills/bundled/stacks/react/rules/security.mdc +70 -0
  72. package/src/gdskills/bundled/stacks/react/rules/testing.mdc +60 -0
  73. package/src/gdskills/bundled/stacks/react/skills/react-build-fix/SKILL.md +139 -0
  74. package/src/gdskills/bundled/stacks/react/skills/react-build-fix/evals.json +72 -0
  75. package/src/gdskills/bundled/stacks/react/skills/react-code-review/SKILL.md +148 -0
  76. package/src/gdskills/bundled/stacks/react/skills/react-code-review/evals.json +74 -0
  77. package/src/gdskills/bundled/stacks/react/skills/react-implementation/SKILL.md +140 -0
  78. package/src/gdskills/bundled/stacks/react/skills/react-implementation/evals.json +74 -0
  79. package/src/gdskills/bundled/stacks/react/skills/react-testing/SKILL.md +142 -0
  80. package/src/gdskills/bundled/stacks/react/skills/react-testing/evals.json +83 -0
  81. package/src/gdskills/bundled/stacks/react/skills/react-upgrade-migration/SKILL.md +155 -0
  82. package/src/gdskills/bundled/stacks/react/skills/react-upgrade-migration/evals.json +74 -0
  83. package/src/gdskills/bundled/stacks/ts-js-node/agent-refs.json +4 -0
  84. package/src/gdskills/bundled/stacks/ts-js-node/governance/eval.json +2155 -0
  85. package/src/gdskills/bundled/stacks/ts-js-node/governance/scout.json +40 -0
  86. package/src/gdskills/bundled/stacks/ts-js-node/pack.json +41 -0
  87. package/src/gdskills/bundled/stacks/ts-js-node/rules/coding-style.mdc +73 -0
  88. package/src/gdskills/bundled/stacks/ts-js-node/rules/patterns.mdc +61 -0
  89. package/src/gdskills/bundled/stacks/ts-js-node/rules/security.mdc +71 -0
  90. package/src/gdskills/bundled/stacks/ts-js-node/rules/testing.mdc +63 -0
  91. package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-build-fix/SKILL.md +137 -0
  92. package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-build-fix/evals.json +73 -0
  93. package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-code-review/SKILL.md +124 -0
  94. package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-code-review/evals.json +74 -0
  95. package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-esm-migration/SKILL.md +152 -0
  96. package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-esm-migration/evals.json +71 -0
  97. package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-implementation/SKILL.md +127 -0
  98. package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-implementation/evals.json +72 -0
  99. package/src/gdskills/bundled/stacks/ts-js-node/skills/nodejs-testing/SKILL.md +134 -0
  100. 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
+ }