swe-workflow-skills 0.1.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 (177) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +144 -0
  3. package/VERSION +1 -0
  4. package/bin/cli.mjs +44 -0
  5. package/catalog.json +225 -0
  6. package/commands/role.md +34 -0
  7. package/hooks/session-start.mjs +118 -0
  8. package/install.mjs +318 -0
  9. package/package.json +47 -0
  10. package/roles.json +194 -0
  11. package/scripts/resolve.mjs +296 -0
  12. package/skills/accessibility-design/SKILL.md +128 -0
  13. package/skills/accessibility-design/evals/evals.json +51 -0
  14. package/skills/accessibility-design/references/accessibility-patterns.md +321 -0
  15. package/skills/api-design/SKILL.md +144 -0
  16. package/skills/api-design/evals/evals.json +48 -0
  17. package/skills/api-design/references/rest-conventions.md +147 -0
  18. package/skills/api-design/templates/api-spec.md +156 -0
  19. package/skills/architecture-design/SKILL.md +86 -0
  20. package/skills/architecture-design/evals/evals.json +44 -0
  21. package/skills/architecture-design/references/clean-architecture.md +147 -0
  22. package/skills/architecture-design/references/component-principles.md +129 -0
  23. package/skills/architecture-design/references/principles.md +81 -0
  24. package/skills/architecture-design/references/solid-principles.md +106 -0
  25. package/skills/architecture-design/templates/adr.md +63 -0
  26. package/skills/architecture-documentation/SKILL.md +126 -0
  27. package/skills/architecture-documentation/evals/evals.json +44 -0
  28. package/skills/architecture-documentation/references/abstraction-levels.md +91 -0
  29. package/skills/architecture-documentation/references/diagram-tooling.md +141 -0
  30. package/skills/architecture-documentation/templates/architecture-doc.md +171 -0
  31. package/skills/bug-investigating/SKILL.md +133 -0
  32. package/skills/bug-investigating/evals/evals.json +56 -0
  33. package/skills/bug-investigating/references/common-bugs.md +62 -0
  34. package/skills/bug-investigating/references/debugging-patterns.md +94 -0
  35. package/skills/cicd-pipeline/SKILL.md +87 -0
  36. package/skills/cicd-pipeline/evals/evals.json +34 -0
  37. package/skills/cicd-pipeline/references/pipeline-patterns.md +206 -0
  38. package/skills/cicd-pipeline/templates/github-actions.md +206 -0
  39. package/skills/code-reviewing/SKILL.md +92 -0
  40. package/skills/code-reviewing/evals/evals.json +62 -0
  41. package/skills/code-reviewing/references/error-handling.md +108 -0
  42. package/skills/code-reviewing/references/review-checklist.md +144 -0
  43. package/skills/configuration-strategy/SKILL.md +109 -0
  44. package/skills/configuration-strategy/evals/evals.json +41 -0
  45. package/skills/configuration-strategy/references/config-patterns.md +161 -0
  46. package/skills/containerization/SKILL.md +90 -0
  47. package/skills/containerization/evals/evals.json +36 -0
  48. package/skills/containerization/references/dockerfile-patterns.md +168 -0
  49. package/skills/containerization/templates/dockerfile.md +154 -0
  50. package/skills/data-modeling/SKILL.md +83 -0
  51. package/skills/data-modeling/evals/evals.json +43 -0
  52. package/skills/data-modeling/references/conventions.md +57 -0
  53. package/skills/data-modeling/templates/schema.md +120 -0
  54. package/skills/dependency-impact-analysis/SKILL.md +113 -0
  55. package/skills/dependency-impact-analysis/evals/evals.json +41 -0
  56. package/skills/dependency-impact-analysis/references/impact-patterns.md +150 -0
  57. package/skills/dependency-management/SKILL.md +161 -0
  58. package/skills/dependency-management/evals/evals.json +48 -0
  59. package/skills/dependency-management/references/evaluation-checklist.md +127 -0
  60. package/skills/deployment-checklist/SKILL.md +132 -0
  61. package/skills/deployment-checklist/evals/evals.json +58 -0
  62. package/skills/deployment-checklist/references/pre-deploy-gates.md +91 -0
  63. package/skills/deployment-repo/SKILL.md +190 -0
  64. package/skills/deployment-repo/evals/evals.json +44 -0
  65. package/skills/deployment-repo/references/deployment-repo-patterns.md +258 -0
  66. package/skills/deployment-repo/references/version-compatibility.md +227 -0
  67. package/skills/deployment-repo/templates/deployment-repo-structure.md +226 -0
  68. package/skills/effort-estimation/SKILL.md +95 -0
  69. package/skills/effort-estimation/evals/evals.json +32 -0
  70. package/skills/effort-estimation/references/estimation-methods.md +154 -0
  71. package/skills/feature-planning/SKILL.md +84 -0
  72. package/skills/feature-planning/evals/evals.json +44 -0
  73. package/skills/feature-planning/templates/plan.md +55 -0
  74. package/skills/feature-planning/templates/task.md +26 -0
  75. package/skills/frontend-architecture/SKILL.md +154 -0
  76. package/skills/frontend-architecture/evals/evals.json +34 -0
  77. package/skills/frontend-architecture/references/component-patterns.md +264 -0
  78. package/skills/frontend-architecture/templates/folder-structure.md +203 -0
  79. package/skills/git-workflow/SKILL.md +127 -0
  80. package/skills/git-workflow/evals/evals.json +44 -0
  81. package/skills/git-workflow/references/conventions.md +142 -0
  82. package/skills/git-workflow/templates/pull-request.md +57 -0
  83. package/skills/gitops-delivery/SKILL.md +319 -0
  84. package/skills/gitops-delivery/evals/evals.json +44 -0
  85. package/skills/gitops-delivery/references/gitops-patterns.md +478 -0
  86. package/skills/gitops-delivery/templates/gitops-config.md +196 -0
  87. package/skills/incident-response/SKILL.md +130 -0
  88. package/skills/incident-response/evals/evals.json +55 -0
  89. package/skills/incident-response/references/communication-templates.md +134 -0
  90. package/skills/incident-response/references/severity-levels.md +77 -0
  91. package/skills/incident-response/templates/incident-timeline.md +57 -0
  92. package/skills/infrastructure-as-code/SKILL.md +86 -0
  93. package/skills/infrastructure-as-code/evals/evals.json +33 -0
  94. package/skills/infrastructure-as-code/references/iac-patterns.md +179 -0
  95. package/skills/infrastructure-as-code/templates/terraform-module.md +158 -0
  96. package/skills/metrics-and-okrs/SKILL.md +113 -0
  97. package/skills/metrics-and-okrs/evals/evals.json +33 -0
  98. package/skills/metrics-and-okrs/references/metric-catalog.md +90 -0
  99. package/skills/metrics-and-okrs/templates/okr-document.md +61 -0
  100. package/skills/ml-experiment-tracking/SKILL.md +96 -0
  101. package/skills/ml-experiment-tracking/evals/evals.json +32 -0
  102. package/skills/ml-experiment-tracking/references/tracking-tools.md +127 -0
  103. package/skills/ml-model-deployment/SKILL.md +106 -0
  104. package/skills/ml-model-deployment/evals/evals.json +34 -0
  105. package/skills/ml-model-deployment/references/serving-patterns.md +162 -0
  106. package/skills/ml-pipeline-design/SKILL.md +162 -0
  107. package/skills/ml-pipeline-design/evals/evals.json +34 -0
  108. package/skills/ml-pipeline-design/references/pipeline-components.md +174 -0
  109. package/skills/observability-design/SKILL.md +162 -0
  110. package/skills/observability-design/evals/evals.json +52 -0
  111. package/skills/observability-design/references/logging-patterns.md +229 -0
  112. package/skills/observability-design/references/slo-framework.md +151 -0
  113. package/skills/observability-design/templates/slo-document.md +80 -0
  114. package/skills/performance-optimization/SKILL.md +83 -0
  115. package/skills/performance-optimization/evals/evals.json +47 -0
  116. package/skills/performance-optimization/references/bottleneck-patterns.md +256 -0
  117. package/skills/performance-optimization/references/concurrency.md +101 -0
  118. package/skills/prd-writing/SKILL.md +109 -0
  119. package/skills/prd-writing/evals/evals.json +33 -0
  120. package/skills/prd-writing/references/prd-examples.md +132 -0
  121. package/skills/prd-writing/templates/prd.md +71 -0
  122. package/skills/prd-writing/templates/rfc.md +79 -0
  123. package/skills/project-documentation/SKILL.md +104 -0
  124. package/skills/project-documentation/evals/evals.json +48 -0
  125. package/skills/project-documentation/references/contributing-guide.md +100 -0
  126. package/skills/project-documentation/templates/changelog.md +59 -0
  127. package/skills/project-documentation/templates/readme.md +121 -0
  128. package/skills/project-proposal/SKILL.md +90 -0
  129. package/skills/project-proposal/evals/evals.json +31 -0
  130. package/skills/project-proposal/references/proposal-examples.md +140 -0
  131. package/skills/project-proposal/templates/proposal.md +76 -0
  132. package/skills/project-review/SKILL.md +111 -0
  133. package/skills/project-review/evals/evals.json +42 -0
  134. package/skills/refactoring/SKILL.md +90 -0
  135. package/skills/refactoring/evals/evals.json +44 -0
  136. package/skills/refactoring/references/transformations.md +132 -0
  137. package/skills/retrospective/SKILL.md +157 -0
  138. package/skills/retrospective/evals/evals.json +34 -0
  139. package/skills/retrospective/references/facilitation-guide.md +130 -0
  140. package/skills/retrospective/templates/post-mortem.md +121 -0
  141. package/skills/rollback-strategy/SKILL.md +116 -0
  142. package/skills/rollback-strategy/evals/evals.json +55 -0
  143. package/skills/rollback-strategy/references/rollback-patterns.md +125 -0
  144. package/skills/rollback-strategy/templates/rollback-plan.md +69 -0
  145. package/skills/security-audit/SKILL.md +146 -0
  146. package/skills/security-audit/evals/evals.json +66 -0
  147. package/skills/security-audit/references/owasp-top-10.md +167 -0
  148. package/skills/security-audit/templates/security-report.md +79 -0
  149. package/skills/skill-router/SKILL.md +171 -0
  150. package/skills/skill-router/evals/evals.json +39 -0
  151. package/skills/strategic-review/SKILL.md +106 -0
  152. package/skills/strategic-review/evals/evals.json +42 -0
  153. package/skills/strategic-review/templates/full-review-prompt.md +84 -0
  154. package/skills/tdd-workflow/SKILL.md +147 -0
  155. package/skills/tdd-workflow/evals/evals.json +58 -0
  156. package/skills/tdd-workflow/references/test-quality.md +71 -0
  157. package/skills/technical-debt-review/SKILL.md +113 -0
  158. package/skills/technical-debt-review/evals/evals.json +41 -0
  159. package/skills/technical-debt-review/references/debt-taxonomy.md +124 -0
  160. package/skills/technical-debt-review/templates/debt-audit.md +85 -0
  161. package/skills/test-data-strategy/SKILL.md +129 -0
  162. package/skills/test-data-strategy/evals/evals.json +49 -0
  163. package/skills/test-data-strategy/references/data-generation-patterns.md +341 -0
  164. package/skills/test-suite-design/SKILL.md +137 -0
  165. package/skills/test-suite-design/evals/evals.json +69 -0
  166. package/skills/test-suite-design/references/test-infrastructure.md +175 -0
  167. package/skills/test-suite-design/references/testing-pyramid.md +140 -0
  168. package/skills/ui-ux-design/SKILL.md +117 -0
  169. package/skills/ui-ux-design/evals/evals.json +35 -0
  170. package/skills/ui-ux-design/references/interaction-patterns.md +145 -0
  171. package/skills/ui-ux-design/templates/screen-spec.md +97 -0
  172. package/skills/verification-before-completion/SKILL.md +85 -0
  173. package/skills/verification-before-completion/evals/evals.json +53 -0
  174. package/skills/writing-skills/SKILL.md +87 -0
  175. package/skills/writing-skills/evals/evals.json +41 -0
  176. package/skills/writing-skills/references/pressure-testing.md +69 -0
  177. package/uninstall.mjs +182 -0
@@ -0,0 +1,256 @@
1
+ # Bottleneck Detection Patterns
2
+
3
+ ## Contents
4
+ - Database bottlenecks
5
+ - Algorithmic bottlenecks
6
+ - Memory bottlenecks
7
+ - Network and I/O bottlenecks
8
+ - Frontend-specific bottlenecks
9
+ - Caching strategies
10
+
11
+ ## Database Bottlenecks
12
+
13
+ ### N+1 Query Problem
14
+
15
+ **Signature**: A loop that makes one database query per iteration.
16
+
17
+ ```javascript
18
+ // BAD: N+1 — 1 query for orders + N queries for users
19
+ const orders = await db.orders.findMany();
20
+ for (const order of orders) {
21
+ order.user = await db.users.findById(order.userId); // N queries!
22
+ }
23
+
24
+ // GOOD: Eager loading — 2 queries total
25
+ const orders = await db.orders.findMany({
26
+ include: { user: true }
27
+ });
28
+
29
+ // GOOD: Batch loading — 2 queries total
30
+ const orders = await db.orders.findMany();
31
+ const userIds = [...new Set(orders.map(o => o.userId))];
32
+ const users = await db.users.findMany({ where: { id: { in: userIds } } });
33
+ const userMap = new Map(users.map(u => [u.id, u]));
34
+ orders.forEach(o => o.user = userMap.get(o.userId));
35
+ ```
36
+
37
+ **How to detect**: Look for database calls inside loops, `.map()`, `.forEach()`, or Promise.all with individual queries. Also check ORM lazy-loading that triggers queries on property access.
38
+
39
+ ### Missing Indexes
40
+
41
+ **Signature**: Slow queries on columns used in WHERE, JOIN, ORDER BY, or GROUP BY.
42
+
43
+ ```sql
44
+ -- If this is slow, check if there's an index on user_id and created_at
45
+ SELECT * FROM orders
46
+ WHERE user_id = 123
47
+ ORDER BY created_at DESC
48
+ LIMIT 20;
49
+
50
+ -- Fix: Add a compound index
51
+ CREATE INDEX idx_orders_user_id_created_at ON orders(user_id, created_at DESC);
52
+ ```
53
+
54
+ **How to detect**: Run `EXPLAIN ANALYZE` on slow queries. Look for "Seq Scan" on large tables — that usually means a missing index.
55
+
56
+ **Index rules of thumb:**
57
+ - Index columns in WHERE clauses that filter large tables
58
+ - Index columns in JOIN conditions
59
+ - Compound indexes should match the query's column order
60
+ - Don't index columns with very low cardinality (boolean flags on huge tables)
61
+ - Every index slows writes — don't over-index
62
+
63
+ ### SELECT * Anti-pattern
64
+
65
+ **Signature**: Selecting all columns when only a few are needed.
66
+
67
+ ```javascript
68
+ // BAD: Loads entire row including large text columns
69
+ const users = await db.query('SELECT * FROM users');
70
+
71
+ // GOOD: Only fetch what's needed
72
+ const users = await db.query('SELECT id, name, email FROM users');
73
+ ```
74
+
75
+ Especially impactful when tables have large TEXT/BLOB columns or many unused columns.
76
+
77
+ ### Unoptimized Pagination
78
+
79
+ **Signature**: Using OFFSET on large tables.
80
+
81
+ ```sql
82
+ -- BAD: Database must scan and discard 100,000 rows
83
+ SELECT * FROM events ORDER BY created_at OFFSET 100000 LIMIT 20;
84
+
85
+ -- GOOD: Cursor-based — database seeks directly
86
+ SELECT * FROM events
87
+ WHERE created_at < '2025-01-15T10:00:00Z'
88
+ ORDER BY created_at DESC
89
+ LIMIT 20;
90
+ ```
91
+
92
+ OFFSET performance degrades linearly with page number. Cursor-based pagination is O(1).
93
+
94
+ ## Algorithmic Bottlenecks
95
+
96
+ ### Hidden O(n²)
97
+
98
+ **Signature**: Nested loops over collections, often disguised as `.includes()`, `.find()`, or `.indexOf()` inside a loop.
99
+
100
+ ```javascript
101
+ // BAD: O(n²) — includes() scans the array each time
102
+ const uniqueItems = [];
103
+ for (const item of items) {
104
+ if (!uniqueItems.includes(item)) {
105
+ uniqueItems.push(item);
106
+ }
107
+ }
108
+
109
+ // GOOD: O(n) — Set has O(1) lookup
110
+ const uniqueItems = [...new Set(items)];
111
+ ```
112
+
113
+ ```javascript
114
+ // BAD: O(n*m) — find() inside map()
115
+ const enriched = orders.map(order => ({
116
+ ...order,
117
+ user: users.find(u => u.id === order.userId) // O(m) per order
118
+ }));
119
+
120
+ // GOOD: O(n+m) — build lookup map first
121
+ const userMap = new Map(users.map(u => [u.id, u]));
122
+ const enriched = orders.map(order => ({
123
+ ...order,
124
+ user: userMap.get(order.userId) // O(1) per order
125
+ }));
126
+ ```
127
+
128
+ ### Unnecessary Computation
129
+
130
+ **Signature**: Recalculating something in every request/loop that doesn't change.
131
+
132
+ ```javascript
133
+ // BAD: Parsing config on every request
134
+ app.get('/data', (req, res) => {
135
+ const config = JSON.parse(fs.readFileSync('config.json')); // Every request!
136
+ // ...
137
+ });
138
+
139
+ // GOOD: Parse once at startup
140
+ const config = JSON.parse(fs.readFileSync('config.json'));
141
+ app.get('/data', (req, res) => {
142
+ // Use pre-parsed config
143
+ });
144
+ ```
145
+
146
+ ## Memory Bottlenecks
147
+
148
+ ### Loading Entire Datasets
149
+
150
+ **Signature**: Reading all rows into memory instead of streaming or paginating.
151
+
152
+ ```javascript
153
+ // BAD: Loads 1M rows into memory
154
+ const allUsers = await db.users.findMany();
155
+ const csv = allUsers.map(u => `${u.name},${u.email}`).join('\n');
156
+
157
+ // GOOD: Stream rows
158
+ const stream = db.users.stream();
159
+ for await (const user of stream) {
160
+ writeChunk(`${user.name},${user.email}\n`);
161
+ }
162
+ ```
163
+
164
+ ### Unbounded Caches
165
+
166
+ **Signature**: In-memory cache with no size limit or eviction policy.
167
+
168
+ ```javascript
169
+ // BAD: Grows forever
170
+ const cache = {};
171
+ function getData(key) {
172
+ if (!cache[key]) cache[key] = fetchExpensiveData(key);
173
+ return cache[key];
174
+ }
175
+
176
+ // GOOD: LRU cache with max size
177
+ const cache = new LRUCache({ max: 1000, ttl: 1000 * 60 * 5 });
178
+ ```
179
+
180
+ ### Event Listener Leaks
181
+
182
+ **Signature**: Adding event listeners without removing them, especially in loops or on repeated operations.
183
+
184
+ ```javascript
185
+ // BAD: Adds a new listener every time this function runs
186
+ function setupHandler() {
187
+ emitter.on('data', handleData); // Accumulates!
188
+ }
189
+
190
+ // GOOD: Remove before adding, or add once
191
+ function setupHandler() {
192
+ emitter.removeListener('data', handleData);
193
+ emitter.on('data', handleData);
194
+ }
195
+ ```
196
+
197
+ ## Network and I/O Bottlenecks
198
+
199
+ ### Sequential External Calls
200
+
201
+ **Signature**: Awaiting multiple independent API calls one after another.
202
+
203
+ ```javascript
204
+ // BAD: 3 sequential calls — total time = sum of all three
205
+ const user = await fetchUser(id);
206
+ const orders = await fetchOrders(id);
207
+ const recommendations = await fetchRecommendations(id);
208
+
209
+ // GOOD: Parallel — total time = slowest of the three
210
+ const [user, orders, recommendations] = await Promise.all([
211
+ fetchUser(id),
212
+ fetchOrders(id),
213
+ fetchRecommendations(id),
214
+ ]);
215
+ ```
216
+
217
+ ### Large Payloads
218
+
219
+ **Signature**: API responses that include data the client doesn't use.
220
+
221
+ - Return only the fields the client needs (field selection / sparse fieldsets)
222
+ - Compress responses (gzip/brotli)
223
+ - Paginate collections
224
+ - Use appropriate image sizes and formats
225
+
226
+ ### Missing Connection Pooling
227
+
228
+ **Signature**: Creating a new database connection per request instead of reusing from a pool.
229
+
230
+ Most ORMs handle this, but verify: is the pool configured? Is the max size appropriate for the workload? Are connections returned to the pool after use?
231
+
232
+ ## Frontend-Specific Bottlenecks
233
+
234
+ - **Unoptimized images**: Serve WebP/AVIF, lazy-load below-the-fold images, use srcset for responsive sizes
235
+ - **Bundle size**: Tree-shake unused code, code-split by route, analyze with `webpack-bundle-analyzer` or `source-map-explorer`
236
+ - **Render blocking**: Defer non-critical JS/CSS, inline critical CSS, preload key assets
237
+ - **Excessive re-renders**: In React — memoize expensive components, avoid creating objects/functions in render, use proper keys in lists
238
+ - **Layout thrashing**: Reading then writing DOM properties in a loop forces the browser to recalculate layout repeatedly
239
+
240
+ ## Caching Strategies
241
+
242
+ | Strategy | Use When | Watch Out For |
243
+ |----------|----------|---------------|
244
+ | **HTTP caching** (Cache-Control, ETag) | Static assets, rarely-changing responses | Stale data served to users |
245
+ | **Application cache** (Redis, Memcached) | Expensive queries, computed results | Cache invalidation complexity |
246
+ | **In-memory cache** (LRU) | Hot data, single-instance apps | Memory pressure, stale data |
247
+ | **CDN** | Static assets, public API responses | Purging on update |
248
+ | **Database query cache** | Read-heavy workloads | Invalidated on any write (may not help) |
249
+
250
+ **Cache invalidation rules:**
251
+ - Write-through: Update cache on every write (consistent but slower writes)
252
+ - Write-behind: Queue cache updates asynchronously (fast writes, eventually consistent)
253
+ - TTL-based: Let entries expire after a time (simplest, acceptable staleness)
254
+ - Event-driven: Invalidate on specific events (most precise, most complex)
255
+
256
+ Start with TTL-based caching. Only add complexity if staleness is unacceptable.
@@ -0,0 +1,101 @@
1
+ # Concurrency Reference
2
+
3
+ ## Contents
4
+ - Separating concurrency from business logic
5
+ - Limiting shared mutable state
6
+ - Concurrency models
7
+ - Common concurrency bugs
8
+ - Testing concurrent code
9
+
10
+ ## Separating Concurrency from Business Logic
11
+
12
+ Concurrency is inherently difficult — it changes the behavior of otherwise correct code in subtle ways. Keep concurrent code separate from business logic so that each can be reasoned about independently.
13
+
14
+ Principles:
15
+ - **Business logic should be pure**: Functions that compute business rules should not manage threads, locks, or async coordination. They take input and return output.
16
+ - **Concurrency is a deployment concern**: The decision to run code in parallel belongs to the orchestration layer, not the domain layer.
17
+ - **Single Responsibility applies**: A class that manages thread safety AND implements business rules has two reasons to change.
18
+
19
+ In practice:
20
+ - Write business logic as synchronous, pure functions
21
+ - Wrap concurrent execution in an orchestration layer (executor service, task queue, event loop)
22
+ - Use the Humble Object pattern: the concurrent wrapper is humble (hard to test but simple), the business logic is testable
23
+
24
+ ## Limiting Shared Mutable State
25
+
26
+ Most concurrency bugs stem from shared mutable state — two threads reading and writing the same data without proper coordination.
27
+
28
+ Strategies to eliminate or reduce shared state (ordered by preference):
29
+
30
+ 1. **Immutable data**: If data cannot change, it can be shared freely without synchronization. Use `const`, `final`, frozen objects, or immutable data structures.
31
+
32
+ 2. **Message passing**: Instead of sharing state, send copies of data between concurrent tasks. Actor models (Erlang, Akka), channels (Go, Rust), and async queues follow this pattern.
33
+
34
+ 3. **Thread-local / task-local storage**: Each concurrent task gets its own copy. No sharing, no coordination needed.
35
+
36
+ 4. **Synchronized access**: When sharing is unavoidable, protect with mutexes, locks, or atomic operations. This is the last resort — it's correct but slow and error-prone.
37
+
38
+ **Rule of thumb**: If you need more than one lock to protect an operation, redesign the data model so the operation only touches one piece of shared state.
39
+
40
+ ## Concurrency Models
41
+
42
+ Different concurrency models suit different problems. Choose based on the workload:
43
+
44
+ **Threads / OS processes**: Best for CPU-bound work that benefits from true parallelism. Heavy resource cost per thread. Risk of races and deadlocks with shared state.
45
+
46
+ **Async/await (event loop)**: Best for I/O-bound work (network calls, file I/O, database queries). Single-threaded concurrency — no shared state issues, but CPU-bound work blocks the loop.
47
+
48
+ **Goroutines / green threads**: Lightweight threads managed by the runtime. Good balance of parallelism and low overhead. Still require discipline with shared state (channels preferred).
49
+
50
+ **Actor model**: Each actor has private state and communicates via messages. Eliminates shared state by design. Good for distributed systems and complex state machines.
51
+
52
+ **Fork-join / work stealing**: Best for recursive divide-and-conquer problems. The runtime distributes sub-tasks across threads. Common in parallel stream/collection processing.
53
+
54
+ ## Common Concurrency Bugs
55
+
56
+ ### Race conditions
57
+ Two tasks access shared state and the outcome depends on execution order. The code works "most of the time" but fails under load or on different hardware.
58
+
59
+ Detection: Non-deterministic test failures, bugs that disappear under debugger (which changes timing), inconsistent data in production.
60
+
61
+ Prevention: Eliminate shared mutable state, use atomic operations, or protect with proper synchronization.
62
+
63
+ ### Deadlocks
64
+ Two tasks each hold a lock the other needs. Both wait forever.
65
+
66
+ Prevention:
67
+ - Always acquire locks in the same order across the codebase
68
+ - Use timeouts on lock acquisition
69
+ - Prefer lock-free data structures when possible
70
+ - Reduce the number of locks (redesign to reduce shared state)
71
+
72
+ ### Livelocks
73
+ Tasks keep responding to each other without making progress — like two people sidestepping in a hallway.
74
+
75
+ Prevention: Add randomized backoff to retry logic. Ensure at least one task can make progress.
76
+
77
+ ### Starvation
78
+ A task never gets the resources it needs because other tasks monopolize them.
79
+
80
+ Prevention: Use fair scheduling, bounded queues, and priority mechanisms. Monitor task latency distributions for signs of starvation.
81
+
82
+ ### Thread pool exhaustion
83
+ All threads in a pool are blocked waiting for I/O or downstream services. New work cannot be accepted.
84
+
85
+ Prevention: Size pools appropriately, use non-blocking I/O for network calls, add circuit breakers for slow dependencies, separate pools for different workload types.
86
+
87
+ ## Testing Concurrent Code
88
+
89
+ Concurrency bugs are notoriously hard to reproduce. Standard unit tests often pass because they run too fast to trigger race conditions.
90
+
91
+ Strategies:
92
+
93
+ **Stress tests**: Run the same operation from many threads/tasks simultaneously. Repeat thousands of times. Bugs that occur "1 in 1000" will surface.
94
+
95
+ **Deterministic testing**: Use test frameworks that control thread scheduling (e.g., `ThreadSanitizer`, `loom` for Rust, `Lincheck` for Kotlin). These systematically explore different interleavings.
96
+
97
+ **Invariant checking**: Instead of asserting specific outcomes, assert invariants that must hold regardless of execution order. "Account balance is never negative" rather than "balance equals 42."
98
+
99
+ **Timeout-based detection**: If a test hangs instead of failing, a deadlock is likely. Set aggressive timeouts on concurrent tests.
100
+
101
+ **Race detectors**: Use runtime tools (`-race` flag in Go, ThreadSanitizer for C/C++/Rust, Java's `jcstress`) to detect data races automatically.
@@ -0,0 +1,109 @@
1
+ ---
2
+ name: prd-writing
3
+ description: "Write lightweight agile PRDs and technical RFCs that align stakeholders before implementation. Triggers: PRD, product requirements, RFC, request for comments, technical design doc, design document, tech spec, write requirements, what are we building, spec this out. Produces the WHAT and WHY — feature-planning handles HOW."
4
+ model: sonnet
5
+ allowed-tools: Read, Grep, Glob, Write, Edit
6
+ ---
7
+
8
+ # PRD & RFC Writing
9
+
10
+ Write lightweight requirements and design documents that align stakeholders without drowning in waterfall-style documentation. In agile, these documents are living artifacts — concise enough to write quickly, clear enough to prevent misalignment.
11
+
12
+ ## Two Document Types
13
+
14
+ ### Agile PRD (Product Requirements Document)
15
+ **Audience**: Product, design, engineering, stakeholders
16
+ **Purpose**: Define WHAT to build and WHY, from the user's perspective
17
+ **When**: Before starting a significant feature or epic (more than a sprint of work)
18
+
19
+ ### Technical RFC (Request for Comments)
20
+ **Audience**: Engineering team, tech leads, architects
21
+ **Purpose**: Propose HOW to build something technically, gather feedback before committing
22
+ **When**: Before implementing non-trivial technical work (new service, data migration, architecture change)
23
+
24
+ Many features need both: a PRD from the product side and an RFC from the engineering side. Some only need one.
25
+
26
+ ## Workflow: Agile PRD
27
+
28
+ ### Step 1: Start with the Problem
29
+
30
+ Every PRD begins with a crystal-clear problem statement:
31
+
32
+ - What user pain or business need does this address?
33
+ - Who specifically has this problem? (Define the persona)
34
+ - How big is this problem? (Frequency, severity, number of users affected)
35
+ - What do users do today to work around it?
36
+
37
+ If you can't articulate the problem, you're not ready to write requirements.
38
+
39
+ ### Step 2: Define Goals and Non-Goals
40
+
41
+ **Goals**: What this project will achieve (tied to metrics when possible)
42
+ **Non-goals**: What this project explicitly will NOT do (prevents scope creep)
43
+
44
+ Non-goals are just as important as goals. They're the guardrails that keep the project focused.
45
+
46
+ ### Step 3: Write User Stories
47
+
48
+ Express requirements as user stories:
49
+
50
+ ```
51
+ As a [user persona],
52
+ I want to [action/capability],
53
+ so that [benefit/outcome].
54
+ ```
55
+
56
+ Group stories by priority using MoSCoW:
57
+ - **Must have**: Project fails without these
58
+ - **Should have**: Important but not launch-blocking
59
+ - **Could have**: Nice to have if time allows
60
+ - **Won't have (this time)**: Explicitly deferred
61
+
62
+ ### Step 4: Define Acceptance Criteria and Constraints
63
+
64
+ For each must-have story, define acceptance criteria (use feature-planning's Given/When/Then format).
65
+
66
+ Document constraints: performance requirements, accessibility requirements, platform support, backwards compatibility, regulatory compliance.
67
+
68
+ ### Step 5: Include Design Context
69
+
70
+ If mockups, wireframes, or user flows exist, link them. If not, describe the intended user experience in enough detail that a designer can start.
71
+
72
+ ### Step 6: Produce the PRD
73
+
74
+ Use the template at [templates/prd.md](templates/prd.md). Keep it under 3 pages. Link to detailed resources rather than embedding everything.
75
+
76
+ ## Workflow: Technical RFC
77
+
78
+ ### Step 1: State the Problem and Context
79
+
80
+ Same discipline as the PRD — start with why, not what. Include:
81
+ - What triggered this RFC (feature requirement, scaling issue, tech debt)
82
+ - Current state of the system
83
+ - Constraints (timeline, backward compatibility, team expertise)
84
+
85
+ ### Step 2: Propose the Solution
86
+
87
+ Describe the technical approach clearly. Include:
88
+ - High-level architecture or design
89
+ - Key components and their interactions
90
+ - Data model changes (link to `data-modeling` if needed)
91
+ - API changes (link to `api-design` if needed)
92
+
93
+ ### Step 3: Present Alternatives
94
+
95
+ List 2-3 alternatives considered with tradeoffs. This proves you've thought beyond the first idea.
96
+
97
+ ### Step 4: Identify Open Questions
98
+
99
+ List questions that need answering during or after the review process. This invites targeted feedback.
100
+
101
+ ### Step 5: Produce the RFC
102
+
103
+ Use the template at [templates/rfc.md](templates/rfc.md). Circulate for review with a clear deadline.
104
+
105
+ ## Principles Applied
106
+
107
+ - **Agile over waterfall**: These documents are living drafts, not contracts. Update as understanding evolves.
108
+ - **KISS**: If it takes more than an afternoon to write, the scope is too large — split it.
109
+ - **Working software over comprehensive documentation**: Write just enough to align. The code is the real spec.
@@ -0,0 +1,33 @@
1
+ {
2
+ "skill_name": "prd-writing",
3
+ "evals": [
4
+ {
5
+ "id": 1,
6
+ "prompt": "Write a PRD for adding multi-language support (i18n) to our React web app. We currently only support English. Our analytics show 30% of users have non-English browser locales. We want to support Spanish, French, and Portuguese initially.",
7
+ "expected_output": "Should produce a lightweight agile PRD with clear problem statement backed by data, user stories prioritized by MoSCoW, non-goals (e.g., not RTL languages yet), and success metrics.",
8
+ "assertions": [
9
+ "Problem statement includes the 30% data point as justification",
10
+ "Goals are measurable (e.g., support 3 languages, reduce bounce rate for non-English users)",
11
+ "Non-goals explicitly state what's deferred (RTL, CJK, machine translation)",
12
+ "User stories cover content translation, language switching, locale detection",
13
+ "MoSCoW prioritization distinguishes must-have from nice-to-have",
14
+ "Constraints mention things like URL strategy, SEO, content workflow",
15
+ "Keeps the PRD concise (not a 10-page waterfall spec)"
16
+ ]
17
+ },
18
+ {
19
+ "id": 2,
20
+ "prompt": "Write a technical RFC for migrating our user authentication from session-based to JWT tokens. We have 200K active users and can't afford downtime during migration.",
21
+ "expected_output": "Should produce an RFC with the zero-downtime constraint front and center, propose a gradual migration strategy, present alternatives, and identify specific risks.",
22
+ "assertions": [
23
+ "Zero-downtime requirement shapes the entire proposal (not just a footnote)",
24
+ "Proposes a gradual migration (dual-auth period, not big bang)",
25
+ "Presents alternatives (session-based improvements, OAuth provider, etc.)",
26
+ "Addresses security implications of JWT (token revocation, expiry strategy)",
27
+ "Includes data migration plan for existing sessions",
28
+ "Has open questions that invite reviewer input",
29
+ "Links to feature-planning for implementation task breakdown"
30
+ ]
31
+ }
32
+ ]
33
+ }
@@ -0,0 +1,132 @@
1
+ # PRD and RFC Examples
2
+
3
+ ## What "Lightweight Agile" Means in Practice
4
+
5
+ A lightweight agile PRD is NOT:
6
+ - A 50-page waterfall requirements spec
7
+ - An exhaustive list of every edge case
8
+ - A contract that cannot change
9
+
10
+ A lightweight agile PRD IS:
11
+ - 1-3 pages that capture the essential problem, goals, and requirements
12
+ - A shared understanding document — alignment tool, not a spec
13
+ - Something a motivated engineer can write in an afternoon
14
+ - Living: updated as the team learns more
15
+
16
+ ---
17
+
18
+ ## Example: Good Lightweight PRD
19
+
20
+ **Feature**: Saved Searches
21
+
22
+ ---
23
+
24
+ **Problem**
25
+
26
+ Power users of our analytics dashboard run the same searches every day. Currently they must re-enter filter combinations manually each session. Support tickets show 15% of users mention "having to set the same filters every time" as a pain point. Usage logs confirm the top 20% of users average 8 filter changes per session.
27
+
28
+ **Goals**
29
+ - Users can save up to 20 named search configurations
30
+ - Saved searches load with one click from the search bar
31
+ - Reduces average filter changes per session by 50% for power users (measure at 30 days post-launch)
32
+
33
+ **Non-goals**
34
+ - Sharing saved searches between users (deferred to v2)
35
+ - Search history / auto-complete (separate feature)
36
+ - Mobile app support (web only for now)
37
+
38
+ **User Stories**
39
+
40
+ *Must have:*
41
+ - As a power user, I want to save my current filter state with a name, so that I can return to it without re-entering filters
42
+ - As a power user, I want to load a saved search by clicking its name, so that I can switch between common configurations quickly
43
+ - As a power user, I want to delete saved searches I no longer need
44
+
45
+ *Should have:*
46
+ - As a power user, I want to rename a saved search, so that I can keep my list organized
47
+
48
+ **Acceptance Criteria** (for must-haves)
49
+
50
+ *Save a search:*
51
+ - Given I have applied one or more filters, when I click "Save search", then I see a dialog to name it
52
+ - Given I enter a name and click Save, then the search appears in my saved searches list immediately
53
+ - Given I try to save with a duplicate name, then I'm warned and can choose to overwrite or rename
54
+
55
+ *Load a search:*
56
+ - Given I have saved searches, when I click a saved search name, then all filters update to that saved configuration in under 200ms
57
+ - Given no saved searches exist, then the saved searches dropdown shows an empty state with "Save your first search" prompt
58
+
59
+ **Constraints**
60
+ - Max 20 saved searches per user (storage and UI constraint)
61
+ - Saved searches are persisted server-side (not localStorage) so they sync across devices
62
+ - Names limited to 50 characters
63
+
64
+ **Design context**: Saved searches appear as a dropdown from the existing search bar. Mockup linked in Figma: [link].
65
+
66
+ ---
67
+
68
+ ## What Makes This PRD Good
69
+
70
+ - **Problem is quantified**: "15% of support tickets", "8 filter changes per session" — not "users find it annoying"
71
+ - **Non-goals are explicit**: prevents scope creep discussions during development
72
+ - **MoSCoW prioritization**: the team knows what to cut if time is short
73
+ - **Acceptance criteria are testable**: Given/When/Then format, specific and binary (pass/fail)
74
+ - **Constraints are technical facts**, not preferences
75
+ - **Under 2 pages** — a motivated engineer can read this in 5 minutes
76
+
77
+ ---
78
+
79
+ ## Example: Good Technical RFC
80
+
81
+ **RFC: Migrate Session Storage from Redis to PostgreSQL**
82
+
83
+ ---
84
+
85
+ **Context**
86
+
87
+ Our Redis cluster is consistently at 80% memory usage and requires a $2,400/month upgrade. Sessions are currently stored as Redis hashes with 24-hour TTL. We have ~50,000 active sessions at peak.
88
+
89
+ **Proposed Solution**
90
+
91
+ Store sessions in a `sessions` PostgreSQL table:
92
+ ```sql
93
+ CREATE TABLE sessions (
94
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
95
+ user_id BIGINT NOT NULL REFERENCES users(id),
96
+ data JSONB NOT NULL DEFAULT '{}',
97
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
98
+ expires_at TIMESTAMPTZ NOT NULL,
99
+ last_accessed_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
100
+ );
101
+ CREATE INDEX sessions_user_id_idx ON sessions(user_id);
102
+ CREATE INDEX sessions_expires_at_idx ON sessions(expires_at) WHERE expires_at > NOW();
103
+ ```
104
+
105
+ Expired sessions are cleaned by a nightly job (`DELETE FROM sessions WHERE expires_at < NOW()`). Session reads update `last_accessed_at` asynchronously (fire-and-forget) to avoid read amplification.
106
+
107
+ **Alternatives Considered**
108
+
109
+ 1. **Upgrade Redis** ($2,400/month, solves capacity but not the operational cost). Simple but doesn't reduce cost.
110
+ 2. **Switch to JWT sessions** (stateless, no storage needed). Rejected: cannot revoke JWTs before expiry, which is a security requirement for us.
111
+ 3. **PostgreSQL** (proposed): Reduces infrastructure cost to ~$0 marginal (existing PG cluster has headroom), adds session revocation query capability, adds audit trail. Tradeoff: higher read latency (~5ms vs ~1ms) and additional load on primary database.
112
+
113
+ **Migration Plan**
114
+ 1. Add `sessions` table to Postgres (backwards compatible — Redis still in use)
115
+ 2. Write to both Redis and Postgres for 2 weeks (dual-write)
116
+ 3. Read from Postgres with Redis fallback for 1 week
117
+ 4. Remove Redis reads; remove Redis writes
118
+ 5. Remove Redis cluster
119
+
120
+ **Open Questions**
121
+ - Should we keep Redis for other uses (rate limiting, pub/sub)? If yes, downgrade instead of removing.
122
+ - Acceptable session read latency budget? Current Redis ~1ms, Postgres ~5ms. Impact on auth-heavy pages?
123
+
124
+ ---
125
+
126
+ ## What Makes This RFC Good
127
+
128
+ - **Quantified trigger**: "$2,400/month", "80% memory" — not "Redis is getting full"
129
+ - **Alternatives include "do nothing" equivalent**: upgrade Redis is explicitly evaluated
130
+ - **Tradeoffs are honest**: "higher read latency (~5ms vs ~1ms)" — doesn't hide downsides
131
+ - **Migration plan is phased**: dual-write period reduces risk
132
+ - **Open questions are targeted**: asks the two things that could change the decision