markdown_exec 3.5.1 → 3.5.2
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.
- checksums.yaml +4 -4
- data/.ai-agent-instructions +54 -0
- data/.cursorrules +198 -0
- data/.rubocop.wide.yml +5 -0
- data/.rubocop.yml +7 -2
- data/CHANGELOG.md +12 -1
- data/Gemfile.lock +1 -1
- data/Rakefile +2 -0
- data/ai-principles.md +516 -0
- data/architecture-decisions.md +190 -0
- data/bats/block-hide.bats +1 -1
- data/bats/block-type-bash.bats +5 -5
- data/bats/block-type-link.bats +1 -1
- data/bats/block-type-opts.bats +3 -3
- data/bats/block-type-port.bats +2 -2
- data/bats/block-type-shell-require-ux.bats +2 -2
- data/bats/block-type-ux-allowed.bats +4 -4
- data/bats/block-type-ux-auto.bats +1 -1
- data/bats/block-type-ux-chained.bats +1 -1
- data/bats/block-type-ux-default.bats +1 -1
- data/bats/block-type-ux-echo-hash-transform.bats +1 -1
- data/bats/block-type-ux-echo-hash.bats +2 -2
- data/bats/block-type-ux-echo.bats +3 -3
- data/bats/block-type-ux-exec-hash-transform.bats +1 -1
- data/bats/block-type-ux-exec-hash.bats +2 -2
- data/bats/block-type-ux-exec.bats +1 -1
- data/bats/block-type-ux-force.bats +1 -1
- data/bats/block-type-ux-formats.bats +1 -1
- data/bats/block-type-ux-hidden.bats +1 -1
- data/bats/block-type-ux-invalid.bats +1 -1
- data/bats/block-type-ux-readonly.bats +1 -1
- data/bats/block-type-ux-require-chained.bats +2 -2
- data/bats/block-type-ux-require-context.bats +2 -2
- data/bats/block-type-ux-require.bats +2 -2
- data/bats/block-type-ux-required-variables.bats +1 -1
- data/bats/block-type-ux-row-format.bats +1 -1
- data/bats/block-type-ux-sources.bats +4 -4
- data/bats/block-type-ux-transform.bats +1 -1
- data/bats/block-type-vars.bats +3 -3
- data/bats/border.bats +1 -1
- data/bats/cli.bats +11 -11
- data/bats/command-substitution-options.bats +2 -2
- data/bats/command-substitution.bats +1 -1
- data/bats/document-shell.bats +1 -1
- data/bats/history.bats +5 -5
- data/bats/import-conflict.bats +1 -1
- data/bats/import-directive-line-continuation.bats +1 -1
- data/bats/import-directive-parameter-symbols.bats +1 -1
- data/bats/import-duplicates.bats +6 -6
- data/bats/import-parameter-symbols.bats +1 -1
- data/bats/import-with-text-substitution.bats +1 -1
- data/bats/import.bats +3 -3
- data/bats/indented-block-type-vars.bats +1 -1
- data/bats/indented-multi-line-output.bats +1 -1
- data/bats/line-decor-dynamic.bats +1 -1
- data/bats/line-wrapping.bats +1 -1
- data/bats/load-vars-state-demo.bats +4 -4
- data/bats/markup.bats +4 -4
- data/bats/mde.bats +4 -4
- data/bats/option-expansion.bats +1 -1
- data/bats/options-collapse.bats +4 -4
- data/bats/options.bats +47 -17
- data/bats/plain.bats +1 -1
- data/bats/publish.bats +2 -2
- data/bats/table-column-truncate.bats +1 -1
- data/bats/table.bats +2 -2
- data/bats/variable-expansion-multiline.bats +1 -1
- data/bats/variable-expansion.bats +6 -6
- data/conversation-template.md +611 -0
- data/docs/block-execution-modes.md +177 -0
- data/docs/block-filtering.md +252 -0
- data/docs/block-naming-patterns.md +210 -0
- data/docs/block-scanning-patterns.md +248 -0
- data/docs/cli-reference.md +370 -0
- data/docs/dev/block-hide.md +1 -1
- data/docs/dev/block-type-ux-transform.md +5 -4
- data/docs/dev/print_bytes.md +3 -0
- data/docs/dev/shebang.md +6 -0
- data/docs/docker-testing.md +5 -0
- data/docs/execution-control.md +384 -0
- data/docs/getting-started.md +209 -0
- data/docs/import-options.md +391 -0
- data/docs/tab-completion.md +7 -0
- data/docs/ux-blocks.md +376 -0
- data/examples/linked1.md +8 -1
- data/implementation-decisions.md +212 -0
- data/lib/cached_nested_file_reader.rb +138 -1
- data/lib/command_result.rb +27 -6
- data/lib/executed_shell_command.rb +512 -0
- data/lib/filter.rb +7 -7
- data/lib/hash_delegator.rb +403 -350
- data/lib/link_history.rb +22 -11
- data/lib/markdown_exec/version.rb +1 -1
- data/lib/mdoc.rb +103 -44
- data/lib/menu.src.yml +110 -83
- data/lib/menu.yml +149 -83
- data/lib/transformed_shell_command.rb +449 -0
- data/lib/wl.rb +15 -0
- data/lib/ww.rb +16 -5
- data/requirements.md +111 -0
- data/semantic-tokens.md +132 -0
- data/tasks.md +69 -0
- metadata +26 -4
- data/docs/ux-blocks-examples.md +0 -120
- data/docs/ux-blocks-init-act.md +0 -100
|
@@ -0,0 +1,611 @@
|
|
|
1
|
+
# STDD Conversation Template: Adding a Feature to an Existing Complex Application
|
|
2
|
+
|
|
3
|
+
**STDD Methodology Version**: 1.0.0
|
|
4
|
+
|
|
5
|
+
This template demonstrates a realistic conversation between a developer and an AI-coder following the STDD methodology when adding a feature to an existing, complex application.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Scenario: Adding Rate Limiting to API Endpoints
|
|
10
|
+
|
|
11
|
+
### Context
|
|
12
|
+
- **Existing Application**: REST API service with multiple endpoints
|
|
13
|
+
- **Feature Request**: Add rate limiting to prevent abuse
|
|
14
|
+
- **Complexity**: Requires integration with existing middleware, configuration, and monitoring
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Conversation Flow
|
|
19
|
+
|
|
20
|
+
### 🎯 Phase 1: Requirements → Pseudo-Code (NO CODE YET)
|
|
21
|
+
|
|
22
|
+
#### Developer Request
|
|
23
|
+
|
|
24
|
+
**Developer**: "I need to add rate limiting to our API endpoints. We're getting hit with too many requests from some clients and it's affecting performance. Can you help implement this?"
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
#### AI Response: Acknowledgment and Planning Phase
|
|
29
|
+
|
|
30
|
+
**AI**: "Observing AI principles!"
|
|
31
|
+
|
|
32
|
+
I'll help you add rate limiting to your API endpoints. Following STDD methodology, let me first understand the requirements and document the approach before writing any code.
|
|
33
|
+
|
|
34
|
+
**Questions to clarify requirements:**
|
|
35
|
+
|
|
36
|
+
1. **Rate limiting scope**: Should this apply to all endpoints, or specific endpoints? Do we need different limits for different endpoints?
|
|
37
|
+
|
|
38
|
+
2. **Rate limiting algorithm**: What approach do you prefer?
|
|
39
|
+
- Token bucket
|
|
40
|
+
- Fixed window
|
|
41
|
+
- Sliding window
|
|
42
|
+
- Leaky bucket
|
|
43
|
+
|
|
44
|
+
3. **Storage**: Where should we store rate limit counters?
|
|
45
|
+
- In-memory (simple, but lost on restart)
|
|
46
|
+
- Redis (distributed, persistent)
|
|
47
|
+
- Database (persistent, but slower)
|
|
48
|
+
|
|
49
|
+
4. **Response behavior**: When rate limit is exceeded, should we:
|
|
50
|
+
- Return HTTP 429 (Too Many Requests)
|
|
51
|
+
- Include retry-after headers
|
|
52
|
+
- Log the event
|
|
53
|
+
|
|
54
|
+
5. **Configuration**: Should rate limits be:
|
|
55
|
+
- Hard-coded
|
|
56
|
+
- Configurable via config file
|
|
57
|
+
- Per-user/API key based
|
|
58
|
+
|
|
59
|
+
6. **Monitoring**: Do you need metrics/logging for rate limit hits?
|
|
60
|
+
|
|
61
|
+
Please provide answers to these questions, or I can proceed with reasonable defaults based on best practices.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
#### Developer Response
|
|
66
|
+
|
|
67
|
+
**Developer**: "Let me answer your questions:
|
|
68
|
+
|
|
69
|
+
1. Apply to all endpoints, but allow different limits per endpoint
|
|
70
|
+
2. Token bucket algorithm - it's more flexible
|
|
71
|
+
3. Redis - we already have it in our stack
|
|
72
|
+
4. Return HTTP 429 with Retry-After header, and log it
|
|
73
|
+
5. Configurable via config file, with per-endpoint overrides
|
|
74
|
+
6. Yes, we need metrics for monitoring
|
|
75
|
+
|
|
76
|
+
Also, we need to exempt certain API keys (admin keys) from rate limiting."
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
#### AI Response: Phase 1 - Requirements Documentation
|
|
81
|
+
|
|
82
|
+
**AI**: "Observing AI principles!"
|
|
83
|
+
|
|
84
|
+
Perfect! Let me document the requirements with satisfaction and validation criteria, then work through architecture and implementation decisions. **No code changes yet** - this is the planning phase.
|
|
85
|
+
|
|
86
|
+
I'll now:
|
|
87
|
+
1. Add the requirement to `requirements.md` with satisfaction and validation criteria
|
|
88
|
+
2. Document architecture decisions in `architecture-decisions.md`
|
|
89
|
+
3. Document implementation decisions in `implementation-decisions.md`
|
|
90
|
+
4. Update `semantic-tokens.md` with new tokens
|
|
91
|
+
5. Create tasks in `tasks.md`
|
|
92
|
+
|
|
93
|
+
Let me start:
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
**AI** (updating documentation):
|
|
98
|
+
|
|
99
|
+
I've documented the requirement `[REQ:RATE_LIMITING]` in `requirements.md` with:
|
|
100
|
+
|
|
101
|
+
- **Description**: Rate limiting for all API endpoints with configurable limits
|
|
102
|
+
- **Rationale**: Prevent abuse and ensure fair resource usage
|
|
103
|
+
- **Satisfaction Criteria**:
|
|
104
|
+
- Rate limiting applies to all endpoints by default
|
|
105
|
+
- Per-endpoint rate limit configuration supported
|
|
106
|
+
- Token bucket algorithm implemented
|
|
107
|
+
- Redis storage for rate limit counters
|
|
108
|
+
- HTTP 429 response with Retry-After header when limit exceeded
|
|
109
|
+
- Admin API keys exempt from rate limiting
|
|
110
|
+
- Rate limit events logged
|
|
111
|
+
- Metrics exposed for monitoring
|
|
112
|
+
|
|
113
|
+
- **Validation Criteria**:
|
|
114
|
+
- Unit tests for token bucket algorithm
|
|
115
|
+
- Integration tests for rate limiting middleware
|
|
116
|
+
- Tests for HTTP 429 response and headers
|
|
117
|
+
- Tests for admin key exemption
|
|
118
|
+
- Load tests to verify rate limiting behavior
|
|
119
|
+
- Manual verification of metrics and logging
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
**AI** (continuing):
|
|
124
|
+
|
|
125
|
+
Now documenting architecture decisions in `architecture-decisions.md`:
|
|
126
|
+
|
|
127
|
+
I've added `[ARCH:RATE_LIMITING_MIDDLEWARE]` which:
|
|
128
|
+
- Uses middleware pattern to intercept requests before handlers
|
|
129
|
+
- Integrates with existing middleware chain
|
|
130
|
+
- References `[REQ:RATE_LIMITING]`
|
|
131
|
+
|
|
132
|
+
I've added `[ARCH:TOKEN_BUCKET_ALGORITHM]` which:
|
|
133
|
+
- Implements token bucket for flexible rate limiting
|
|
134
|
+
- References `[REQ:RATE_LIMITING]`
|
|
135
|
+
|
|
136
|
+
I've added `[ARCH:REDIS_STORAGE]` which:
|
|
137
|
+
- Uses Redis for distributed rate limit counter storage
|
|
138
|
+
- References `[REQ:RATE_LIMITING]`
|
|
139
|
+
|
|
140
|
+
I've added `[ARCH:CONFIGURATION_MANAGEMENT]` which:
|
|
141
|
+
- Extends existing config structure for rate limit settings
|
|
142
|
+
- Supports per-endpoint overrides
|
|
143
|
+
- References `[REQ:RATE_LIMITING]`
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
**AI** (continuing):
|
|
148
|
+
|
|
149
|
+
Now documenting implementation decisions in `implementation-decisions.md`:
|
|
150
|
+
|
|
151
|
+
I've added `[IMPL:TOKEN_BUCKET_STRUCT]` which:
|
|
152
|
+
- Defines data structure for token bucket state
|
|
153
|
+
- References `[ARCH:TOKEN_BUCKET_ALGORITHM]` and `[REQ:RATE_LIMITING]`
|
|
154
|
+
|
|
155
|
+
I've added `[IMPL:RATE_LIMIT_MIDDLEWARE_FUNC]` which:
|
|
156
|
+
- Implements middleware function signature
|
|
157
|
+
- References `[ARCH:RATE_LIMITING_MIDDLEWARE]` and `[REQ:RATE_LIMITING]`
|
|
158
|
+
|
|
159
|
+
I've added `[IMPL:REDIS_COUNTER_KEYS]` which:
|
|
160
|
+
- Defines Redis key naming strategy for rate limit counters
|
|
161
|
+
- References `[ARCH:REDIS_STORAGE]` and `[REQ:RATE_LIMITING]`
|
|
162
|
+
|
|
163
|
+
I've added `[IMPL:ADMIN_KEY_EXEMPTION]` which:
|
|
164
|
+
- Implements logic to check and exempt admin API keys
|
|
165
|
+
- References `[ARCH:RATE_LIMITING_MIDDLEWARE]` and `[REQ:RATE_LIMITING]`
|
|
166
|
+
|
|
167
|
+
I've added `[IMPL:METRICS_EXPOSURE]` which:
|
|
168
|
+
- Integrates with existing metrics system
|
|
169
|
+
- References `[ARCH:RATE_LIMITING_MIDDLEWARE]` and `[REQ:RATE_LIMITING]`
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
**AI** (continuing):
|
|
174
|
+
|
|
175
|
+
Updated `semantic-tokens.md` with all new tokens and their relationships.
|
|
176
|
+
|
|
177
|
+
Now creating tasks in `tasks.md`:
|
|
178
|
+
|
|
179
|
+
I've created the following tasks with priorities:
|
|
180
|
+
|
|
181
|
+
**P0 Tasks (Critical)**:
|
|
182
|
+
- `[REQ:RATE_LIMITING]` Implement token bucket algorithm core logic
|
|
183
|
+
- `[REQ:RATE_LIMITING]` Implement rate limiting middleware
|
|
184
|
+
- `[REQ:RATE_LIMITING]` Write unit tests for token bucket
|
|
185
|
+
|
|
186
|
+
**P1 Tasks (Important)**:
|
|
187
|
+
- `[REQ:RATE_LIMITING]` Integrate Redis storage
|
|
188
|
+
- `[REQ:RATE_LIMITING]` Add configuration support
|
|
189
|
+
- `[REQ:RATE_LIMITING]` Implement admin key exemption
|
|
190
|
+
- `[REQ:RATE_LIMITING]` Write integration tests
|
|
191
|
+
|
|
192
|
+
**P2 Tasks (Nice-to-Have)**:
|
|
193
|
+
- `[REQ:RATE_LIMITING]` Add metrics and logging
|
|
194
|
+
- `[REQ:RATE_LIMITING]` Add per-endpoint configuration
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
**AI** (pseudo-code):
|
|
199
|
+
|
|
200
|
+
Here's the pseudo-code approach:
|
|
201
|
+
|
|
202
|
+
```text
|
|
203
|
+
// [REQ:RATE_LIMITING] Rate Limiting Middleware
|
|
204
|
+
// [ARCH:RATE_LIMITING_MIDDLEWARE] [IMPL:RATE_LIMIT_MIDDLEWARE_FUNC]
|
|
205
|
+
function rateLimitMiddleware(config, redisClient):
|
|
206
|
+
return function(next):
|
|
207
|
+
return function(request, response):
|
|
208
|
+
// [IMPL:ADMIN_KEY_EXEMPTION] Check if admin key
|
|
209
|
+
if isAdminKey(request.apiKey):
|
|
210
|
+
return next(request, response)
|
|
211
|
+
|
|
212
|
+
// [IMPL:REDIS_COUNTER_KEYS] Get endpoint-specific config
|
|
213
|
+
endpointConfig = getEndpointConfig(request.path, config)
|
|
214
|
+
|
|
215
|
+
// [IMPL:TOKEN_BUCKET_STRUCT] Check rate limit
|
|
216
|
+
allowed = checkTokenBucket(
|
|
217
|
+
redisClient,
|
|
218
|
+
request.apiKey,
|
|
219
|
+
request.path,
|
|
220
|
+
endpointConfig.limit,
|
|
221
|
+
endpointConfig.window
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
if not allowed:
|
|
225
|
+
// [REQ:RATE_LIMITING] Return 429 with Retry-After
|
|
226
|
+
response.status = 429
|
|
227
|
+
response.headers["Retry-After"] = calculateRetryAfter(...)
|
|
228
|
+
// [REQ:RATE_LIMITING] Log event
|
|
229
|
+
logRateLimitExceeded(request)
|
|
230
|
+
// [IMPL:METRICS_EXPOSURE] Record metric
|
|
231
|
+
recordMetric("rate_limit_exceeded")
|
|
232
|
+
return response
|
|
233
|
+
|
|
234
|
+
// [REQ:RATE_LIMITING] Continue to next handler
|
|
235
|
+
return next(request, response)
|
|
236
|
+
|
|
237
|
+
// [REQ:RATE_LIMITING] Token Bucket Algorithm
|
|
238
|
+
// [ARCH:TOKEN_BUCKET_ALGORITHM] [IMPL:TOKEN_BUCKET_STRUCT]
|
|
239
|
+
function checkTokenBucket(redis, key, path, limit, window):
|
|
240
|
+
bucketKey = formatRedisKey(key, path)
|
|
241
|
+
currentTime = now()
|
|
242
|
+
|
|
243
|
+
// Get current bucket state from Redis
|
|
244
|
+
bucket = redis.get(bucketKey)
|
|
245
|
+
|
|
246
|
+
if bucket is null:
|
|
247
|
+
// Initialize new bucket
|
|
248
|
+
bucket = {tokens: limit, lastRefill: currentTime}
|
|
249
|
+
redis.set(bucketKey, bucket, ttl=window)
|
|
250
|
+
return true
|
|
251
|
+
|
|
252
|
+
// Refill tokens based on elapsed time
|
|
253
|
+
elapsed = currentTime - bucket.lastRefill
|
|
254
|
+
tokensToAdd = (elapsed / window) * limit
|
|
255
|
+
bucket.tokens = min(limit, bucket.tokens + tokensToAdd)
|
|
256
|
+
bucket.lastRefill = currentTime
|
|
257
|
+
|
|
258
|
+
// Check if request can be allowed
|
|
259
|
+
if bucket.tokens >= 1:
|
|
260
|
+
bucket.tokens -= 1
|
|
261
|
+
redis.set(bucketKey, bucket, ttl=window)
|
|
262
|
+
return true
|
|
263
|
+
else:
|
|
264
|
+
return false
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
**AI** (summary):
|
|
270
|
+
|
|
271
|
+
**Planning Phase Complete - Ready for Review**
|
|
272
|
+
|
|
273
|
+
I've completed Phase 1 of STDD:
|
|
274
|
+
|
|
275
|
+
✅ **Requirements documented** in `requirements.md` with satisfaction and validation criteria
|
|
276
|
+
✅ **Architecture decisions** documented in `architecture-decisions.md` with `[ARCH:*]` tokens
|
|
277
|
+
✅ **Implementation decisions** documented in `implementation-decisions.md` with `[IMPL:*]` tokens
|
|
278
|
+
✅ **Semantic tokens** registered in `semantic-tokens.md`
|
|
279
|
+
✅ **Tasks created** in `tasks.md` with priorities
|
|
280
|
+
✅ **Pseudo-code** provided showing the approach
|
|
281
|
+
|
|
282
|
+
**No code has been written yet** - this follows STDD's documentation-first approach.
|
|
283
|
+
|
|
284
|
+
Please review the documentation and let me know if you'd like any changes before I proceed to Phase 2 (task breakdown) and Phase 3 (implementation).
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
### ✅ Developer Approval
|
|
289
|
+
|
|
290
|
+
**Developer**: "This looks good! The approach makes sense. One clarification: for the token bucket, can we make the refill rate configurable too? So we can have different refill rates for different endpoints."
|
|
291
|
+
|
|
292
|
+
---
|
|
293
|
+
|
|
294
|
+
### 🔄 AI Response: Updating Requirements
|
|
295
|
+
|
|
296
|
+
**AI**: "Observing AI principles!"
|
|
297
|
+
|
|
298
|
+
Good catch! Let me update the requirements and architecture decisions to include configurable refill rates.
|
|
299
|
+
|
|
300
|
+
**AI** (updating documentation):
|
|
301
|
+
|
|
302
|
+
Updated `requirements.md`:
|
|
303
|
+
- Added to satisfaction criteria: "Refill rate configurable per endpoint"
|
|
304
|
+
- Added to validation criteria: "Tests for different refill rates"
|
|
305
|
+
|
|
306
|
+
Updated `architecture-decisions.md`:
|
|
307
|
+
- Enhanced `[ARCH:TOKEN_BUCKET_ALGORITHM]` to include configurable refill rate
|
|
308
|
+
- Enhanced `[ARCH:CONFIGURATION_MANAGEMENT]` to include refill rate in config
|
|
309
|
+
|
|
310
|
+
Updated `implementation-decisions.md`:
|
|
311
|
+
- Enhanced `[IMPL:TOKEN_BUCKET_STRUCT]` to include refill rate parameter
|
|
312
|
+
|
|
313
|
+
Updated pseudo-code to show refill rate calculation using config value.
|
|
314
|
+
|
|
315
|
+
Ready to proceed to Phase 2?
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
**Developer**: "Yes, proceed!"
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
### 📋 Phase 2: Pseudo-Code → Tasks (Task Breakdown)
|
|
324
|
+
|
|
325
|
+
**AI**: "Observing AI principles!"
|
|
326
|
+
|
|
327
|
+
Breaking down tasks into implementable subtasks in `tasks.md`. Each subtask is a single, complete unit of work.
|
|
328
|
+
|
|
329
|
+
**AI** (updating tasks.md):
|
|
330
|
+
|
|
331
|
+
I've broken down each task into subtasks:
|
|
332
|
+
|
|
333
|
+
**P0: Implement token bucket algorithm core logic [REQ:RATE_LIMITING]**
|
|
334
|
+
- [ ] Create `TokenBucket` struct with fields: tokens, lastRefill, limit, refillRate
|
|
335
|
+
- [ ] Implement `NewTokenBucket(limit, refillRate)` constructor
|
|
336
|
+
- [ ] Implement `AllowRequest()` method that checks and consumes tokens
|
|
337
|
+
- [ ] Implement `RefillTokens()` method that calculates and adds tokens based on elapsed time
|
|
338
|
+
- [ ] Write unit test `TestTokenBucket_REQ_RATE_LIMITING` for basic functionality
|
|
339
|
+
- [ ] Write unit test `TestTokenBucketRefill_REQ_RATE_LIMITING` for refill logic
|
|
340
|
+
- [ ] Write unit test `TestTokenBucketExhausted_REQ_RATE_LIMITING` for limit exceeded
|
|
341
|
+
|
|
342
|
+
**P0: Implement rate limiting middleware [REQ:RATE_LIMITING]**
|
|
343
|
+
- [ ] Create middleware function signature matching existing middleware pattern
|
|
344
|
+
- [ ] Extract API key from request
|
|
345
|
+
- [ ] Extract endpoint path from request
|
|
346
|
+
- [ ] Integrate token bucket check
|
|
347
|
+
- [ ] Return 429 response with Retry-After header when limit exceeded
|
|
348
|
+
- [ ] Write integration test `TestRateLimitMiddleware_REQ_RATE_LIMITING`
|
|
349
|
+
|
|
350
|
+
**P0: Write unit tests for token bucket [REQ:RATE_LIMITING]**
|
|
351
|
+
- [ ] Test token consumption
|
|
352
|
+
- [ ] Test token refill with different rates
|
|
353
|
+
- [ ] Test bucket exhaustion
|
|
354
|
+
- [ ] Test concurrent access (if applicable)
|
|
355
|
+
|
|
356
|
+
**P1: Integrate Redis storage [REQ:RATE_LIMITING]**
|
|
357
|
+
- [ ] Create Redis client wrapper for rate limiting
|
|
358
|
+
- [ ] Implement `GetBucketState(key)` function
|
|
359
|
+
- [ ] Implement `SetBucketState(key, state, ttl)` function
|
|
360
|
+
- [ ] Implement Redis key naming strategy
|
|
361
|
+
- [ ] Write integration test `TestRedisStorage_REQ_RATE_LIMITING`
|
|
362
|
+
|
|
363
|
+
**P1: Add configuration support [REQ:RATE_LIMITING]**
|
|
364
|
+
- [ ] Extend config struct with rate limit settings
|
|
365
|
+
- [ ] Add default rate limit values
|
|
366
|
+
- [ ] Add per-endpoint override structure
|
|
367
|
+
- [ ] Implement config loading and parsing
|
|
368
|
+
- [ ] Write test `TestConfigLoading_REQ_RATE_LIMITING`
|
|
369
|
+
|
|
370
|
+
**P1: Implement admin key exemption [REQ:RATE_LIMITING]**
|
|
371
|
+
- [ ] Create function `IsAdminKey(apiKey)` to check admin keys
|
|
372
|
+
- [ ] Load admin keys from configuration
|
|
373
|
+
- [ ] Add exemption check in middleware before rate limit check
|
|
374
|
+
- [ ] Write test `TestAdminKeyExemption_REQ_RATE_LIMITING`
|
|
375
|
+
|
|
376
|
+
**P1: Write integration tests [REQ:RATE_LIMITING]**
|
|
377
|
+
- [ ] Test rate limiting with real Redis
|
|
378
|
+
- [ ] Test HTTP 429 response format
|
|
379
|
+
- [ ] Test Retry-After header calculation
|
|
380
|
+
- [ ] Test admin key bypass
|
|
381
|
+
- [ ] Test per-endpoint limits
|
|
382
|
+
|
|
383
|
+
**P2: Add metrics and logging [REQ:RATE_LIMITING]**
|
|
384
|
+
- [ ] Integrate with existing metrics system
|
|
385
|
+
- [ ] Add metric for rate limit exceeded events
|
|
386
|
+
- [ ] Add logging for rate limit events
|
|
387
|
+
- [ ] Write test `TestMetrics_REQ_RATE_LIMITING`
|
|
388
|
+
|
|
389
|
+
**P2: Add per-endpoint configuration [REQ:RATE_LIMITING]**
|
|
390
|
+
- [ ] Implement endpoint path matching logic
|
|
391
|
+
- [ ] Implement config lookup with endpoint override
|
|
392
|
+
- [ ] Write test `TestPerEndpointConfig_REQ_RATE_LIMITING`
|
|
393
|
+
|
|
394
|
+
All subtasks are now documented. Ready to proceed to Phase 3 (implementation)?
|
|
395
|
+
|
|
396
|
+
---
|
|
397
|
+
|
|
398
|
+
**Developer**: "Yes, let's start implementing. Begin with the P0 tasks."
|
|
399
|
+
|
|
400
|
+
---
|
|
401
|
+
|
|
402
|
+
### 💻 Phase 3: Tasks → Implementation
|
|
403
|
+
|
|
404
|
+
**AI**: "Observing AI principles!"
|
|
405
|
+
|
|
406
|
+
Starting with P0 tasks, beginning with the token bucket algorithm core logic.
|
|
407
|
+
|
|
408
|
+
**AI** (implementing):
|
|
409
|
+
|
|
410
|
+
Implementing the first subtask: Creating the `TokenBucket` struct.
|
|
411
|
+
|
|
412
|
+
**AI** (after completing subtask):
|
|
413
|
+
|
|
414
|
+
✅ Completed: Created `TokenBucket` struct with fields: tokens, lastRefill, limit, refillRate
|
|
415
|
+
|
|
416
|
+
Moving to next subtask: Implement `NewTokenBucket()` constructor.
|
|
417
|
+
|
|
418
|
+
**AI** (continuing implementation):
|
|
419
|
+
|
|
420
|
+
✅ Completed: Implemented `NewTokenBucket(limit, refillRate)` constructor
|
|
421
|
+
✅ Completed: Implemented `AllowRequest()` method
|
|
422
|
+
✅ Completed: Implemented `RefillTokens()` method
|
|
423
|
+
✅ Completed: Wrote unit test `TestTokenBucket_REQ_RATE_LIMITING`
|
|
424
|
+
✅ Completed: Wrote unit test `TestTokenBucketRefill_REQ_RATE_LIMITING`
|
|
425
|
+
✅ Completed: Wrote unit test `TestTokenBucketExhausted_REQ_RATE_LIMITING`
|
|
426
|
+
|
|
427
|
+
All subtasks for "Implement token bucket algorithm core logic" are complete. Removing subtasks and marking parent task complete.
|
|
428
|
+
|
|
429
|
+
**AI** (updating tasks.md):
|
|
430
|
+
|
|
431
|
+
✅ Marked "Implement token bucket algorithm core logic" as complete
|
|
432
|
+
|
|
433
|
+
Starting next P0 task: "Implement rate limiting middleware"
|
|
434
|
+
|
|
435
|
+
**AI** (implementing middleware):
|
|
436
|
+
|
|
437
|
+
✅ Completed: Created middleware function signature
|
|
438
|
+
✅ Completed: Extracted API key from request
|
|
439
|
+
✅ Completed: Extracted endpoint path from request
|
|
440
|
+
✅ Completed: Integrated token bucket check
|
|
441
|
+
✅ Completed: Return 429 response with Retry-After header
|
|
442
|
+
✅ Completed: Wrote integration test `TestRateLimitMiddleware_REQ_RATE_LIMITING`
|
|
443
|
+
|
|
444
|
+
**AI** (updating tasks.md):
|
|
445
|
+
|
|
446
|
+
✅ Marked "Implement rate limiting middleware" as complete
|
|
447
|
+
|
|
448
|
+
All P0 tasks complete. Moving to P1 tasks.
|
|
449
|
+
|
|
450
|
+
**AI** (continuing with P1 tasks):
|
|
451
|
+
|
|
452
|
+
Starting P1: "Integrate Redis storage"
|
|
453
|
+
|
|
454
|
+
**AI** (implementing Redis integration):
|
|
455
|
+
|
|
456
|
+
✅ Completed: Created Redis client wrapper
|
|
457
|
+
✅ Completed: Implemented `GetBucketState(key)`
|
|
458
|
+
✅ Completed: Implemented `SetBucketState(key, state, ttl)`
|
|
459
|
+
✅ Completed: Implemented Redis key naming strategy
|
|
460
|
+
✅ Completed: Wrote integration test `TestRedisStorage_REQ_RATE_LIMITING`
|
|
461
|
+
|
|
462
|
+
**AI** (updating tasks.md):
|
|
463
|
+
|
|
464
|
+
✅ Marked "Integrate Redis storage" as complete
|
|
465
|
+
|
|
466
|
+
Continuing with remaining P1 tasks...
|
|
467
|
+
|
|
468
|
+
**AI** (after completing all P1 tasks):
|
|
469
|
+
|
|
470
|
+
✅ All P1 tasks complete
|
|
471
|
+
|
|
472
|
+
**AI** (updating documentation):
|
|
473
|
+
|
|
474
|
+
Updating `requirements.md`:
|
|
475
|
+
- Marked `[REQ:RATE_LIMITING]` as ✅ Implemented
|
|
476
|
+
|
|
477
|
+
Updating `semantic-tokens.md`:
|
|
478
|
+
- Updated all token statuses to Implemented
|
|
479
|
+
|
|
480
|
+
All implementation complete! Should I proceed with P2 tasks (metrics and per-endpoint config), or would you like to test what we have first?
|
|
481
|
+
|
|
482
|
+
---
|
|
483
|
+
|
|
484
|
+
**Developer**: "Let's test what we have first. Run the tests and make sure everything passes."
|
|
485
|
+
|
|
486
|
+
---
|
|
487
|
+
|
|
488
|
+
**AI**: "Observing AI principles!"
|
|
489
|
+
|
|
490
|
+
Running all tests related to rate limiting:
|
|
491
|
+
|
|
492
|
+
**AI** (running tests):
|
|
493
|
+
|
|
494
|
+
```bash
|
|
495
|
+
go test -v -run "REQ_RATE_LIMITING" ./...
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
Test results:
|
|
499
|
+
- ✅ `TestTokenBucket_REQ_RATE_LIMITING` - PASSED
|
|
500
|
+
- ✅ `TestTokenBucketRefill_REQ_RATE_LIMITING` - PASSED
|
|
501
|
+
- ✅ `TestTokenBucketExhausted_REQ_RATE_LIMITING` - PASSED
|
|
502
|
+
- ✅ `TestRateLimitMiddleware_REQ_RATE_LIMITING` - PASSED
|
|
503
|
+
- ✅ `TestRedisStorage_REQ_RATE_LIMITING` - PASSED
|
|
504
|
+
- ✅ `TestConfigLoading_REQ_RATE_LIMITING` - PASSED
|
|
505
|
+
- ✅ `TestAdminKeyExemption_REQ_RATE_LIMITING` - PASSED
|
|
506
|
+
|
|
507
|
+
All tests passing! ✅
|
|
508
|
+
|
|
509
|
+
**AI** (final documentation update):
|
|
510
|
+
|
|
511
|
+
Updated `tasks.md`:
|
|
512
|
+
- All completed tasks marked as ✅ Complete
|
|
513
|
+
- All subtasks removed from completed tasks
|
|
514
|
+
|
|
515
|
+
The rate limiting feature is implemented and tested. P2 tasks (metrics and per-endpoint config) remain as optional enhancements.
|
|
516
|
+
|
|
517
|
+
---
|
|
518
|
+
|
|
519
|
+
## Key Takeaways from This Conversation
|
|
520
|
+
|
|
521
|
+
1. **AI Always Acknowledges Principles**: Every response starts with "Observing AI principles!"
|
|
522
|
+
|
|
523
|
+
2. **No Code Until Planning Complete**: Phase 1 (Requirements → Pseudo-Code) happens entirely without code changes
|
|
524
|
+
|
|
525
|
+
3. **Documentation Happens Immediately**: Architecture and implementation decisions are documented as they're made, not deferred
|
|
526
|
+
|
|
527
|
+
4. **Requirements Include Satisfaction & Validation**: Each requirement has explicit criteria for both satisfaction and validation
|
|
528
|
+
|
|
529
|
+
5. **Tasks Have Priorities**: All tasks are assigned P0/P1/P2/P3 priorities
|
|
530
|
+
|
|
531
|
+
6. **Subtasks Are Temporary**: Subtasks are removed when parent tasks complete
|
|
532
|
+
|
|
533
|
+
7. **Semantic Tokens Throughout**: Every decision, test, and code comment references semantic tokens
|
|
534
|
+
|
|
535
|
+
8. **Traceability Maintained**: Requirements → Architecture → Implementation → Tests → Code all linked via tokens
|
|
536
|
+
|
|
537
|
+
9. **Developer Can Review Before Implementation**: Planning phase allows review before any code is written
|
|
538
|
+
|
|
539
|
+
10. **Iterative Refinement**: Requirements can be refined based on developer feedback before implementation
|
|
540
|
+
|
|
541
|
+
---
|
|
542
|
+
|
|
543
|
+
## Conversation Patterns
|
|
544
|
+
|
|
545
|
+
### Pattern 1: Initial Feature Request
|
|
546
|
+
- Developer describes need
|
|
547
|
+
- AI acknowledges principles
|
|
548
|
+
- AI asks clarifying questions
|
|
549
|
+
- Developer provides answers
|
|
550
|
+
|
|
551
|
+
### Pattern 2: Planning Phase
|
|
552
|
+
- AI documents requirements with satisfaction/validation criteria
|
|
553
|
+
- AI documents architecture decisions
|
|
554
|
+
- AI documents implementation decisions
|
|
555
|
+
- AI creates tasks
|
|
556
|
+
- AI provides pseudo-code
|
|
557
|
+
- Developer reviews and approves
|
|
558
|
+
|
|
559
|
+
### Pattern 3: Refinement
|
|
560
|
+
- Developer requests changes/clarifications
|
|
561
|
+
- AI updates documentation immediately
|
|
562
|
+
- Developer approves
|
|
563
|
+
- Proceed to next phase
|
|
564
|
+
|
|
565
|
+
### Pattern 4: Implementation Phase
|
|
566
|
+
- AI implements highest priority tasks first
|
|
567
|
+
- AI updates tasks.md as subtasks complete
|
|
568
|
+
- AI removes completed subtasks
|
|
569
|
+
- AI marks parent tasks complete when all subtasks done
|
|
570
|
+
- AI updates documentation throughout
|
|
571
|
+
|
|
572
|
+
### Pattern 5: Completion
|
|
573
|
+
- AI runs tests
|
|
574
|
+
- AI verifies all documentation is current
|
|
575
|
+
- AI marks requirements as implemented
|
|
576
|
+
- AI updates token registry
|
|
577
|
+
- Developer reviews and approves
|
|
578
|
+
|
|
579
|
+
---
|
|
580
|
+
|
|
581
|
+
## Notes for Developers
|
|
582
|
+
|
|
583
|
+
When working with AI following STDD:
|
|
584
|
+
|
|
585
|
+
1. **Be Specific**: Provide clear requirements and answer clarifying questions
|
|
586
|
+
2. **Review Planning**: Take time to review Phase 1 documentation before approving
|
|
587
|
+
3. **Request Changes Early**: It's easier to change documentation than code
|
|
588
|
+
4. **Trust the Process**: The documentation-first approach prevents rework
|
|
589
|
+
5. **Verify Traceability**: Check that semantic tokens are used consistently
|
|
590
|
+
|
|
591
|
+
---
|
|
592
|
+
|
|
593
|
+
## Notes for AI Agents
|
|
594
|
+
|
|
595
|
+
When following STDD:
|
|
596
|
+
|
|
597
|
+
1. **Always Acknowledge**: Start every response with "Observing AI principles!"
|
|
598
|
+
2. **No Code in Phase 1**: Planning phase is documentation only
|
|
599
|
+
3. **Document Immediately**: Don't defer documentation - do it as decisions are made
|
|
600
|
+
4. **Ask Questions**: Clarify requirements before documenting
|
|
601
|
+
5. **Show Pseudo-Code**: Help developer visualize the approach
|
|
602
|
+
6. **Update Tasks Continuously**: Keep tasks.md current as work progresses
|
|
603
|
+
7. **Remove Subtasks**: Clean up completed subtasks
|
|
604
|
+
8. **Maintain Tokens**: Keep semantic-tokens.md updated
|
|
605
|
+
9. **Cross-Reference**: Always link tokens: IMPL → ARCH → REQ
|
|
606
|
+
10. **Test References**: Include semantic tokens in test names
|
|
607
|
+
|
|
608
|
+
---
|
|
609
|
+
|
|
610
|
+
**End of Conversation Template**
|
|
611
|
+
|