forge-workflow 1.4.0 → 1.4.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.
- package/.claude/settings.json +4 -1
- package/.claude/settings.local.json +21 -1
- package/README.md +217 -761
- package/docs/EXAMPLES.md +750 -0
- package/docs/README-v1.3.md +860 -0
- package/docs/SETUP.md +723 -0
- package/package.json +1 -1
package/docs/EXAMPLES.md
ADDED
|
@@ -0,0 +1,750 @@
|
|
|
1
|
+
# Forge Workflow Examples
|
|
2
|
+
|
|
3
|
+
Real-world examples showing how to use Forge for different scenarios.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Table of Contents
|
|
8
|
+
|
|
9
|
+
- [Example 1: Simple Feature](#example-1-simple-feature)
|
|
10
|
+
- [Example 2: Bug Fix with Security](#example-2-bug-fix-with-security)
|
|
11
|
+
- [Example 3: Multi-File Refactor](#example-3-multi-file-refactor)
|
|
12
|
+
- [Example 4: Architecture Change](#example-4-architecture-change)
|
|
13
|
+
- [Example 5: Team Collaboration](#example-5-team-collaboration)
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Example 1: Simple Feature
|
|
18
|
+
|
|
19
|
+
**Task**: Add a health check endpoint
|
|
20
|
+
|
|
21
|
+
**Estimated Time**: 15 minutes
|
|
22
|
+
|
|
23
|
+
**Workflow**: Tactical (no OpenSpec needed)
|
|
24
|
+
|
|
25
|
+
### Step-by-Step
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# ═══════════════════════════════════════════════════════════
|
|
29
|
+
# STAGE 1: STATUS - Where are we?
|
|
30
|
+
# ═══════════════════════════════════════════════════════════
|
|
31
|
+
/status
|
|
32
|
+
|
|
33
|
+
# Output:
|
|
34
|
+
# ✓ Branch: main
|
|
35
|
+
# ✓ Clean working directory
|
|
36
|
+
# ✓ No active work
|
|
37
|
+
|
|
38
|
+
# ═══════════════════════════════════════════════════════════
|
|
39
|
+
# STAGE 2: RESEARCH
|
|
40
|
+
# ═══════════════════════════════════════════════════════════
|
|
41
|
+
/research health-check-endpoint
|
|
42
|
+
|
|
43
|
+
# Creates: docs/research/health-check-endpoint.md
|
|
44
|
+
# Contains:
|
|
45
|
+
# - REST health check conventions
|
|
46
|
+
# - HTTP 200 vs 503 debate
|
|
47
|
+
# - Security: avoid exposing internal details
|
|
48
|
+
# - TDD scenarios: 200 OK test, optional dependencies
|
|
49
|
+
|
|
50
|
+
# ═══════════════════════════════════════════════════════════
|
|
51
|
+
# STAGE 3: PLAN
|
|
52
|
+
# ═══════════════════════════════════════════════════════════
|
|
53
|
+
/plan health-check-endpoint
|
|
54
|
+
|
|
55
|
+
# Creates:
|
|
56
|
+
# - Branch: feat/health-check-endpoint
|
|
57
|
+
# - Beads issue: PROJ-42
|
|
58
|
+
|
|
59
|
+
# ═══════════════════════════════════════════════════════════
|
|
60
|
+
# STAGE 4: DEV (TDD)
|
|
61
|
+
# ═══════════════════════════════════════════════════════════
|
|
62
|
+
/dev
|
|
63
|
+
|
|
64
|
+
# RED: Write failing test
|
|
65
|
+
# File: tests/health.test.js
|
|
66
|
+
describe('GET /health', () => {
|
|
67
|
+
it('returns 200 OK with status', async () => {
|
|
68
|
+
const response = await request(app).get('/health');
|
|
69
|
+
expect(response.status).toBe(200);
|
|
70
|
+
expect(response.body).toEqual({ status: 'ok' });
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
# Run → ❌ Fails
|
|
74
|
+
|
|
75
|
+
# GREEN: Minimal code
|
|
76
|
+
# File: routes/health.js
|
|
77
|
+
router.get('/health', (req, res) => {
|
|
78
|
+
res.status(200).json({ status: 'ok' });
|
|
79
|
+
});
|
|
80
|
+
# Run → ✅ Passes
|
|
81
|
+
|
|
82
|
+
# REFACTOR: (none needed)
|
|
83
|
+
git commit -m "feat: add health check endpoint"
|
|
84
|
+
|
|
85
|
+
# ═══════════════════════════════════════════════════════════
|
|
86
|
+
# STAGE 5: CHECK
|
|
87
|
+
# ═══════════════════════════════════════════════════════════
|
|
88
|
+
/check
|
|
89
|
+
|
|
90
|
+
# ✓ Type check passed
|
|
91
|
+
# ✓ Linter passed
|
|
92
|
+
# ✓ Tests passed (1 test)
|
|
93
|
+
# ✓ Security scan passed
|
|
94
|
+
|
|
95
|
+
# ═══════════════════════════════════════════════════════════
|
|
96
|
+
# STAGE 6: SHIP
|
|
97
|
+
# ═══════════════════════════════════════════════════════════
|
|
98
|
+
/ship
|
|
99
|
+
|
|
100
|
+
# Created PR #42
|
|
101
|
+
# URL: https://github.com/you/project/pull/42
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**Result**: Feature shipped in 15 minutes with tests and documentation.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Example 2: Bug Fix with Security
|
|
109
|
+
|
|
110
|
+
**Task**: Fix SQL injection vulnerability in search endpoint
|
|
111
|
+
|
|
112
|
+
**Estimated Time**: 30 minutes
|
|
113
|
+
|
|
114
|
+
**Severity**: High (security vulnerability)
|
|
115
|
+
|
|
116
|
+
### Step-by-Step
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
# ═══════════════════════════════════════════════════════════
|
|
120
|
+
# STAGE 1: STATUS
|
|
121
|
+
# ═══════════════════════════════════════════════════════════
|
|
122
|
+
/status
|
|
123
|
+
|
|
124
|
+
# If Beads installed:
|
|
125
|
+
bd create "SQL injection in search endpoint" \
|
|
126
|
+
--type bug \
|
|
127
|
+
--priority 0 \
|
|
128
|
+
--label "security,critical"
|
|
129
|
+
|
|
130
|
+
# ═══════════════════════════════════════════════════════════
|
|
131
|
+
# STAGE 2: RESEARCH
|
|
132
|
+
# ═══════════════════════════════════════════════════════════
|
|
133
|
+
/research sql-injection-fix-search
|
|
134
|
+
|
|
135
|
+
# Research includes:
|
|
136
|
+
# - OWASP A03:2021 Injection analysis
|
|
137
|
+
# - Parameterized queries vs prepared statements
|
|
138
|
+
# - Input validation best practices
|
|
139
|
+
# - Testing for SQL injection (sqlmap patterns)
|
|
140
|
+
|
|
141
|
+
# ═══════════════════════════════════════════════════════════
|
|
142
|
+
# STAGE 3: PLAN
|
|
143
|
+
# ═══════════════════════════════════════════════════════════
|
|
144
|
+
/plan sql-injection-fix-search
|
|
145
|
+
|
|
146
|
+
# Branch: fix/sql-injection-search
|
|
147
|
+
# Updates issue: PROJ-123
|
|
148
|
+
|
|
149
|
+
# ═══════════════════════════════════════════════════════════
|
|
150
|
+
# STAGE 4: DEV (TDD for security)
|
|
151
|
+
# ═══════════════════════════════════════════════════════════
|
|
152
|
+
/dev
|
|
153
|
+
|
|
154
|
+
# RED: Write test for SQL injection attempt
|
|
155
|
+
describe('POST /search security', () => {
|
|
156
|
+
it('prevents SQL injection via search param', async () => {
|
|
157
|
+
const maliciousInput = "'; DROP TABLE users--";
|
|
158
|
+
const response = await request(app)
|
|
159
|
+
.post('/search')
|
|
160
|
+
.send({ query: maliciousInput });
|
|
161
|
+
|
|
162
|
+
expect(response.status).toBe(200);
|
|
163
|
+
// Verify database still intact
|
|
164
|
+
const users = await db.query('SELECT COUNT(*) FROM users');
|
|
165
|
+
expect(users.rows[0].count).toBeGreaterThan(0);
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
# Run → ❌ Fails (database affected)
|
|
169
|
+
|
|
170
|
+
# GREEN: Fix with parameterized query
|
|
171
|
+
// Before (vulnerable):
|
|
172
|
+
const results = await db.query(
|
|
173
|
+
`SELECT * FROM products WHERE name LIKE '%${req.body.query}%'`
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
// After (safe):
|
|
177
|
+
const results = await db.query(
|
|
178
|
+
'SELECT * FROM products WHERE name LIKE $1',
|
|
179
|
+
[`%${req.body.query}%`]
|
|
180
|
+
);
|
|
181
|
+
# Run → ✅ Passes
|
|
182
|
+
|
|
183
|
+
# REFACTOR: Add input validation
|
|
184
|
+
const { query } = req.body;
|
|
185
|
+
if (!query || typeof query !== 'string') {
|
|
186
|
+
return res.status(400).json({ error: 'Invalid query' });
|
|
187
|
+
}
|
|
188
|
+
if (query.length > 100) {
|
|
189
|
+
return res.status(400).json({ error: 'Query too long' });
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
git commit -m "fix: prevent SQL injection in search endpoint
|
|
193
|
+
|
|
194
|
+
- Use parameterized queries
|
|
195
|
+
- Add input validation
|
|
196
|
+
- Add security test
|
|
197
|
+
|
|
198
|
+
OWASP A03:2021 Injection"
|
|
199
|
+
|
|
200
|
+
# ═══════════════════════════════════════════════════════════
|
|
201
|
+
# STAGE 5: CHECK
|
|
202
|
+
# ═══════════════════════════════════════════════════════════
|
|
203
|
+
/check
|
|
204
|
+
|
|
205
|
+
# ✓ Type check passed
|
|
206
|
+
# ✓ Linter passed
|
|
207
|
+
# ✓ Tests passed (including security test)
|
|
208
|
+
# ✓ Security scan: SQL injection vulnerability FIXED
|
|
209
|
+
|
|
210
|
+
# ═══════════════════════════════════════════════════════════
|
|
211
|
+
# STAGE 6: SHIP
|
|
212
|
+
# ═══════════════════════════════════════════════════════════
|
|
213
|
+
/ship
|
|
214
|
+
|
|
215
|
+
# PR description includes:
|
|
216
|
+
# ## Security Fix
|
|
217
|
+
# - Fixed SQL injection in search endpoint
|
|
218
|
+
# - OWASP A03:2021 Injection
|
|
219
|
+
# - Severity: High
|
|
220
|
+
#
|
|
221
|
+
# ## Changes
|
|
222
|
+
# - Parameterized queries
|
|
223
|
+
# - Input validation (type + length)
|
|
224
|
+
# - Security test added
|
|
225
|
+
#
|
|
226
|
+
# ## Verification
|
|
227
|
+
# - ✓ Manual sqlmap testing
|
|
228
|
+
# - ✓ Automated security scan passed
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
**Result**: Security vulnerability fixed with tests in 30 minutes.
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## Example 3: Multi-File Refactor
|
|
236
|
+
|
|
237
|
+
**Task**: Extract authentication logic to separate service
|
|
238
|
+
|
|
239
|
+
**Estimated Time**: 2-3 hours
|
|
240
|
+
|
|
241
|
+
**Files Affected**: 5-6 files
|
|
242
|
+
|
|
243
|
+
### Step-by-Step
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
# ═══════════════════════════════════════════════════════════
|
|
247
|
+
# STAGE 1: STATUS
|
|
248
|
+
# ═══════════════════════════════════════════════════════════
|
|
249
|
+
/status
|
|
250
|
+
|
|
251
|
+
bd create "Extract auth logic to service" \
|
|
252
|
+
--type chore \
|
|
253
|
+
--priority 2
|
|
254
|
+
|
|
255
|
+
# ═══════════════════════════════════════════════════════════
|
|
256
|
+
# STAGE 2: RESEARCH
|
|
257
|
+
# ═══════════════════════════════════════════════════════════
|
|
258
|
+
/research auth-service-extraction
|
|
259
|
+
|
|
260
|
+
# Research covers:
|
|
261
|
+
# - Service layer patterns
|
|
262
|
+
# - Dependency injection
|
|
263
|
+
# - Testing strategies for services
|
|
264
|
+
# - File organization
|
|
265
|
+
|
|
266
|
+
# Codebase analysis finds:
|
|
267
|
+
# - Auth logic scattered across 3 route handlers
|
|
268
|
+
# - 15 references to inline JWT code
|
|
269
|
+
# - No service layer exists yet
|
|
270
|
+
|
|
271
|
+
# ═══════════════════════════════════════════════════════════
|
|
272
|
+
# STAGE 3: PLAN
|
|
273
|
+
# ═══════════════════════════════════════════════════════════
|
|
274
|
+
/plan auth-service-extraction
|
|
275
|
+
|
|
276
|
+
# Branch: refactor/auth-service
|
|
277
|
+
# Issue: PROJ-85
|
|
278
|
+
|
|
279
|
+
# Plan includes:
|
|
280
|
+
# 1. Create AuthService class
|
|
281
|
+
# 2. Extract login logic
|
|
282
|
+
# 3. Extract signup logic
|
|
283
|
+
# 4. Extract token validation
|
|
284
|
+
# 5. Update all references
|
|
285
|
+
# 6. Add service tests
|
|
286
|
+
|
|
287
|
+
# ═══════════════════════════════════════════════════════════
|
|
288
|
+
# STAGE 4: DEV (TDD for each method)
|
|
289
|
+
# ═══════════════════════════════════════════════════════════
|
|
290
|
+
/dev
|
|
291
|
+
|
|
292
|
+
# RED: Test for AuthService.login()
|
|
293
|
+
describe('AuthService', () => {
|
|
294
|
+
describe('login', () => {
|
|
295
|
+
it('returns JWT for valid credentials', async () => {
|
|
296
|
+
const result = await authService.login('user@test.com', 'password123');
|
|
297
|
+
expect(result.token).toBeDefined();
|
|
298
|
+
expect(jwt.verify(result.token, SECRET)).toBeTruthy();
|
|
299
|
+
});
|
|
300
|
+
});
|
|
301
|
+
});
|
|
302
|
+
# Run → ❌ Fails (AuthService doesn't exist)
|
|
303
|
+
|
|
304
|
+
# GREEN: Create AuthService
|
|
305
|
+
class AuthService {
|
|
306
|
+
async login(email, password) {
|
|
307
|
+
const user = await db.findUserByEmail(email);
|
|
308
|
+
if (!user || !(await bcrypt.compare(password, user.password))) {
|
|
309
|
+
throw new Error('Invalid credentials');
|
|
310
|
+
}
|
|
311
|
+
return {
|
|
312
|
+
token: jwt.sign({ userId: user.id }, SECRET, { expiresIn: '24h' })
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
# Run → ✅ Passes
|
|
317
|
+
|
|
318
|
+
# REFACTOR: Update routes to use service
|
|
319
|
+
// Before:
|
|
320
|
+
app.post('/login', async (req, res) => {
|
|
321
|
+
const user = await db.findUserByEmail(req.body.email);
|
|
322
|
+
// ... inline JWT logic
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
// After:
|
|
326
|
+
app.post('/login', async (req, res) => {
|
|
327
|
+
const result = await authService.login(req.body.email, req.body.password);
|
|
328
|
+
res.json(result);
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
git commit -m "refactor: extract login to AuthService"
|
|
332
|
+
|
|
333
|
+
# Repeat for signup, token validation, etc.
|
|
334
|
+
# 5-6 commits total
|
|
335
|
+
|
|
336
|
+
# ═══════════════════════════════════════════════════════════
|
|
337
|
+
# STAGE 5: CHECK
|
|
338
|
+
# ═══════════════════════════════════════════════════════════
|
|
339
|
+
/check
|
|
340
|
+
|
|
341
|
+
# ✓ Type check passed
|
|
342
|
+
# ✓ Linter passed
|
|
343
|
+
# ✓ Tests passed (15 new service tests + existing route tests)
|
|
344
|
+
# ✓ Security scan passed
|
|
345
|
+
|
|
346
|
+
# ═══════════════════════════════════════════════════════════
|
|
347
|
+
# STAGE 6: SHIP
|
|
348
|
+
# ═══════════════════════════════════════════════════════════
|
|
349
|
+
/ship
|
|
350
|
+
|
|
351
|
+
# PR #85
|
|
352
|
+
# - Created AuthService class
|
|
353
|
+
# - Extracted 3 route handlers
|
|
354
|
+
# - 15 service tests
|
|
355
|
+
# - All existing tests still pass
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
**Result**: Clean refactor with full test coverage in 2-3 hours.
|
|
359
|
+
|
|
360
|
+
---
|
|
361
|
+
|
|
362
|
+
## Example 4: Architecture Change
|
|
363
|
+
|
|
364
|
+
**Task**: Add user authentication system (strategic)
|
|
365
|
+
|
|
366
|
+
**Estimated Time**: 2-3 days
|
|
367
|
+
|
|
368
|
+
**Approach**: OpenSpec proposal first
|
|
369
|
+
|
|
370
|
+
### Step-by-Step
|
|
371
|
+
|
|
372
|
+
```bash
|
|
373
|
+
# ═══════════════════════════════════════════════════════════
|
|
374
|
+
# STAGE 1: STATUS
|
|
375
|
+
# ═══════════════════════════════════════════════════════════
|
|
376
|
+
/status
|
|
377
|
+
|
|
378
|
+
# ═══════════════════════════════════════════════════════════
|
|
379
|
+
# STAGE 2: RESEARCH
|
|
380
|
+
# ═══════════════════════════════════════════════════════════
|
|
381
|
+
/research user-authentication
|
|
382
|
+
|
|
383
|
+
# Comprehensive research:
|
|
384
|
+
# - JWT vs session-based auth
|
|
385
|
+
# - Password hashing (bcrypt vs argon2)
|
|
386
|
+
# - OWASP A07:2021 Authentication Failures
|
|
387
|
+
# - OAuth 2.0 for social login
|
|
388
|
+
# - Rate limiting for login attempts
|
|
389
|
+
# - Database schema for users table
|
|
390
|
+
# - Migration strategy
|
|
391
|
+
|
|
392
|
+
# Research doc: 500+ lines
|
|
393
|
+
|
|
394
|
+
# ═══════════════════════════════════════════════════════════
|
|
395
|
+
# STAGE 3: PLAN (with OpenSpec)
|
|
396
|
+
# ═══════════════════════════════════════════════════════════
|
|
397
|
+
/plan user-authentication
|
|
398
|
+
|
|
399
|
+
# Because this is strategic (architecture change):
|
|
400
|
+
# OpenSpec proposal created
|
|
401
|
+
|
|
402
|
+
# In AI assistant (Claude, Cursor, etc.):
|
|
403
|
+
/opsx:new
|
|
404
|
+
# Describe: "Add user authentication with JWT"
|
|
405
|
+
|
|
406
|
+
/opsx:ff
|
|
407
|
+
# Generates:
|
|
408
|
+
# - openspec/changes/user-authentication/proposal.md
|
|
409
|
+
# - openspec/changes/user-authentication/design.md
|
|
410
|
+
# - openspec/changes/user-authentication/tasks.md
|
|
411
|
+
# - openspec/changes/user-authentication/specs/ (delta specs)
|
|
412
|
+
|
|
413
|
+
# Review proposal.md:
|
|
414
|
+
## Proposal: User Authentication
|
|
415
|
+
|
|
416
|
+
**Intent**: Add secure authentication system
|
|
417
|
+
|
|
418
|
+
**Scope**:
|
|
419
|
+
- User registration (email + password)
|
|
420
|
+
- Login with JWT tokens
|
|
421
|
+
- Password reset flow
|
|
422
|
+
- Rate limiting
|
|
423
|
+
- Email verification
|
|
424
|
+
|
|
425
|
+
**Rationale**:
|
|
426
|
+
- Users need private accounts
|
|
427
|
+
- Security: bcrypt, JWT, rate limiting
|
|
428
|
+
- Follows OWASP guidelines
|
|
429
|
+
|
|
430
|
+
**Alternatives Considered**:
|
|
431
|
+
1. Session-based (rejected: scalability)
|
|
432
|
+
2. OAuth only (rejected: want email/password too)
|
|
433
|
+
|
|
434
|
+
# Create PR for PROPOSAL APPROVAL first
|
|
435
|
+
git checkout -b proposal/user-authentication
|
|
436
|
+
git add openspec/
|
|
437
|
+
git commit -m "proposal: user authentication system"
|
|
438
|
+
git push
|
|
439
|
+
gh pr create --title "Proposal: User Authentication"
|
|
440
|
+
|
|
441
|
+
# Wait for approval before implementation
|
|
442
|
+
|
|
443
|
+
# ═══════════════════════════════════════════════════════════
|
|
444
|
+
# AFTER PROPOSAL APPROVED
|
|
445
|
+
# ═══════════════════════════════════════════════════════════
|
|
446
|
+
|
|
447
|
+
# Create implementation branch
|
|
448
|
+
git checkout -b feat/user-authentication
|
|
449
|
+
|
|
450
|
+
bd create "User authentication (see openspec/changes/user-authentication)" \
|
|
451
|
+
--type feature \
|
|
452
|
+
--priority 1
|
|
453
|
+
|
|
454
|
+
# ═══════════════════════════════════════════════════════════
|
|
455
|
+
# STAGE 4: DEV (TDD for each task in tasks.md)
|
|
456
|
+
# ═══════════════════════════════════════════════════════════
|
|
457
|
+
/dev
|
|
458
|
+
|
|
459
|
+
# OpenSpec tasks.md has 12 tasks:
|
|
460
|
+
# 1. Create users table migration
|
|
461
|
+
# 2. Create User model
|
|
462
|
+
# 3. Hash passwords with bcrypt
|
|
463
|
+
# 4. POST /auth/signup endpoint
|
|
464
|
+
# 5. POST /auth/login endpoint
|
|
465
|
+
# 6. JWT middleware
|
|
466
|
+
# 7. POST /auth/refresh endpoint
|
|
467
|
+
# 8. POST /auth/forgot-password endpoint
|
|
468
|
+
# 9. POST /auth/reset-password endpoint
|
|
469
|
+
# 10. Rate limiting middleware
|
|
470
|
+
# 11. Email verification
|
|
471
|
+
# 12. Update all protected routes
|
|
472
|
+
|
|
473
|
+
# Each task: RED → GREEN → REFACTOR → COMMIT
|
|
474
|
+
|
|
475
|
+
# Example for task 4 (signup):
|
|
476
|
+
|
|
477
|
+
# RED:
|
|
478
|
+
describe('POST /auth/signup', () => {
|
|
479
|
+
it('creates user with hashed password', async () => {
|
|
480
|
+
const response = await request(app)
|
|
481
|
+
.post('/auth/signup')
|
|
482
|
+
.send({ email: 'test@example.com', password: 'secure123' });
|
|
483
|
+
|
|
484
|
+
expect(response.status).toBe(201);
|
|
485
|
+
expect(response.body.token).toBeDefined();
|
|
486
|
+
|
|
487
|
+
const user = await db.findUserByEmail('test@example.com');
|
|
488
|
+
expect(user.password).not.toBe('secure123'); // hashed
|
|
489
|
+
});
|
|
490
|
+
});
|
|
491
|
+
# Run → ❌ Fails
|
|
492
|
+
|
|
493
|
+
# GREEN:
|
|
494
|
+
app.post('/auth/signup', async (req, res) => {
|
|
495
|
+
const { email, password } = req.body;
|
|
496
|
+
const hashedPassword = await bcrypt.hash(password, 10);
|
|
497
|
+
const user = await db.createUser(email, hashedPassword);
|
|
498
|
+
const token = jwt.sign({ userId: user.id }, SECRET, { expiresIn: '24h' });
|
|
499
|
+
res.status(201).json({ token });
|
|
500
|
+
});
|
|
501
|
+
# Run → ✅ Passes
|
|
502
|
+
|
|
503
|
+
# REFACTOR: Extract to AuthService, add validation
|
|
504
|
+
git commit -m "feat: add user signup endpoint
|
|
505
|
+
|
|
506
|
+
- Bcrypt password hashing
|
|
507
|
+
- JWT token generation
|
|
508
|
+
- Input validation
|
|
509
|
+
- Rate limiting
|
|
510
|
+
|
|
511
|
+
Task 4/12 in openspec/changes/user-authentication/tasks.md"
|
|
512
|
+
|
|
513
|
+
# Repeat for all 12 tasks
|
|
514
|
+
# ~1-2 days
|
|
515
|
+
|
|
516
|
+
# Update OpenSpec progress:
|
|
517
|
+
/opsx:apply
|
|
518
|
+
|
|
519
|
+
bd update PROJ-90 --status in_progress --comment "8/12 tasks complete"
|
|
520
|
+
|
|
521
|
+
# ═══════════════════════════════════════════════════════════
|
|
522
|
+
# STAGE 5: CHECK
|
|
523
|
+
# ═══════════════════════════════════════════════════════════
|
|
524
|
+
/check
|
|
525
|
+
|
|
526
|
+
# ✓ Type check passed
|
|
527
|
+
# ✓ Linter passed
|
|
528
|
+
# ✓ Tests passed (45 new tests)
|
|
529
|
+
# ✓ Security scan passed
|
|
530
|
+
# ✓ Migration runs successfully
|
|
531
|
+
|
|
532
|
+
# ═══════════════════════════════════════════════════════════
|
|
533
|
+
# STAGE 6: SHIP
|
|
534
|
+
# ═══════════════════════════════════════════════════════════
|
|
535
|
+
/ship
|
|
536
|
+
|
|
537
|
+
# PR #90 includes:
|
|
538
|
+
# - Link to OpenSpec proposal
|
|
539
|
+
# - All 12 tasks completed
|
|
540
|
+
# - 45 tests
|
|
541
|
+
# - Security scan results
|
|
542
|
+
# - Migration instructions
|
|
543
|
+
|
|
544
|
+
# ═══════════════════════════════════════════════════════════
|
|
545
|
+
# STAGE 7: REVIEW
|
|
546
|
+
# ═══════════════════════════════════════════════════════════
|
|
547
|
+
/review 90
|
|
548
|
+
|
|
549
|
+
# Address feedback from:
|
|
550
|
+
# - Security team
|
|
551
|
+
# - Architecture review
|
|
552
|
+
# - CI/CD failures
|
|
553
|
+
|
|
554
|
+
# ═══════════════════════════════════════════════════════════
|
|
555
|
+
# STAGE 8: MERGE
|
|
556
|
+
# ═══════════════════════════════════════════════════════════
|
|
557
|
+
/merge 90
|
|
558
|
+
|
|
559
|
+
# After merge:
|
|
560
|
+
/opsx:sync # Merge delta specs into main specs
|
|
561
|
+
/opsx:archive user-authentication
|
|
562
|
+
|
|
563
|
+
bd close PROJ-90
|
|
564
|
+
|
|
565
|
+
# ═══════════════════════════════════════════════════════════
|
|
566
|
+
# STAGE 9: VERIFY
|
|
567
|
+
# ═══════════════════════════════════════════════════════════
|
|
568
|
+
/verify
|
|
569
|
+
|
|
570
|
+
# Check:
|
|
571
|
+
# - API docs updated
|
|
572
|
+
# - README has auth examples
|
|
573
|
+
# - Migration in changelog
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
**Result**: Complete authentication system with proposal approval, TDD, and documentation in 2-3 days.
|
|
577
|
+
|
|
578
|
+
---
|
|
579
|
+
|
|
580
|
+
## Example 5: Team Collaboration
|
|
581
|
+
|
|
582
|
+
**Task**: Multiple developers working on same project with Beads
|
|
583
|
+
|
|
584
|
+
### Scenario
|
|
585
|
+
|
|
586
|
+
Team of 3 developers:
|
|
587
|
+
- **Alice**: Working on payment integration
|
|
588
|
+
- **Bob**: Working on email notifications
|
|
589
|
+
- **Charlie**: Working on admin dashboard
|
|
590
|
+
|
|
591
|
+
### Workflow
|
|
592
|
+
|
|
593
|
+
```bash
|
|
594
|
+
# ═══════════════════════════════════════════════════════════
|
|
595
|
+
# PROJECT SETUP (Once per project)
|
|
596
|
+
# ═══════════════════════════════════════════════════════════
|
|
597
|
+
bd init --prefix SHOP
|
|
598
|
+
bd sync # Commit .beads/ to git
|
|
599
|
+
|
|
600
|
+
# ═══════════════════════════════════════════════════════════
|
|
601
|
+
# ALICE: Payment Integration
|
|
602
|
+
# ═══════════════════════════════════════════════════════════
|
|
603
|
+
|
|
604
|
+
# Morning: Check what's available
|
|
605
|
+
bd ready
|
|
606
|
+
# Output:
|
|
607
|
+
# SHOP-1: Payment integration (ready)
|
|
608
|
+
# SHOP-3: Admin dashboard (ready)
|
|
609
|
+
|
|
610
|
+
# Claim work
|
|
611
|
+
bd update SHOP-1 --status in_progress
|
|
612
|
+
/status
|
|
613
|
+
/research stripe-payment-integration
|
|
614
|
+
/plan stripe-payment-integration
|
|
615
|
+
/dev
|
|
616
|
+
|
|
617
|
+
# Midday: Progress update
|
|
618
|
+
bd comments SHOP-1 "Stripe SDK integrated, working on webhooks"
|
|
619
|
+
|
|
620
|
+
# Afternoon: Blocked on API keys
|
|
621
|
+
bd update SHOP-1 --status blocked --comment "Need production Stripe API keys"
|
|
622
|
+
|
|
623
|
+
# Create dependency
|
|
624
|
+
bd create "Get Stripe API keys from DevOps" --type chore --priority 1
|
|
625
|
+
bd dep add SHOP-1 SHOP-5 # SHOP-1 depends on SHOP-5
|
|
626
|
+
|
|
627
|
+
bd sync # Push to git
|
|
628
|
+
|
|
629
|
+
# ═══════════════════════════════════════════════════════════
|
|
630
|
+
# BOB: Email Notifications (Same Time)
|
|
631
|
+
# ═══════════════════════════════════════════════════════════
|
|
632
|
+
|
|
633
|
+
# Morning: Pull latest, check work
|
|
634
|
+
git pull
|
|
635
|
+
bd sync # Sync with Alice's updates
|
|
636
|
+
|
|
637
|
+
bd ready
|
|
638
|
+
# Output:
|
|
639
|
+
# SHOP-3: Admin dashboard (ready)
|
|
640
|
+
# SHOP-2: Email notifications (ready)
|
|
641
|
+
|
|
642
|
+
# Claim different feature
|
|
643
|
+
bd update SHOP-2 --status in_progress
|
|
644
|
+
/research sendgrid-email-notifications
|
|
645
|
+
/plan email-notifications
|
|
646
|
+
/dev
|
|
647
|
+
|
|
648
|
+
# No conflicts with Alice (different files)
|
|
649
|
+
|
|
650
|
+
# End of day: Complete
|
|
651
|
+
bd close SHOP-2 --reason "Implemented with SendGrid"
|
|
652
|
+
/ship
|
|
653
|
+
bd sync
|
|
654
|
+
|
|
655
|
+
# ═══════════════════════════════════════════════════════════
|
|
656
|
+
# CHARLIE: Admin Dashboard (Next Day)
|
|
657
|
+
# ═══════════════════════════════════════════════════════════
|
|
658
|
+
|
|
659
|
+
# Morning: Check dependencies
|
|
660
|
+
git pull
|
|
661
|
+
bd sync
|
|
662
|
+
|
|
663
|
+
bd show SHOP-3
|
|
664
|
+
# Output:
|
|
665
|
+
# Status: ready
|
|
666
|
+
# Depends on: (none)
|
|
667
|
+
|
|
668
|
+
bd update SHOP-3 --status in_progress
|
|
669
|
+
|
|
670
|
+
# Discovers overlap with Bob's work
|
|
671
|
+
bd comments SHOP-3 "Need Bob's email service for user notifications"
|
|
672
|
+
bd dep add SHOP-3 SHOP-2 # SHOP-3 depends on SHOP-2
|
|
673
|
+
|
|
674
|
+
# Bob's work already merged, so can proceed
|
|
675
|
+
/research admin-dashboard
|
|
676
|
+
/plan admin-dashboard
|
|
677
|
+
/dev
|
|
678
|
+
|
|
679
|
+
# ═══════════════════════════════════════════════════════════
|
|
680
|
+
# COLLABORATION PATTERNS
|
|
681
|
+
# ═══════════════════════════════════════════════════════════
|
|
682
|
+
|
|
683
|
+
# Check what teammates are working on:
|
|
684
|
+
bd list --status in_progress
|
|
685
|
+
|
|
686
|
+
# Check blocked work:
|
|
687
|
+
bd blocked
|
|
688
|
+
# Output:
|
|
689
|
+
# SHOP-1: Payment integration (blocked by SHOP-5)
|
|
690
|
+
|
|
691
|
+
# Find work with no blockers:
|
|
692
|
+
bd ready
|
|
693
|
+
|
|
694
|
+
# See full project status:
|
|
695
|
+
bd stats
|
|
696
|
+
# Output:
|
|
697
|
+
# Total issues: 12
|
|
698
|
+
# Open: 8
|
|
699
|
+
# In Progress: 3 (Alice, Bob, Charlie)
|
|
700
|
+
# Blocked: 1 (SHOP-1)
|
|
701
|
+
# Done: 4
|
|
702
|
+
|
|
703
|
+
# Always sync at end of session:
|
|
704
|
+
bd sync
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
**Result**: Team can work in parallel, track dependencies, and avoid conflicts.
|
|
708
|
+
|
|
709
|
+
---
|
|
710
|
+
|
|
711
|
+
## Key Takeaways
|
|
712
|
+
|
|
713
|
+
### 1. Simple Features (15-30 min)
|
|
714
|
+
- Use `/research` even for small features
|
|
715
|
+
- TDD keeps scope focused
|
|
716
|
+
- No OpenSpec needed
|
|
717
|
+
|
|
718
|
+
### 2. Bug Fixes with Security (30-60 min)
|
|
719
|
+
- OWASP research in `/research` stage
|
|
720
|
+
- Security tests are mandatory
|
|
721
|
+
- Priority 0 for critical vulnerabilities
|
|
722
|
+
|
|
723
|
+
### 3. Multi-File Refactors (2-4 hours)
|
|
724
|
+
- TDD for each extracted method
|
|
725
|
+
- Commit after each GREEN cycle
|
|
726
|
+
- All existing tests must pass
|
|
727
|
+
|
|
728
|
+
### 4. Architecture Changes (2-5 days)
|
|
729
|
+
- Always use OpenSpec proposal
|
|
730
|
+
- Get approval BEFORE implementation
|
|
731
|
+
- Tasks.md breaks down work
|
|
732
|
+
- Frequent progress updates
|
|
733
|
+
|
|
734
|
+
### 5. Team Collaboration
|
|
735
|
+
- Beads tracks dependencies
|
|
736
|
+
- `bd ready` finds available work
|
|
737
|
+
- `bd sync` at end of every session
|
|
738
|
+
- Comments keep teammates informed
|
|
739
|
+
|
|
740
|
+
---
|
|
741
|
+
|
|
742
|
+
## Next Steps
|
|
743
|
+
|
|
744
|
+
📚 **New to Forge?** → [QUICKSTART.md](../QUICKSTART.md)
|
|
745
|
+
|
|
746
|
+
📖 **Learn workflow** → [WORKFLOW.md](WORKFLOW.md)
|
|
747
|
+
|
|
748
|
+
🛠️ **Setup tools** → [SETUP.md](SETUP.md)
|
|
749
|
+
|
|
750
|
+
💬 **Questions?** → [GitHub Discussions](https://github.com/harshanandak/forge/discussions)
|