devflow-kit 1.1.0 → 1.2.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 (107) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +23 -6
  3. package/dist/plugins.js +67 -3
  4. package/package.json +2 -1
  5. package/plugins/devflow-accessibility/.claude-plugin/plugin.json +15 -0
  6. package/plugins/devflow-ambient/.claude-plugin/plugin.json +1 -1
  7. package/plugins/devflow-ambient/skills/ambient-router/SKILL.md +1 -1
  8. package/plugins/devflow-ambient/skills/ambient-router/references/skill-catalog.md +4 -0
  9. package/plugins/devflow-audit-claude/.claude-plugin/plugin.json +1 -1
  10. package/plugins/devflow-code-review/.claude-plugin/plugin.json +1 -4
  11. package/plugins/devflow-code-review/agents/reviewer.md +8 -0
  12. package/plugins/devflow-code-review/commands/code-review-teams.md +11 -1
  13. package/plugins/devflow-code-review/commands/code-review.md +12 -2
  14. package/plugins/devflow-core-skills/.claude-plugin/plugin.json +2 -6
  15. package/plugins/devflow-debug/.claude-plugin/plugin.json +1 -1
  16. package/plugins/devflow-frontend-design/.claude-plugin/plugin.json +15 -0
  17. package/plugins/devflow-go/.claude-plugin/plugin.json +15 -0
  18. package/plugins/devflow-go/skills/go/SKILL.md +187 -0
  19. package/plugins/devflow-go/skills/go/references/concurrency.md +312 -0
  20. package/plugins/devflow-go/skills/go/references/detection.md +129 -0
  21. package/plugins/devflow-go/skills/go/references/patterns.md +232 -0
  22. package/plugins/devflow-go/skills/go/references/violations.md +205 -0
  23. package/plugins/devflow-implement/.claude-plugin/plugin.json +1 -3
  24. package/plugins/devflow-implement/agents/coder.md +11 -6
  25. package/plugins/devflow-java/.claude-plugin/plugin.json +15 -0
  26. package/plugins/devflow-java/skills/java/SKILL.md +183 -0
  27. package/plugins/devflow-java/skills/java/references/detection.md +120 -0
  28. package/plugins/devflow-java/skills/java/references/modern-java.md +270 -0
  29. package/plugins/devflow-java/skills/java/references/patterns.md +235 -0
  30. package/plugins/devflow-java/skills/java/references/violations.md +213 -0
  31. package/plugins/devflow-python/.claude-plugin/plugin.json +15 -0
  32. package/plugins/devflow-python/skills/python/SKILL.md +188 -0
  33. package/plugins/devflow-python/skills/python/references/async.md +220 -0
  34. package/plugins/devflow-python/skills/python/references/detection.md +128 -0
  35. package/plugins/devflow-python/skills/python/references/patterns.md +226 -0
  36. package/plugins/devflow-python/skills/python/references/violations.md +204 -0
  37. package/plugins/devflow-react/.claude-plugin/plugin.json +15 -0
  38. package/plugins/{devflow-core-skills → devflow-react}/skills/react/SKILL.md +1 -1
  39. package/plugins/{devflow-core-skills → devflow-react}/skills/react/references/patterns.md +3 -3
  40. package/plugins/devflow-resolve/.claude-plugin/plugin.json +1 -1
  41. package/plugins/devflow-rust/.claude-plugin/plugin.json +15 -0
  42. package/plugins/devflow-rust/skills/rust/SKILL.md +193 -0
  43. package/plugins/devflow-rust/skills/rust/references/detection.md +131 -0
  44. package/plugins/devflow-rust/skills/rust/references/ownership.md +242 -0
  45. package/plugins/devflow-rust/skills/rust/references/patterns.md +210 -0
  46. package/plugins/devflow-rust/skills/rust/references/violations.md +191 -0
  47. package/plugins/devflow-self-review/.claude-plugin/plugin.json +1 -1
  48. package/plugins/devflow-specify/.claude-plugin/plugin.json +1 -1
  49. package/plugins/devflow-typescript/.claude-plugin/plugin.json +15 -0
  50. package/plugins/{devflow-core-skills → devflow-typescript}/skills/typescript/references/patterns.md +3 -3
  51. package/shared/agents/coder.md +11 -6
  52. package/shared/agents/reviewer.md +8 -0
  53. package/shared/skills/ambient-router/SKILL.md +1 -1
  54. package/shared/skills/ambient-router/references/skill-catalog.md +4 -0
  55. package/shared/skills/go/SKILL.md +187 -0
  56. package/shared/skills/go/references/concurrency.md +312 -0
  57. package/shared/skills/go/references/detection.md +129 -0
  58. package/shared/skills/go/references/patterns.md +232 -0
  59. package/shared/skills/go/references/violations.md +205 -0
  60. package/shared/skills/java/SKILL.md +183 -0
  61. package/shared/skills/java/references/detection.md +120 -0
  62. package/shared/skills/java/references/modern-java.md +270 -0
  63. package/shared/skills/java/references/patterns.md +235 -0
  64. package/shared/skills/java/references/violations.md +213 -0
  65. package/shared/skills/python/SKILL.md +188 -0
  66. package/shared/skills/python/references/async.md +220 -0
  67. package/shared/skills/python/references/detection.md +128 -0
  68. package/shared/skills/python/references/patterns.md +226 -0
  69. package/shared/skills/python/references/violations.md +204 -0
  70. package/shared/skills/react/SKILL.md +1 -1
  71. package/shared/skills/react/references/patterns.md +3 -3
  72. package/shared/skills/rust/SKILL.md +193 -0
  73. package/shared/skills/rust/references/detection.md +131 -0
  74. package/shared/skills/rust/references/ownership.md +242 -0
  75. package/shared/skills/rust/references/patterns.md +210 -0
  76. package/shared/skills/rust/references/violations.md +191 -0
  77. package/shared/skills/typescript/references/patterns.md +3 -3
  78. package/plugins/devflow-code-review/skills/react/SKILL.md +0 -276
  79. package/plugins/devflow-code-review/skills/react/references/patterns.md +0 -1331
  80. package/plugins/devflow-core-skills/skills/accessibility/SKILL.md +0 -229
  81. package/plugins/devflow-core-skills/skills/accessibility/references/detection.md +0 -171
  82. package/plugins/devflow-core-skills/skills/accessibility/references/patterns.md +0 -670
  83. package/plugins/devflow-core-skills/skills/accessibility/references/violations.md +0 -419
  84. package/plugins/devflow-core-skills/skills/frontend-design/SKILL.md +0 -254
  85. package/plugins/devflow-core-skills/skills/frontend-design/references/detection.md +0 -184
  86. package/plugins/devflow-core-skills/skills/frontend-design/references/patterns.md +0 -511
  87. package/plugins/devflow-core-skills/skills/frontend-design/references/violations.md +0 -453
  88. package/plugins/devflow-core-skills/skills/react/references/violations.md +0 -565
  89. package/plugins/devflow-implement/skills/accessibility/SKILL.md +0 -229
  90. package/plugins/devflow-implement/skills/accessibility/references/detection.md +0 -171
  91. package/plugins/devflow-implement/skills/accessibility/references/patterns.md +0 -670
  92. package/plugins/devflow-implement/skills/accessibility/references/violations.md +0 -419
  93. package/plugins/devflow-implement/skills/frontend-design/SKILL.md +0 -254
  94. package/plugins/devflow-implement/skills/frontend-design/references/detection.md +0 -184
  95. package/plugins/devflow-implement/skills/frontend-design/references/patterns.md +0 -511
  96. package/plugins/devflow-implement/skills/frontend-design/references/violations.md +0 -453
  97. /package/plugins/{devflow-code-review → devflow-accessibility}/skills/accessibility/SKILL.md +0 -0
  98. /package/plugins/{devflow-code-review → devflow-accessibility}/skills/accessibility/references/detection.md +0 -0
  99. /package/plugins/{devflow-code-review → devflow-accessibility}/skills/accessibility/references/patterns.md +0 -0
  100. /package/plugins/{devflow-code-review → devflow-accessibility}/skills/accessibility/references/violations.md +0 -0
  101. /package/plugins/{devflow-code-review → devflow-frontend-design}/skills/frontend-design/SKILL.md +0 -0
  102. /package/plugins/{devflow-code-review → devflow-frontend-design}/skills/frontend-design/references/detection.md +0 -0
  103. /package/plugins/{devflow-code-review → devflow-frontend-design}/skills/frontend-design/references/patterns.md +0 -0
  104. /package/plugins/{devflow-code-review → devflow-frontend-design}/skills/frontend-design/references/violations.md +0 -0
  105. /package/plugins/{devflow-code-review → devflow-react}/skills/react/references/violations.md +0 -0
  106. /package/plugins/{devflow-core-skills → devflow-typescript}/skills/typescript/SKILL.md +0 -0
  107. /package/plugins/{devflow-core-skills → devflow-typescript}/skills/typescript/references/violations.md +0 -0
@@ -0,0 +1,191 @@
1
+ # Rust Violation Examples
2
+
3
+ Extended violation patterns for Rust reviews. Reference from main SKILL.md.
4
+
5
+ ## Unwrap Abuse
6
+
7
+ ### Unwrap in Library Code
8
+
9
+ ```rust
10
+ // VIOLATION: Panics on None — caller has no way to handle failure
11
+ pub fn get_username(users: &HashMap<u64, String>, id: u64) -> &str {
12
+ users.get(&id).unwrap() // Panics if id not found
13
+ }
14
+
15
+ // VIOLATION: Unwrap on parse without context
16
+ let port: u16 = std::env::var("PORT").unwrap().parse().unwrap();
17
+ ```
18
+
19
+ ### Expect Without Useful Message
20
+
21
+ ```rust
22
+ // VIOLATION: Message doesn't help diagnose the problem
23
+ let config = load_config().expect("failed");
24
+
25
+ // CORRECT: Actionable message
26
+ let config = load_config().expect("failed to load config from config.toml — does file exist?");
27
+ ```
28
+
29
+ ---
30
+
31
+ ## Unnecessary Cloning
32
+
33
+ ### Clone to Satisfy Borrow Checker
34
+
35
+ ```rust
36
+ // VIOLATION: Cloning to work around borrow issues
37
+ fn process_items(items: &Vec<Item>) {
38
+ let cloned = items.clone(); // Entire Vec cloned
39
+ for item in &cloned {
40
+ println!("{}", item.name);
41
+ }
42
+ }
43
+
44
+ // CORRECT: Just borrow
45
+ fn process_items(items: &[Item]) {
46
+ for item in items {
47
+ println!("{}", item.name);
48
+ }
49
+ }
50
+ ```
51
+
52
+ ### Clone in Hot Loop
53
+
54
+ ```rust
55
+ // VIOLATION: Allocating on every iteration
56
+ for record in &records {
57
+ let key = record.id.clone(); // String allocation per iteration
58
+ map.insert(key, record);
59
+ }
60
+
61
+ // CORRECT: Borrow or use references
62
+ for record in &records {
63
+ map.insert(&record.id, record);
64
+ }
65
+ ```
66
+
67
+ ---
68
+
69
+ ## Stringly-Typed APIs
70
+
71
+ ### String Where Enum Belongs
72
+
73
+ ```rust
74
+ // VIOLATION: Any typo compiles and fails at runtime
75
+ fn set_status(status: &str) {
76
+ match status {
77
+ "active" => { /* ... */ }
78
+ "inactive" => { /* ... */ }
79
+ _ => panic!("unknown status"), // Runtime failure
80
+ }
81
+ }
82
+
83
+ // CORRECT: Compiler enforces valid values
84
+ enum Status { Active, Inactive }
85
+
86
+ fn set_status(status: Status) {
87
+ match status {
88
+ Status::Active => { /* ... */ }
89
+ Status::Inactive => { /* ... */ }
90
+ } // Exhaustive — no default needed
91
+ }
92
+ ```
93
+
94
+ ---
95
+
96
+ ## Unsafe Without Justification
97
+
98
+ ### Bare Unsafe Block
99
+
100
+ ```rust
101
+ // VIOLATION: No safety comment explaining invariants
102
+ unsafe {
103
+ let ptr = data.as_ptr();
104
+ std::ptr::copy_nonoverlapping(ptr, dest, len);
105
+ }
106
+
107
+ // CORRECT: Document why this is safe
108
+ // SAFETY: `data` is guaranteed to be valid for `len` bytes because
109
+ // it was allocated by `Vec::with_capacity(len)` and filled by `read_exact`.
110
+ // `dest` is a valid pointer from `alloc::alloc(layout)` with matching size.
111
+ unsafe {
112
+ std::ptr::copy_nonoverlapping(data.as_ptr(), dest, len);
113
+ }
114
+ ```
115
+
116
+ ### Unnecessary Unsafe
117
+
118
+ ```rust
119
+ // VIOLATION: Using unsafe when safe alternative exists
120
+ unsafe fn get_element(slice: &[u8], index: usize) -> u8 {
121
+ *slice.get_unchecked(index)
122
+ }
123
+
124
+ // CORRECT: Safe indexing with bounds check
125
+ fn get_element(slice: &[u8], index: usize) -> Option<u8> {
126
+ slice.get(index).copied()
127
+ }
128
+ ```
129
+
130
+ ---
131
+
132
+ ## Ignoring Results
133
+
134
+ ### Discarding Write Errors
135
+
136
+ ```rust
137
+ // VIOLATION: Write failure silently ignored
138
+ let _ = file.write_all(data);
139
+ let _ = file.flush();
140
+
141
+ // CORRECT: Propagate errors
142
+ file.write_all(data)?;
143
+ file.flush()?;
144
+ ```
145
+
146
+ ### Ignoring Lock Poisoning
147
+
148
+ ```rust
149
+ // VIOLATION: Silently ignoring poisoned mutex
150
+ let guard = mutex.lock().unwrap_or_else(|e| e.into_inner());
151
+
152
+ // CORRECT: Handle or propagate the poison
153
+ let guard = mutex.lock().map_err(|_| AppError::LockPoisoned)?;
154
+ ```
155
+
156
+ ---
157
+
158
+ ## Concurrency Violations
159
+
160
+ ### Shared Mutable State Without Synchronization
161
+
162
+ ```rust
163
+ // VIOLATION: Data race potential — no synchronization
164
+ static mut COUNTER: u64 = 0;
165
+
166
+ fn increment() {
167
+ unsafe { COUNTER += 1; } // Undefined behavior under concurrency
168
+ }
169
+
170
+ // CORRECT: Use atomic or mutex
171
+ use std::sync::atomic::{AtomicU64, Ordering};
172
+ static COUNTER: AtomicU64 = AtomicU64::new(0);
173
+
174
+ fn increment() {
175
+ COUNTER.fetch_add(1, Ordering::Relaxed);
176
+ }
177
+ ```
178
+
179
+ ### Blocking in Async Context
180
+
181
+ ```rust
182
+ // VIOLATION: Blocks the async runtime thread
183
+ async fn read_file(path: &str) -> Result<String, io::Error> {
184
+ std::fs::read_to_string(path) // Blocking call in async fn
185
+ }
186
+
187
+ // CORRECT: Use async file I/O or spawn_blocking
188
+ async fn read_file(path: &str) -> Result<String, io::Error> {
189
+ tokio::fs::read_to_string(path).await
190
+ }
191
+ ```
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "devflow-self-review",
3
3
  "description": "Self-review workflow: Simplifier + Scrutinizer for code quality",
4
- "version": "1.1.0",
4
+ "version": "1.2.0",
5
5
  "agents": ["simplifier", "scrutinizer", "validator"],
6
6
  "skills": ["self-review", "core-patterns"]
7
7
  }
@@ -5,7 +5,7 @@
5
5
  "name": "DevFlow Contributors",
6
6
  "email": "dean@keren.dev"
7
7
  },
8
- "version": "1.1.0",
8
+ "version": "1.2.0",
9
9
  "homepage": "https://github.com/dean0x/devflow",
10
10
  "repository": "https://github.com/dean0x/devflow",
11
11
  "license": "MIT",
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "devflow-typescript",
3
+ "description": "TypeScript language patterns - type safety, generics, utility types, type guards",
4
+ "author": {
5
+ "name": "DevFlow Contributors",
6
+ "email": "dean@keren.dev"
7
+ },
8
+ "version": "1.2.0",
9
+ "homepage": "https://github.com/dean0x/devflow",
10
+ "repository": "https://github.com/dean0x/devflow",
11
+ "license": "MIT",
12
+ "keywords": ["typescript", "types", "generics", "type-safety"],
13
+ "agents": [],
14
+ "skills": ["typescript"]
15
+ }
@@ -137,7 +137,7 @@ const isUndefined = (value: unknown): value is undefined =>
137
137
  const isNullish = (value: unknown): value is null | undefined =>
138
138
  value === null || value === undefined;
139
139
 
140
- const isFunction = (value: unknown): value is Function =>
140
+ const isFunction = (value: unknown): value is (...args: unknown[]) => unknown =>
141
141
  typeof value === 'function';
142
142
 
143
143
  const isObject = (value: unknown): value is object =>
@@ -760,7 +760,7 @@ function debounce<T extends (...args: any[]) => any>(
760
760
  fn: T,
761
761
  delayMs: number
762
762
  ): (...args: Parameters<T>) => void {
763
- let timeoutId: NodeJS.Timeout | null = null;
763
+ let timeoutId: ReturnType<typeof setTimeout> | null = null;
764
764
 
765
765
  return (...args: Parameters<T>) => {
766
766
  if (timeoutId) clearTimeout(timeoutId);
@@ -774,7 +774,7 @@ function throttle<T extends (...args: any[]) => any>(
774
774
  limitMs: number
775
775
  ): (...args: Parameters<T>) => void {
776
776
  let lastRun = 0;
777
- let timeoutId: NodeJS.Timeout | null = null;
777
+ let timeoutId: ReturnType<typeof setTimeout> | null = null;
778
778
 
779
779
  return (...args: Parameters<T>) => {
780
780
  const now = Date.now();
@@ -2,7 +2,7 @@
2
2
  name: Coder
3
3
  description: Autonomous task implementation on feature branch. Implements, tests, and commits.
4
4
  model: inherit
5
- skills: core-patterns, git-safety, implementation-patterns, git-workflow, typescript, react, test-patterns, input-validation, accessibility, frontend-design
5
+ skills: core-patterns, git-safety, implementation-patterns, git-workflow, test-patterns, input-validation
6
6
  ---
7
7
 
8
8
  # Coder Agent
@@ -33,11 +33,16 @@ You receive from orchestrator:
33
33
 
34
34
  2. **Reference handoff** (if PRIOR_PHASE_SUMMARY provided): Use summary to validate your understanding of prior work, not as the sole source of truth. The actual code is authoritative.
35
35
 
36
- 3. **Load domain skills**: Based on DOMAIN hint, apply relevant patterns:
37
- - `backend`: typescript, implementation-patterns, input-validation
38
- - `frontend`: react, typescript, accessibility, frontend-design
39
- - `tests`: test-patterns, typescript
40
- - `fullstack`: all of the above
36
+ 3. **Load domain skills**: Based on DOMAIN hint and files in scope, dynamically load relevant language/ecosystem skills by reading their SKILL.md. Only load skills that are installed:
37
+ - `backend` (TypeScript): Read `~/.claude/skills/typescript/SKILL.md`, `~/.claude/skills/input-validation/SKILL.md`
38
+ - `backend` (Go): Read `~/.claude/skills/go/SKILL.md`
39
+ - `backend` (Java): Read `~/.claude/skills/java/SKILL.md`
40
+ - `backend` (Python): Read `~/.claude/skills/python/SKILL.md`
41
+ - `backend` (Rust): Read `~/.claude/skills/rust/SKILL.md`
42
+ - `frontend`: Read `~/.claude/skills/react/SKILL.md`, `~/.claude/skills/typescript/SKILL.md`, `~/.claude/skills/accessibility/SKILL.md`, `~/.claude/skills/frontend-design/SKILL.md`
43
+ - `tests`: Read `~/.claude/skills/test-patterns/SKILL.md`, `~/.claude/skills/typescript/SKILL.md`
44
+ - `fullstack`: Combine backend + frontend skills
45
+ - If a Read fails (skill not installed), skip it silently and continue.
41
46
 
42
47
  4. **Implement the plan**: Work through execution steps systematically, creating and modifying files. Follow existing patterns. Type everything. Use Result types if codebase uses them.
43
48
 
@@ -34,6 +34,10 @@ The orchestrator provides:
34
34
  | `react` | `~/.claude/skills/react/SKILL.md` |
35
35
  | `accessibility` | `~/.claude/skills/accessibility/SKILL.md` |
36
36
  | `frontend-design` | `~/.claude/skills/frontend-design/SKILL.md` |
37
+ | `go` | `~/.claude/skills/go/SKILL.md` |
38
+ | `java` | `~/.claude/skills/java/SKILL.md` |
39
+ | `python` | `~/.claude/skills/python/SKILL.md` |
40
+ | `rust` | `~/.claude/skills/rust/SKILL.md` |
37
41
 
38
42
  ## Responsibilities
39
43
 
@@ -117,3 +121,7 @@ Report format for `{output_path}`:
117
121
  | react | If .tsx/.jsx files changed |
118
122
  | accessibility | If .tsx/.jsx files changed |
119
123
  | frontend-design | If .tsx/.jsx/.css/.scss files changed |
124
+ | go | If .go files changed |
125
+ | java | If .java files changed |
126
+ | python | If .py files changed |
127
+ | rust | If .rs files changed |
@@ -54,7 +54,7 @@ Based on classified intent, read the following skills to inform your response.
54
54
 
55
55
  | Intent | Primary Skills | Secondary (if file type matches) |
56
56
  |--------|---------------|----------------------------------|
57
- | **BUILD** | test-driven-development, implementation-patterns | typescript (.ts), react (.tsx/.jsx), frontend-design (CSS/UI), input-validation (forms/API), security-patterns (auth/crypto) |
57
+ | **BUILD** | test-driven-development, implementation-patterns | typescript (.ts), react (.tsx/.jsx), go (.go), java (.java), python (.py), rust (.rs), frontend-design (CSS/UI), input-validation (forms/API), security-patterns (auth/crypto) |
58
58
  | **DEBUG** | test-patterns, core-patterns | git-safety (if git operations involved) |
59
59
  | **REVIEW** | self-review, core-patterns | test-patterns |
60
60
  | **PLAN** | implementation-patterns | core-patterns |
@@ -16,6 +16,10 @@ These skills may be loaded during STANDARD-depth ambient routing.
16
16
  | react | React components in scope | `*.tsx`, `*.jsx` |
17
17
  | frontend-design | UI/styling work | `*.css`, `*.scss`, `*.tsx` with styling keywords |
18
18
  | input-validation | Forms, APIs, user input | Files with form/input/validation keywords |
19
+ | go | Go files in scope | `*.go` |
20
+ | java | Java files in scope | `*.java` |
21
+ | python | Python files in scope | `*.py` |
22
+ | rust | Rust files in scope | `*.rs` |
19
23
  | security-patterns | Auth, crypto, secrets | Files with auth/token/crypto/password keywords |
20
24
 
21
25
  ### DEBUG Intent
@@ -0,0 +1,187 @@
1
+ ---
2
+ name: go
3
+ description: This skill should be used when the user works with Go files (.go), asks about "error handling", "interfaces", "goroutines", "channels", "packages", or discusses Go idioms and concurrency. Provides patterns for error handling, interface design, concurrency, and package organization.
4
+ user-invocable: false
5
+ allowed-tools: Read, Grep, Glob
6
+ activation:
7
+ file-patterns:
8
+ - "**/*.go"
9
+ exclude:
10
+ - "vendor/**"
11
+ ---
12
+
13
+ # Go Patterns
14
+
15
+ Reference for Go-specific patterns, idioms, and best practices.
16
+
17
+ ## Iron Law
18
+
19
+ > **ERRORS ARE VALUES**
20
+ >
21
+ > Never ignore errors. `if err != nil` is correctness, not boilerplate. Every error
22
+ > return must be checked, wrapped with context, or explicitly documented as intentionally
23
+ > ignored with `_ = fn()`. Silent error swallowing causes cascading failures.
24
+
25
+ ## When This Skill Activates
26
+
27
+ - Working with Go codebases
28
+ - Designing interfaces and packages
29
+ - Implementing concurrent code
30
+ - Handling errors
31
+ - Structuring Go projects
32
+
33
+ ---
34
+
35
+ ## Error Handling
36
+
37
+ ### Wrap Errors with Context
38
+
39
+ ```go
40
+ // BAD: return err
41
+ // GOOD: return fmt.Errorf("reading config %s: %w", path, err)
42
+ ```
43
+
44
+ ### Sentinel Errors for Expected Conditions
45
+
46
+ ```go
47
+ var ErrNotFound = errors.New("not found")
48
+
49
+ func FindUser(id string) (*User, error) {
50
+ u, err := db.Get(id)
51
+ if err != nil {
52
+ return nil, fmt.Errorf("finding user %s: %w", id, err)
53
+ }
54
+ if u == nil {
55
+ return nil, ErrNotFound
56
+ }
57
+ return u, nil
58
+ }
59
+ // Caller: if errors.Is(err, ErrNotFound) { ... }
60
+ ```
61
+
62
+ ---
63
+
64
+ ## Interface Design
65
+
66
+ ### Accept Interfaces, Return Structs
67
+
68
+ ```go
69
+ // BAD: func NewService(repo *PostgresRepo) *Service
70
+ // GOOD: func NewService(repo Repository) *Service
71
+
72
+ type Repository interface {
73
+ FindByID(ctx context.Context, id string) (*Entity, error)
74
+ Save(ctx context.Context, entity *Entity) error
75
+ }
76
+ ```
77
+
78
+ ### Keep Interfaces Small
79
+
80
+ ```go
81
+ // BAD: 10-method interface
82
+ // GOOD: single-method interfaces composed as needed
83
+ type Reader interface { Read(p []byte) (n int, err error) }
84
+ type Writer interface { Write(p []byte) (n int, err error) }
85
+ type ReadWriter interface { Reader; Writer }
86
+ ```
87
+
88
+ ---
89
+
90
+ ## Concurrency
91
+
92
+ ### Use Context for Cancellation
93
+
94
+ ```go
95
+ func Process(ctx context.Context, items []Item) error {
96
+ g, ctx := errgroup.WithContext(ctx)
97
+ for _, item := range items {
98
+ g.Go(func() error {
99
+ return processItem(ctx, item)
100
+ })
101
+ }
102
+ return g.Wait()
103
+ }
104
+ ```
105
+
106
+ ### Channel Direction
107
+
108
+ ```go
109
+ // Declare direction in function signatures
110
+ func producer(ch chan<- int) { ch <- 42 }
111
+ func consumer(ch <-chan int) { v := <-ch; _ = v }
112
+ ```
113
+
114
+ ---
115
+
116
+ ## Package Design
117
+
118
+ ### Organize by Domain, Not by Type
119
+
120
+ ```go
121
+ // BAD: models/, controllers/, services/
122
+ // GOOD: user/, order/, payment/
123
+ ```
124
+
125
+ ### Export Only What's Needed
126
+
127
+ ```go
128
+ // Internal helpers stay unexported (lowercase)
129
+ func (s *Service) validate(u *User) error { ... }
130
+
131
+ // Public API is exported (uppercase)
132
+ func (s *Service) CreateUser(ctx context.Context, req CreateUserReq) (*User, error) { ... }
133
+ ```
134
+
135
+ ---
136
+
137
+ ## Zero Values
138
+
139
+ ```go
140
+ // Use zero values as valid defaults
141
+ var mu sync.Mutex // Ready to use
142
+ var buf bytes.Buffer // Ready to use
143
+ var wg sync.WaitGroup // Ready to use
144
+
145
+ // Design types with useful zero values
146
+ type Config struct {
147
+ Timeout time.Duration // zero = no timeout
148
+ Retries int // zero = no retries
149
+ }
150
+ ```
151
+
152
+ ---
153
+
154
+ ## Anti-Patterns
155
+
156
+ | Pattern | Bad | Good |
157
+ |---------|-----|------|
158
+ | Ignoring error | `val, _ := fn()` | `val, err := fn(); if err != nil { ... }` |
159
+ | Naked return | `return` in named returns | Explicit `return val, err` |
160
+ | init() abuse | Complex `init()` functions | Explicit initialization in `main()` or constructors |
161
+ | Interface pollution | Defining interfaces before use | Define interfaces at the consumer site |
162
+ | Goroutine leak | `go fn()` without lifecycle | Use context, errgroup, or done channels |
163
+
164
+ ---
165
+
166
+ ## Extended References
167
+
168
+ For additional patterns and examples:
169
+ - `references/violations.md` - Common Go violations
170
+ - `references/patterns.md` - Extended Go patterns
171
+ - `references/detection.md` - Detection patterns for Go issues
172
+ - `references/concurrency.md` - Advanced concurrency patterns
173
+
174
+ ---
175
+
176
+ ## Checklist
177
+
178
+ - [ ] All errors checked or explicitly ignored with `_ =`
179
+ - [ ] Errors wrapped with `fmt.Errorf("context: %w", err)`
180
+ - [ ] Interfaces defined at consumer, not producer
181
+ - [ ] Interfaces kept small (1-3 methods)
182
+ - [ ] Context passed as first parameter
183
+ - [ ] Goroutines have clear lifecycle/cancellation
184
+ - [ ] Channel direction specified in signatures
185
+ - [ ] Zero values are useful defaults
186
+ - [ ] Packages organized by domain
187
+ - [ ] No `init()` with side effects