bros-harness 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 (187) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/LICENSE +21 -0
  3. package/README.md +183 -0
  4. package/SECURITY.md +16 -0
  5. package/assets/agents.manifest.json +55 -0
  6. package/assets/commands.manifest.json +35 -0
  7. package/assets/docs.manifest.json +20 -0
  8. package/assets/import-report.md +25 -0
  9. package/assets/manifest.json +799 -0
  10. package/assets/opencode/agents/README.md +3 -0
  11. package/assets/opencode/agents/bro-build.md +256 -0
  12. package/assets/opencode/agents/bro-design.md +77 -0
  13. package/assets/opencode/agents/bro-docs.md +72 -0
  14. package/assets/opencode/agents/bro-explore.md +143 -0
  15. package/assets/opencode/agents/bro-ops.md +195 -0
  16. package/assets/opencode/agents/bro-shield.md +77 -0
  17. package/assets/opencode/agents/bro-test.md +204 -0
  18. package/assets/opencode/agents/bro-ui.md +135 -0
  19. package/assets/opencode/agents/mighty-bro.md +252 -0
  20. package/assets/opencode/commands/README.md +3 -0
  21. package/assets/opencode/commands/bros-assemble.md +32 -0
  22. package/assets/opencode/commands/bros-build.md +58 -0
  23. package/assets/opencode/commands/bros-plan.md +83 -0
  24. package/assets/opencode/commands/bros-review.md +38 -0
  25. package/assets/opencode/commands/bros-status.md +26 -0
  26. package/assets/opencode/docs/README.md +3 -0
  27. package/assets/opencode/docs/bros-builtin-skills.md +63 -0
  28. package/assets/opencode/docs/bros-harness.md +194 -0
  29. package/assets/opencode/skills/README.md +3 -0
  30. package/assets/opencode/skills/agent-architecture-audit/SKILL.md +256 -0
  31. package/assets/opencode/skills/agent-harness-construction/.openskills.json +7 -0
  32. package/assets/opencode/skills/agent-harness-construction/SKILL.md +73 -0
  33. package/assets/opencode/skills/agent-introspection-debugging/.openskills.json +7 -0
  34. package/assets/opencode/skills/agent-introspection-debugging/SKILL.md +153 -0
  35. package/assets/opencode/skills/api-design/.openskills.json +7 -0
  36. package/assets/opencode/skills/api-design/agents/openai.yaml +7 -0
  37. package/assets/opencode/skills/architecture-decision-records/.openskills.json +7 -0
  38. package/assets/opencode/skills/architecture-decision-records/SKILL.md +179 -0
  39. package/assets/opencode/skills/article-writing/.openskills.json +7 -0
  40. package/assets/opencode/skills/article-writing/SKILL.md +79 -0
  41. package/assets/opencode/skills/article-writing/agents/openai.yaml +7 -0
  42. package/assets/opencode/skills/automation-audit-ops/.openskills.json +7 -0
  43. package/assets/opencode/skills/automation-audit-ops/SKILL.md +142 -0
  44. package/assets/opencode/skills/backend-patterns/.openskills.json +7 -0
  45. package/assets/opencode/skills/backend-patterns/SKILL.md +561 -0
  46. package/assets/opencode/skills/backend-patterns/agents/openai.yaml +7 -0
  47. package/assets/opencode/skills/benchmark/.openskills.json +7 -0
  48. package/assets/opencode/skills/benchmark/SKILL.md +93 -0
  49. package/assets/opencode/skills/bros-orchestrate/SKILL.md +455 -0
  50. package/assets/opencode/skills/browser-qa/.openskills.json +7 -0
  51. package/assets/opencode/skills/browser-qa/SKILL.md +87 -0
  52. package/assets/opencode/skills/canary-watch/.openskills.json +7 -0
  53. package/assets/opencode/skills/canary-watch/SKILL.md +107 -0
  54. package/assets/opencode/skills/code-review-expert/SKILL.md +155 -0
  55. package/assets/opencode/skills/code-review-expert/agents/agent.yaml +7 -0
  56. package/assets/opencode/skills/code-review-expert/references/code-quality-checklist.md +130 -0
  57. package/assets/opencode/skills/code-review-expert/references/removal-plan.md +52 -0
  58. package/assets/opencode/skills/code-review-expert/references/security-checklist.md +118 -0
  59. package/assets/opencode/skills/code-review-expert/references/solid-checklist.md +65 -0
  60. package/assets/opencode/skills/code-tour/.openskills.json +7 -0
  61. package/assets/opencode/skills/code-tour/SKILL.md +236 -0
  62. package/assets/opencode/skills/coding-standards/.openskills.json +7 -0
  63. package/assets/opencode/skills/coding-standards/SKILL.md +549 -0
  64. package/assets/opencode/skills/coding-standards/agents/openai.yaml +7 -0
  65. package/assets/opencode/skills/context-budget/.openskills.json +7 -0
  66. package/assets/opencode/skills/context-budget/SKILL.md +135 -0
  67. package/assets/opencode/skills/database-migrations/.openskills.json +7 -0
  68. package/assets/opencode/skills/database-migrations/SKILL.md +429 -0
  69. package/assets/opencode/skills/deployment-patterns/.openskills.json +7 -0
  70. package/assets/opencode/skills/deployment-patterns/SKILL.md +427 -0
  71. package/assets/opencode/skills/design-system/.openskills.json +7 -0
  72. package/assets/opencode/skills/design-system/SKILL.md +82 -0
  73. package/assets/opencode/skills/docker-patterns/.openskills.json +7 -0
  74. package/assets/opencode/skills/docker-patterns/SKILL.md +364 -0
  75. package/assets/opencode/skills/documentation-lookup/.openskills.json +7 -0
  76. package/assets/opencode/skills/documentation-lookup/SKILL.md +90 -0
  77. package/assets/opencode/skills/documentation-lookup/agents/openai.yaml +7 -0
  78. package/assets/opencode/skills/e2e-testing/.openskills.json +7 -0
  79. package/assets/opencode/skills/e2e-testing/SKILL.md +326 -0
  80. package/assets/opencode/skills/e2e-testing/agents/openai.yaml +7 -0
  81. package/assets/opencode/skills/error-handling/SKILL.md +376 -0
  82. package/assets/opencode/skills/frontend-design/.openskills.json +7 -0
  83. package/assets/opencode/skills/frontend-design/SKILL.md +145 -0
  84. package/assets/opencode/skills/frontend-design-direction/SKILL.md +92 -0
  85. package/assets/opencode/skills/frontend-patterns/.openskills.json +7 -0
  86. package/assets/opencode/skills/frontend-patterns/SKILL.md +642 -0
  87. package/assets/opencode/skills/frontend-patterns/agents/openai.yaml +7 -0
  88. package/assets/opencode/skills/gateguard/.openskills.json +7 -0
  89. package/assets/opencode/skills/gateguard/SKILL.md +125 -0
  90. package/assets/opencode/skills/git-master/SKILL.md +60 -0
  91. package/assets/opencode/skills/golang-patterns/.openskills.json +7 -0
  92. package/assets/opencode/skills/golang-patterns/SKILL.md +674 -0
  93. package/assets/opencode/skills/golang-testing/.openskills.json +7 -0
  94. package/assets/opencode/skills/golang-testing/SKILL.md +720 -0
  95. package/assets/opencode/skills/grafana-dashboard-design/SKILL.md +65 -0
  96. package/assets/opencode/skills/hexagonal-architecture/.openskills.json +7 -0
  97. package/assets/opencode/skills/hexagonal-architecture/SKILL.md +276 -0
  98. package/assets/opencode/skills/java-coding-standards/.openskills.json +7 -0
  99. package/assets/opencode/skills/java-coding-standards/SKILL.md +383 -0
  100. package/assets/opencode/skills/jpa-patterns/.openskills.json +7 -0
  101. package/assets/opencode/skills/jpa-patterns/SKILL.md +151 -0
  102. package/assets/opencode/skills/knowledge-ops/.openskills.json +7 -0
  103. package/assets/opencode/skills/knowledge-ops/SKILL.md +154 -0
  104. package/assets/opencode/skills/make-interfaces-feel-better/SKILL.md +151 -0
  105. package/assets/opencode/skills/mysql-patterns/SKILL.md +412 -0
  106. package/assets/opencode/skills/nestjs-patterns/.openskills.json +7 -0
  107. package/assets/opencode/skills/nestjs-patterns/SKILL.md +230 -0
  108. package/assets/opencode/skills/nextjs-turbopack/.openskills.json +7 -0
  109. package/assets/opencode/skills/nextjs-turbopack/SKILL.md +57 -0
  110. package/assets/opencode/skills/nextjs-turbopack/agents/openai.yaml +7 -0
  111. package/assets/opencode/skills/parallel-execution-optimizer/SKILL.md +72 -0
  112. package/assets/opencode/skills/postgres-patterns/.openskills.json +7 -0
  113. package/assets/opencode/skills/postgres-patterns/SKILL.md +147 -0
  114. package/assets/opencode/skills/prisma-patterns/SKILL.md +371 -0
  115. package/assets/opencode/skills/product-capability/.openskills.json +7 -0
  116. package/assets/opencode/skills/product-capability/SKILL.md +141 -0
  117. package/assets/opencode/skills/product-lens/.openskills.json +7 -0
  118. package/assets/opencode/skills/product-lens/SKILL.md +92 -0
  119. package/assets/opencode/skills/production-audit/SKILL.md +206 -0
  120. package/assets/opencode/skills/python-patterns/.openskills.json +7 -0
  121. package/assets/opencode/skills/python-patterns/SKILL.md +750 -0
  122. package/assets/opencode/skills/python-testing/.openskills.json +7 -0
  123. package/assets/opencode/skills/python-testing/SKILL.md +816 -0
  124. package/assets/opencode/skills/redis-patterns/SKILL.md +403 -0
  125. package/assets/opencode/skills/requirements-clarity/README.md +260 -0
  126. package/assets/opencode/skills/requirements-clarity/SKILL.md +324 -0
  127. package/assets/opencode/skills/rust-patterns/.openskills.json +7 -0
  128. package/assets/opencode/skills/rust-patterns/SKILL.md +499 -0
  129. package/assets/opencode/skills/rust-testing/.openskills.json +7 -0
  130. package/assets/opencode/skills/rust-testing/SKILL.md +500 -0
  131. package/assets/opencode/skills/safety-guard/.openskills.json +7 -0
  132. package/assets/opencode/skills/safety-guard/SKILL.md +75 -0
  133. package/assets/opencode/skills/search-first/.openskills.json +7 -0
  134. package/assets/opencode/skills/search-first/SKILL.md +181 -0
  135. package/assets/opencode/skills/security-review/.openskills.json +7 -0
  136. package/assets/opencode/skills/security-review/agents/openai.yaml +7 -0
  137. package/assets/opencode/skills/security-review/cloud-infrastructure-security.md +361 -0
  138. package/assets/opencode/skills/security-scan/.openskills.json +7 -0
  139. package/assets/opencode/skills/security-scan/SKILL.md +165 -0
  140. package/assets/opencode/skills/springboot-patterns/.openskills.json +7 -0
  141. package/assets/opencode/skills/springboot-patterns/SKILL.md +314 -0
  142. package/assets/opencode/skills/springboot-tdd/.openskills.json +7 -0
  143. package/assets/opencode/skills/springboot-tdd/SKILL.md +158 -0
  144. package/assets/opencode/skills/springboot-verification/.openskills.json +7 -0
  145. package/assets/opencode/skills/springboot-verification/SKILL.md +231 -0
  146. package/assets/opencode/skills/strategic-compact/.openskills.json +7 -0
  147. package/assets/opencode/skills/strategic-compact/SKILL.md +131 -0
  148. package/assets/opencode/skills/strategic-compact/agents/openai.yaml +7 -0
  149. package/assets/opencode/skills/strategic-compact/suggest-compact.sh +54 -0
  150. package/assets/opencode/skills/tdd-workflow/.openskills.json +7 -0
  151. package/assets/opencode/skills/tdd-workflow/SKILL.md +463 -0
  152. package/assets/opencode/skills/tdd-workflow/agents/openai.yaml +7 -0
  153. package/assets/opencode/skills/verification-loop/.openskills.json +7 -0
  154. package/assets/opencode/skills/verification-loop/SKILL.md +126 -0
  155. package/assets/opencode/skills/verification-loop/agents/openai.yaml +7 -0
  156. package/assets/opencode/skills/vite-patterns/SKILL.md +449 -0
  157. package/assets/opencode/skills/web-doc-search/SKILL.md +51 -0
  158. package/assets/opencode/templates/README.md +3 -0
  159. package/assets/opencode/templates/bros/adr.md +39 -0
  160. package/assets/opencode/templates/bros/delivery-report.md +71 -0
  161. package/assets/opencode/templates/bros/explorer-evidence-packet.md +51 -0
  162. package/assets/opencode/templates/bros/prd.md +72 -0
  163. package/assets/opencode/templates/bros/security-review.md +48 -0
  164. package/assets/opencode/templates/bros/status-board.md +33 -0
  165. package/assets/opencode/templates/bros/task-packet.md +94 -0
  166. package/assets/opencode/templates/bros/test-strategy.md +57 -0
  167. package/assets/opencode/templates/bros/ui-implementation-packet.md +64 -0
  168. package/assets/skills.manifest.json +650 -0
  169. package/assets/templates.manifest.json +55 -0
  170. package/bin/bros.mjs +122 -0
  171. package/docs/compatibility.md +9 -0
  172. package/docs/installation.md +66 -0
  173. package/docs/integrations/claude.md +5 -0
  174. package/docs/integrations/codex.md +5 -0
  175. package/docs/integrations/opencode.md +39 -0
  176. package/docs/migration/from-local-opencode-config.md +10 -0
  177. package/docs/release-process.md +11 -0
  178. package/docs/repository-structure.md +15 -0
  179. package/docs/roadmap.md +20 -0
  180. package/docs/security.md +18 -0
  181. package/docs/testing.md +9 -0
  182. package/examples/opencode/README.md +11 -0
  183. package/examples/opencode/opencode.example.jsonc +4 -0
  184. package/package.json +43 -0
  185. package/scripts/validate-assets.mjs +22 -0
  186. package/scripts/verify-no-secrets.mjs +38 -0
  187. package/src/plugin.mjs +98 -0
@@ -0,0 +1,403 @@
1
+ ---
2
+ name: redis-patterns
3
+ description: Redis data structure patterns, caching strategies, distributed locks, rate limiting, pub/sub, and connection management for production applications.
4
+ origin: ECC
5
+ ---
6
+
7
+ # Redis Patterns
8
+
9
+ Quick reference for Redis best practices across common backend use cases.
10
+
11
+ ## How It Works
12
+
13
+ Redis is an in-memory data structure store that supports strings, hashes, lists, sets, sorted sets, streams, and more. Individual Redis commands are atomic on a single instance; multi-step workflows require Lua scripts, MULTI/EXEC transactions, or explicit synchronization to stay atomic. Data is optionally persisted via RDB snapshots or AOF logs. Clients communicate over TCP using the RESP protocol; connection pools are essential to avoid per-request handshake overhead.
14
+
15
+ ## When to Activate
16
+
17
+ - Adding caching to an application
18
+ - Implementing rate limiting or throttling
19
+ - Building distributed locks or coordination
20
+ - Setting up session or token storage
21
+ - Using Pub/Sub or Redis Streams for messaging
22
+ - Configuring Redis in production (pooling, eviction, clustering)
23
+
24
+ ## Data Structure Cheat Sheet
25
+
26
+ | Use Case | Structure | Example Key |
27
+ |----------|-----------|-------------|
28
+ | Simple cache | String | `product:123` |
29
+ | User session | Hash | `session:abc` |
30
+ | Leaderboard | Sorted Set | `scores:weekly` |
31
+ | Unique visitors | Set | `visitors:2024-01-01` |
32
+ | Activity feed | List | `feed:user:456` |
33
+ | Event stream | Stream | `events:orders` |
34
+ | Counters / rate limits | String (INCR) | `ratelimit:user:123` |
35
+ | Bloom filter / HLL | HyperLogLog | `hll:pageviews` |
36
+
37
+ ## Core Patterns
38
+
39
+ ### Cache-Aside (Lazy Loading)
40
+
41
+ ```python
42
+ import redis
43
+ import json
44
+
45
+ r = redis.Redis(host='localhost', port=6379, decode_responses=True)
46
+
47
+ def get_product(product_id: int):
48
+ cache_key = f"product:{product_id}"
49
+ cached = r.get(cache_key)
50
+
51
+ if cached:
52
+ return json.loads(cached)
53
+
54
+ product = db.query("SELECT * FROM products WHERE id = %s", product_id)
55
+ r.setex(cache_key, 3600, json.dumps(product)) # TTL: 1 hour
56
+ return product
57
+ ```
58
+
59
+ ### Write-Through Cache
60
+
61
+ ```python
62
+ def update_product(product_id: int, data: dict):
63
+ # Write to DB first
64
+ db.execute("UPDATE products SET ... WHERE id = %s", product_id)
65
+
66
+ # Immediately update cache
67
+ cache_key = f"product:{product_id}"
68
+ r.setex(cache_key, 3600, json.dumps(data))
69
+ ```
70
+
71
+ ### Cache Invalidation
72
+
73
+ ```python
74
+ # Tag-based invalidation — group related keys under a set
75
+ def cache_product(product_id: int, category_id: int, data: dict):
76
+ key = f"product:{product_id}"
77
+ tag = f"tag:category:{category_id}"
78
+ pipe = r.pipeline(transaction=True)
79
+ pipe.setex(key, 3600, json.dumps(data))
80
+ pipe.sadd(tag, key)
81
+ pipe.expire(tag, 3600)
82
+ pipe.execute()
83
+
84
+ def invalidate_category(category_id: int):
85
+ tag = f"tag:category:{category_id}"
86
+ keys = r.smembers(tag)
87
+ if keys:
88
+ r.delete(*keys)
89
+ r.delete(tag)
90
+ ```
91
+
92
+ ### Session Storage
93
+
94
+ ```python
95
+ import time
96
+ import uuid
97
+
98
+ def create_session(user_id: int, ttl: int = 86400) -> str:
99
+ session_id = str(uuid.uuid4())
100
+ key = f"session:{session_id}"
101
+ pipe = r.pipeline(transaction=True)
102
+ pipe.hset(key, mapping={
103
+ "user_id": user_id,
104
+ "created_at": int(time.time()),
105
+ })
106
+ pipe.expire(key, ttl)
107
+ pipe.execute()
108
+ return session_id
109
+
110
+ def get_session(session_id: str) -> dict | None:
111
+ data = r.hgetall(f"session:{session_id}")
112
+ return data if data else None
113
+
114
+ def delete_session(session_id: str):
115
+ r.delete(f"session:{session_id}")
116
+ ```
117
+
118
+ ## Rate Limiting
119
+
120
+ ### Fixed Window (Simple)
121
+
122
+ ```python
123
+ def is_rate_limited(user_id: int, limit: int = 100, window: int = 60) -> bool:
124
+ key = f"ratelimit:{user_id}:{int(time.time()) // window}"
125
+ pipe = r.pipeline(transaction=True)
126
+ pipe.incr(key)
127
+ pipe.expire(key, window)
128
+ count, _ = pipe.execute()
129
+ return count > limit
130
+ ```
131
+
132
+ ### Sliding Window (Lua — Atomic)
133
+
134
+ ```lua
135
+ -- sliding_window.lua
136
+ local key = KEYS[1]
137
+ local now = tonumber(ARGV[1])
138
+ local window = tonumber(ARGV[2])
139
+ local limit = tonumber(ARGV[3])
140
+
141
+ redis.call('ZREMRANGEBYSCORE', key, 0, now - window)
142
+ local count = redis.call('ZCARD', key)
143
+
144
+ if count < limit then
145
+ -- Use unique member (now + sequence) to avoid collisions within the same millisecond
146
+ local seq_key = key .. ':seq'
147
+ local seq = redis.call('INCR', seq_key)
148
+ redis.call('EXPIRE', seq_key, math.ceil(window / 1000))
149
+ redis.call('ZADD', key, now, now .. '-' .. seq)
150
+ redis.call('EXPIRE', key, math.ceil(window / 1000))
151
+ return 1
152
+ end
153
+ return 0
154
+ ```
155
+
156
+ ```python
157
+ sliding_window = r.register_script(open('sliding_window.lua').read())
158
+
159
+ def allow_request(user_id: int) -> bool:
160
+ key = f"ratelimit:sliding:{user_id}"
161
+ now = int(time.time() * 1000)
162
+ return bool(sliding_window(keys=[key], args=[now, 60000, 100]))
163
+ ```
164
+
165
+ ## Distributed Locks
166
+
167
+ ### Distributed Lock (Single Node — SET NX PX)
168
+
169
+ ```python
170
+ import uuid
171
+
172
+ def acquire_lock(resource: str, ttl_ms: int = 5000) -> str | None:
173
+ lock_key = f"lock:{resource}"
174
+ token = str(uuid.uuid4())
175
+ acquired = r.set(lock_key, token, px=ttl_ms, nx=True)
176
+ return token if acquired else None
177
+
178
+ def release_lock(resource: str, token: str) -> bool:
179
+ release_script = """
180
+ if redis.call('get', KEYS[1]) == ARGV[1] then
181
+ return redis.call('del', KEYS[1])
182
+ else
183
+ return 0
184
+ end
185
+ """
186
+ result = r.eval(release_script, 1, f"lock:{resource}", token)
187
+ return bool(result)
188
+
189
+ # Usage
190
+ token = acquire_lock("order:payment:123")
191
+ if token:
192
+ try:
193
+ process_payment()
194
+ finally:
195
+ release_lock("order:payment:123", token)
196
+ ```
197
+
198
+ > For multi-node setups use the `redlock-py` library which implements the full Redlock algorithm.
199
+
200
+ ## Pub/Sub & Streams
201
+
202
+ ### Pub/Sub (Fire-and-Forget)
203
+
204
+ ```python
205
+ # Publisher
206
+ def publish_event(channel: str, payload: dict):
207
+ r.publish(channel, json.dumps(payload))
208
+
209
+ # Subscriber (blocking — run in separate thread/process)
210
+ def subscribe_events(channel: str):
211
+ pubsub = r.pubsub()
212
+ pubsub.subscribe(channel)
213
+ for message in pubsub.listen():
214
+ if message['type'] == 'message':
215
+ handle(json.loads(message['data']))
216
+ ```
217
+
218
+ ### Redis Streams (Durable Queue)
219
+
220
+ ```python
221
+ # Producer
222
+ def emit(stream: str, event: dict):
223
+ r.xadd(stream, event, maxlen=10000) # Cap stream length
224
+
225
+ # Consumer group — guarantees at-least-once delivery
226
+ try:
227
+ r.xgroup_create('events:orders', 'processor', id='0', mkstream=True)
228
+ except Exception:
229
+ pass # Group already exists
230
+
231
+ def consume(stream: str, group: str, consumer: str):
232
+ while True:
233
+ messages = r.xreadgroup(group, consumer, {stream: '>'}, count=10, block=2000)
234
+ for _, entries in (messages or []):
235
+ for msg_id, data in entries:
236
+ process(data)
237
+ r.xack(stream, group, msg_id)
238
+ ```
239
+
240
+ > Prefer **Streams** over Pub/Sub when you need delivery guarantees, consumer groups, or replay.
241
+
242
+ ## Key Design
243
+
244
+ ### Naming Conventions
245
+
246
+ ```
247
+ # Pattern: resource:id:field
248
+ user:123:profile
249
+ order:456:status
250
+ cache:product:789
251
+
252
+ # Pattern: namespace:resource:id
253
+ myapp:session:abc123
254
+ myapp:ratelimit:user:123
255
+
256
+ # Pattern: resource:date (time-bound keys)
257
+ stats:pageviews:2024-01-01
258
+ ```
259
+
260
+ ### TTL Strategy
261
+
262
+ | Data Type | Suggested TTL |
263
+ |-----------|--------------|
264
+ | User session | 24h (`86400`) |
265
+ | API response cache | 5–15 min |
266
+ | Rate limit window | Match window size |
267
+ | Short-lived tokens | 5–10 min |
268
+ | Leaderboard | 1h–24h |
269
+ | Static/reference data | 1h–1 week |
270
+
271
+ Always set a TTL. Keys without TTL accumulate indefinitely and cause memory pressure.
272
+
273
+ ## Connection Management
274
+
275
+ ### Connection Pooling
276
+
277
+ ```python
278
+ from redis import ConnectionPool, Redis
279
+
280
+ pool = ConnectionPool(
281
+ host='localhost',
282
+ port=6379,
283
+ db=0,
284
+ max_connections=20,
285
+ decode_responses=True,
286
+ socket_connect_timeout=2,
287
+ socket_timeout=2,
288
+ )
289
+
290
+ r = Redis(connection_pool=pool)
291
+ ```
292
+
293
+ ### Cluster Mode
294
+
295
+ ```python
296
+ from redis.cluster import RedisCluster
297
+
298
+ r = RedisCluster(
299
+ startup_nodes=[{"host": "redis-1", "port": 6379}],
300
+ decode_responses=True,
301
+ skip_full_coverage_check=True,
302
+ )
303
+ ```
304
+
305
+ ### Sentinel (High Availability)
306
+
307
+ ```python
308
+ from redis.sentinel import Sentinel
309
+
310
+ sentinel = Sentinel(
311
+ [('sentinel-1', 26379), ('sentinel-2', 26379)],
312
+ socket_timeout=0.5,
313
+ )
314
+ master = sentinel.master_for('mymaster', decode_responses=True)
315
+ replica = sentinel.slave_for('mymaster', decode_responses=True)
316
+ ```
317
+
318
+ ## Eviction Policies
319
+
320
+ | Policy | Behavior | Best For |
321
+ |--------|----------|----------|
322
+ | `noeviction` | Error on write when full | Queues / critical data |
323
+ | `allkeys-lru` | Evict least recently used | General cache |
324
+ | `volatile-lru` | LRU only among keys with TTL | Mixed data store |
325
+ | `allkeys-lfu` | Evict least frequently used | Skewed access patterns |
326
+ | `volatile-ttl` | Evict soonest-to-expire | Prioritize long-lived data |
327
+
328
+ Set via `redis.conf`: `maxmemory-policy allkeys-lru`
329
+
330
+ ## Anti-Patterns
331
+
332
+ | Anti-Pattern | Problem | Fix |
333
+ |---|---|---|
334
+ | Keys with no TTL | Memory grows unbounded | Always set TTL |
335
+ | `KEYS *` in production | Blocks the server (O(N)) | Use `SCAN` cursor |
336
+ | Storing large blobs (>100KB) | Slow serialization, memory pressure | Store reference + fetch from object store |
337
+ | Single Redis for everything | No isolation between cache & queue | Use separate DBs or instances |
338
+ | Ignoring connection pool limits | Connection exhaustion under load | Size pool to workload |
339
+ | Not handling cache miss stampede | Thundering herd on cold start | Use locks or probabilistic early expiry |
340
+ | `FLUSHALL` without thought | Wipes entire instance | Scope deletes by key pattern |
341
+
342
+ ### Cache Miss Stampede Prevention
343
+
344
+ ```python
345
+ import threading
346
+
347
+ _locks: dict[str, threading.Lock] = {}
348
+ _locks_mutex = threading.Lock()
349
+
350
+ def get_with_lock(key: str, fetch_fn, ttl: int = 300):
351
+ cached = r.get(key)
352
+ if cached:
353
+ return json.loads(cached)
354
+
355
+ with _locks_mutex:
356
+ if key not in _locks:
357
+ _locks[key] = threading.Lock()
358
+ lock = _locks[key]
359
+ with lock:
360
+ cached = r.get(key) # Re-check after acquiring lock
361
+ if cached:
362
+ return json.loads(cached)
363
+ value = fetch_fn()
364
+ r.setex(key, ttl, json.dumps(value))
365
+ return value
366
+ ```
367
+
368
+ > Note: for multi-process deployments, replace the in-process lock with `acquire_lock`/`release_lock` from the Distributed Locks section above.
369
+
370
+ ## Examples
371
+
372
+ **Add caching to a Django/Flask API endpoint:**
373
+ Use cache-aside with `setex` and a 5-minute TTL on the response. Key on the request parameters.
374
+
375
+ **Rate-limit an API by user:**
376
+ Use fixed-window with `pipeline(transaction=True)` for low-traffic endpoints; use sliding-window Lua for accurate per-user throttling.
377
+
378
+ **Coordinate a background job across workers:**
379
+ Use `acquire_lock` with a TTL that exceeds the expected job duration. Always release in a `finally` block.
380
+
381
+ **Fan-out notifications to multiple subscribers:**
382
+ Use Pub/Sub for fire-and-forget. Switch to Streams if you need guaranteed delivery or replay for late consumers.
383
+
384
+ ## Quick Reference
385
+
386
+ | Pattern | When to Use |
387
+ |---------|-------------|
388
+ | Cache-aside | Read-heavy, tolerate slight staleness |
389
+ | Write-through | Strong consistency required |
390
+ | Distributed lock | Prevent concurrent access to a resource |
391
+ | Sliding window rate limit | Accurate per-user throttling |
392
+ | Redis Streams | Durable event queue with consumer groups |
393
+ | Pub/Sub | Broadcast with no delivery guarantees needed |
394
+ | Sorted Set leaderboard | Ranked scoring, pagination |
395
+ | HyperLogLog | Approximate unique count at low memory |
396
+
397
+ ## Related
398
+
399
+ - Skill: `postgres-patterns` — relational data patterns
400
+ - Skill: `backend-patterns` — API and service layer patterns
401
+ - Skill: `database-migrations` — schema versioning
402
+ - Skill: `django-patterns` — Django cache framework integration
403
+ - Agent: `database-reviewer` — full database review workflow
@@ -0,0 +1,260 @@
1
+ # Requirements Clarity
2
+
3
+ A systematic skill for transforming vague requirements into actionable Product Requirements Documents (PRDs) through focused dialogue and iterative clarification.
4
+
5
+ ## Purpose
6
+
7
+ This skill helps you avoid costly misunderstandings and rework by ensuring requirements are crystal clear before implementation begins. It uses a 100-point scoring system to systematically identify gaps and guide you through targeted questions until your requirements are development-ready.
8
+
9
+ ## When to Use This Skill
10
+
11
+ ### Use When
12
+ - Requirements are vague or ambiguous (e.g., "add login feature", "implement payment")
13
+ - Features are complex and estimated to take more than 2 days
14
+ - Cross-team coordination is required
15
+ - Missing technical context (no tech stack, integration points, or constraints mentioned)
16
+ - Incomplete specifications (no acceptance criteria, success metrics, edge cases)
17
+ - Unclear scope boundaries ("what exactly does 'user management' include?")
18
+
19
+ ### Don't Use When
20
+ - Specific file paths are mentioned (e.g., "fix auth.go:45")
21
+ - Code snippets are already included in the request
22
+ - Working with existing functions/classes (use code review instead)
23
+ - Bug fixes with clear reproduction steps
24
+
25
+ ## How It Works
26
+
27
+ ### The Clarification Process
28
+
29
+ 1. **Initial Analysis** (Step 1)
30
+ - Parses your requirement description
31
+ - Generates a clarity score (0-100) using a detailed rubric
32
+ - Identifies what's clear and what needs clarification
33
+ - Creates a feature name and prepares for PRD generation
34
+
35
+ 2. **Gap Analysis** (Step 2)
36
+ - Systematically identifies missing information across four dimensions:
37
+ - **Functional Scope**: Core functionality, boundaries, edge cases
38
+ - **User Interaction**: Inputs, outputs, success/failure scenarios
39
+ - **Technical Constraints**: Performance, compatibility, security, scalability
40
+ - **Business Value**: Problem statement, target users, success metrics
41
+
42
+ 3. **Interactive Clarification** (Step 3)
43
+ - Asks 2-3 focused questions per round (avoids overwhelming you)
44
+ - Builds context progressively
45
+ - Updates clarity score after each response
46
+ - Continues until score reaches ≥ 90/100
47
+
48
+ 4. **PRD Generation** (Step 4)
49
+ - Once clarity score ≥ 90, generates comprehensive PRD
50
+ - Saves to `./docs/prds/{feature-name}-v{version}-prd.md`
51
+ - Includes all clarified information in structured format
52
+
53
+ ### Clarity Scoring Rubric
54
+
55
+ The 100-point scoring system evaluates:
56
+
57
+ - **Functional Clarity** (30 points): Clear inputs/outputs, user interaction, success criteria
58
+ - **Technical Specificity** (25 points): Technology stack, integration points, constraints
59
+ - **Implementation Completeness** (25 points): Edge cases, error handling, data validation
60
+ - **Business Context** (20 points): Problem statement, target users, success metrics
61
+
62
+ ## Key Features
63
+
64
+ ### Systematic Questioning
65
+ - Focused, specific questions (not overwhelming)
66
+ - One category at a time
67
+ - Builds on previous answers
68
+ - Uses your language and provides examples
69
+
70
+ ### Quality-Driven Iteration
71
+ - Continuous clarity assessment
72
+ - Transparent score updates
73
+ - Iterates until ≥ 90 points achieved
74
+ - Documents all clarification rounds
75
+
76
+ ### Actionable Output
77
+ - Concrete specifications ready for development
78
+ - Measurable acceptance criteria (checklistable format)
79
+ - Executable implementation phases with specific tasks
80
+ - Complete PRD with all necessary sections
81
+
82
+ ### Core Principles
83
+ - **Why?** (YAGNI check) - Ensures features are truly needed
84
+ - **Simpler?** (KISS check) - Explores simpler alternatives before complex solutions
85
+
86
+ ## Usage Examples
87
+
88
+ ### Example 1: Vague Feature Request
89
+
90
+ **User Input:**
91
+ ```
92
+ I need a login feature for my app.
93
+ ```
94
+
95
+ **Skill Response:**
96
+ ```
97
+ I understand your requirement. Let me help you refine this specification.
98
+
99
+ Current Clarity Score: 25/100
100
+
101
+ Clear Aspects:
102
+ - Need authentication functionality
103
+
104
+ Needs Clarification:
105
+ - Authentication method (email/password, OAuth, SSO?)
106
+ - User types and permissions
107
+ - Security requirements
108
+ - Integration with existing systems
109
+ - Success metrics
110
+
111
+ Let me systematically clarify these points...
112
+
113
+ 1. Authentication Method: What authentication method do you prefer?
114
+ - For example: Email/password, social login (Google/GitHub),
115
+ magic links, or SSO?
116
+
117
+ 2. User Management: Do you need different user roles or permissions?
118
+ - For example: Admin vs. regular users, or all users have same access?
119
+
120
+ 3. Technology Stack: What's your current tech stack?
121
+ - For example: React frontend, Node.js backend, PostgreSQL database?
122
+ ```
123
+
124
+ ### Example 2: After Clarification Round
125
+
126
+ **After User Response:**
127
+ ```
128
+ Thank you for the additional information!
129
+
130
+ Clarity Score Update: 25/100 → 65/100
131
+
132
+ New Clarified Content:
133
+ - Authentication: Email/password with optional Google OAuth
134
+ - User roles: Admin and regular users with different permissions
135
+ - Tech stack: Next.js 14, PostgreSQL, using NextAuth.js
136
+
137
+ Remaining Points to Clarify:
138
+ - Password requirements and security constraints
139
+ - Session management (duration, refresh tokens?)
140
+ - Edge cases (account lockout, password reset)
141
+ - Success metrics (MAU, conversion rate?)
142
+
143
+ Let me continue with the next round of questions...
144
+
145
+ 1. Security Requirements: What are your password requirements?
146
+ - For example: Minimum length, special characters, 2FA?
147
+
148
+ 2. Session Management: How long should user sessions last?
149
+ - For example: 24 hours, 7 days, remember me option?
150
+
151
+ 3. Edge Cases: How should we handle failed login attempts?
152
+ - For example: Rate limiting, account lockout after X attempts?
153
+ ```
154
+
155
+ ### Example 3: Final PRD Generation
156
+
157
+ **When Clarity Score ≥ 90:**
158
+ ```
159
+ Perfect! I will now generate the complete PRD document...
160
+
161
+ [Generates PRD at ./docs/prds/user-authentication-v1.0-prd.md]
162
+
163
+ Your Product Requirements Document is ready!
164
+
165
+ File: ./docs/prds/user-authentication-v1.0-prd.md
166
+ Quality Score: 92/100
167
+ Clarification Rounds: 3
168
+
169
+ The PRD includes:
170
+ ✓ Complete requirements description with background and value proposition
171
+ ✓ Technical approach with architecture decisions
172
+ ✓ Measurable acceptance criteria (functional, quality, user acceptance)
173
+ ✓ 4 execution phases with specific tasks and deliverables
174
+ ✓ Risk assessment and mitigation strategies
175
+
176
+ You can now hand this off to your development team for implementation.
177
+ ```
178
+
179
+ ## Generated PRD Structure
180
+
181
+ The final PRD includes:
182
+
183
+ 1. **Requirements Description**
184
+ - Background (business problem, target users, value proposition)
185
+ - Feature overview (core features, boundaries, user scenarios)
186
+ - Detailed requirements (I/O, user interaction, data, edge cases)
187
+
188
+ 2. **Design Decisions**
189
+ - Technical approach (architecture, components, data storage, interfaces)
190
+ - Constraints (performance, compatibility, security, scalability)
191
+ - Risk assessment (technical, dependency, schedule risks)
192
+
193
+ 3. **Acceptance Criteria**
194
+ - Functional acceptance (feature-specific conditions)
195
+ - Quality standards (code quality, test coverage, performance, security)
196
+ - User acceptance (UX, documentation, training)
197
+
198
+ 4. **Execution Phases**
199
+ - Phase 1: Preparation (environment setup, technical validation)
200
+ - Phase 2: Core Development (implement core functionality)
201
+ - Phase 3: Integration & Testing (quality assurance)
202
+ - Phase 4: Deployment (release and monitoring)
203
+
204
+ Each phase includes specific tasks, deliverables, and time estimates.
205
+
206
+ ## Output Location
207
+
208
+ PRDs are saved to:
209
+ ```
210
+ ./docs/prds/{feature-name}-v{version}-prd.md
211
+ ```
212
+
213
+ Where:
214
+ - `{feature-name}`: Auto-generated in kebab-case format
215
+ - `{version}`: Document version (default 1.0, or user-specified)
216
+
217
+ ## Best Practices
218
+
219
+ ### DO
220
+ - Answer questions thoroughly but concisely
221
+ - Provide examples when you have specific preferences
222
+ - Ask for clarification if questions aren't clear
223
+ - Review the final PRD and provide feedback
224
+ - Share constraints and non-negotiables upfront
225
+
226
+ ### DON'T
227
+ - Rush through clarification rounds
228
+ - Assume the skill knows your technical context
229
+ - Skip questions that seem "obvious"
230
+ - Approve PRD before reviewing thoroughly
231
+ - Provide contradictory information across rounds
232
+
233
+ ## Success Criteria
234
+
235
+ A successful requirements clarification session results in:
236
+ - Clarity score ≥ 90/100
237
+ - All PRD sections complete with substantial content
238
+ - Acceptance criteria in checklistable format
239
+ - Execution phases with actionable, concrete tasks
240
+ - Development team can start implementation immediately
241
+ - No major questions or ambiguities remain
242
+
243
+ ## Tips for Better Results
244
+
245
+ 1. **Be Specific**: Instead of "fast", say "< 200ms response time"
246
+ 2. **Think End-to-End**: Consider the full user journey
247
+ 3. **Share Constraints Early**: Technical limitations, budget, timeline
248
+ 4. **Provide Context**: Explain the "why" behind your requirement
249
+ 5. **Reference Examples**: "Like Stripe's payment flow" is clearer than abstract descriptions
250
+
251
+ ## Related Skills
252
+
253
+ - **feature-planning**: For breaking down features after PRD is complete
254
+ - **implementation-blueprint**: For detailed implementation planning
255
+ - **dev-spec**: For complete design and planning sessions
256
+ - **critical-brainstorm**: For exploring and stress-testing ideas before clarification
257
+
258
+ ---
259
+
260
+ **Need help clarifying requirements?** Invoke this skill and provide your initial requirement description. The skill will guide you through systematic clarification until you have a development-ready PRD.