sedd 0.1.1 → 0.1.3
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/commands/sedd.clarify.md +182 -64
- package/commands/sedd.implement.md +197 -25
- package/commands/sedd.specify.md +20 -15
- package/hooks/README.md +11 -8
- package/hooks/check-roadmap.js +71 -31
- package/package.json +3 -2
- package/templates/acceptance-template.md +64 -0
package/commands/sedd.clarify.md
CHANGED
|
@@ -40,11 +40,11 @@ User runs `/sedd.clarify`
|
|
|
40
40
|
- AI listens and records everything in clarify.md
|
|
41
41
|
- User controls the flow with inline commands:
|
|
42
42
|
|
|
43
|
-
|
|
|
44
|
-
|
|
45
|
-
| `continue` |
|
|
46
|
-
| `
|
|
47
|
-
| `tasks` |
|
|
43
|
+
| Comando | O que faz |
|
|
44
|
+
|---------|-----------|
|
|
45
|
+
| `continue` | Continuar explicando, AI anota |
|
|
46
|
+
| `pergunte` | AI faz próxima pergunta de clarificação |
|
|
47
|
+
| `tasks` | Gerar tasks.md e finalizar |
|
|
48
48
|
|
|
49
49
|
⚠️ **ALWAYS CREATES TASKS**
|
|
50
50
|
- Every clarify creates a NEW migration
|
|
@@ -53,26 +53,31 @@ User runs `/sedd.clarify`
|
|
|
53
53
|
|
|
54
54
|
## Workflow
|
|
55
55
|
|
|
56
|
-
### Step 1:
|
|
56
|
+
### Step 1: Capture Expected Outcome (FIRST - MANDATORY)
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
- spec.md
|
|
60
|
-
- interfaces.ts
|
|
61
|
-
- Previous migrations (if any)
|
|
62
|
-
|
|
63
|
-
### Step 2: Capture Expected Outcome (NEW)
|
|
58
|
+
**ANTES DE QUALQUER COISA**, pergunte ao usuário:
|
|
64
59
|
|
|
65
|
-
Before creating migration, ask user:
|
|
66
60
|
```
|
|
67
|
-
|
|
68
|
-
|
|
61
|
+
🎯 Qual é sua EXPECTATIVA para esta clarificação?
|
|
62
|
+
|
|
63
|
+
O que você espera ter funcionando ao final desta migration?
|
|
64
|
+
(Isso será usado para validar se as tasks cobrem seu objetivo)
|
|
69
65
|
```
|
|
70
66
|
|
|
71
|
-
Save in `clarify.md` under `## Expected Outcome` section.
|
|
67
|
+
Save in `clarify.md` under `## Expected Outcome` section (NO TOPO).
|
|
68
|
+
|
|
69
|
+
**NÃO PROSSIGA** sem a expectativa do usuário.
|
|
70
|
+
|
|
71
|
+
### Step 2: Load Context
|
|
72
|
+
|
|
73
|
+
Read from feature root:
|
|
74
|
+
- spec.md (especialmente a seção Expectation original)
|
|
75
|
+
- interfaces.ts
|
|
76
|
+
- Previous migrations (if any)
|
|
72
77
|
|
|
73
78
|
### Step 3: Create New Migration Folder
|
|
74
79
|
|
|
75
|
-
Generate new migration folder
|
|
80
|
+
Generate new migration folder:
|
|
76
81
|
|
|
77
82
|
```
|
|
78
83
|
Migration ID: 001 (or next: 002, 003...)
|
|
@@ -120,17 +125,14 @@ Present the clarification session with available commands:
|
|
|
120
125
|
Spec loaded: spec.md
|
|
121
126
|
Interfaces: interfaces.ts
|
|
122
127
|
|
|
123
|
-
Você pode
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
128
|
+
Você pode explicar livremente o que precisa.
|
|
129
|
+
Eu vou anotar tudo e fazer perguntas quando necessário.
|
|
130
|
+
|
|
131
|
+
Digite um comando para controlar o fluxo:
|
|
127
132
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
│ pergunta │ AI faz próxima pergunta (q, ?) │
|
|
132
|
-
│ tasks │ Gerar tasks e finalizar (done) │
|
|
133
|
-
└───────────┴────────────────────────────────────┘
|
|
133
|
+
continue → Continuar explicando
|
|
134
|
+
pergunte → AI faz próxima pergunta
|
|
135
|
+
tasks → Gerar tasks e finalizar
|
|
134
136
|
|
|
135
137
|
Como você quer começar?
|
|
136
138
|
```
|
|
@@ -184,13 +186,13 @@ System will support multiple tenants with isolated configurations.
|
|
|
184
186
|
```
|
|
185
187
|
✓ Anotado: Multi-tenant com configurações isoladas
|
|
186
188
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
189
|
+
Digite um comando:
|
|
190
|
+
continue → Continuar explicando
|
|
191
|
+
pergunte → AI faz próxima pergunta
|
|
192
|
+
tasks → Gerar tasks e finalizar
|
|
191
193
|
```
|
|
192
194
|
|
|
193
|
-
#### 5.2 User Says "continue"
|
|
195
|
+
#### 5.2 User Says "continue"
|
|
194
196
|
|
|
195
197
|
Keep in discussion mode:
|
|
196
198
|
|
|
@@ -198,7 +200,7 @@ Keep in discussion mode:
|
|
|
198
200
|
Ok, continue explicando...
|
|
199
201
|
```
|
|
200
202
|
|
|
201
|
-
#### 5.3 User Says "
|
|
203
|
+
#### 5.3 User Says "pergunte"
|
|
202
204
|
|
|
203
205
|
AI analyzes gaps and asks ONE clarification question:
|
|
204
206
|
|
|
@@ -223,7 +225,7 @@ Sua resposta (ou continue explicando):
|
|
|
223
225
|
|
|
224
226
|
After user answers, update clarify.md and decisions.md immediately.
|
|
225
227
|
|
|
226
|
-
#### 5.4 User Says "tasks"
|
|
228
|
+
#### 5.4 User Says "tasks"
|
|
227
229
|
|
|
228
230
|
Proceed to Step 6 (Generate Tasks).
|
|
229
231
|
|
|
@@ -255,47 +257,163 @@ T001-001, T001-002 → T001-003 → T001-004
|
|
|
255
257
|
→ T001-005
|
|
256
258
|
```
|
|
257
259
|
|
|
258
|
-
### Step
|
|
260
|
+
### Step 6.5: Generate Acceptance Criteria (NEW)
|
|
261
|
+
|
|
262
|
+
Após gerar tasks, criar critérios de aceite baseados na expectativa:
|
|
263
|
+
|
|
264
|
+
#### 6.5.1 Transformar Expectativa em Critérios
|
|
265
|
+
|
|
266
|
+
Regras de geração:
|
|
259
267
|
|
|
260
|
-
|
|
268
|
+
| Padrão na Expectativa | Critério Gerado |
|
|
269
|
+
|----------------------|-----------------|
|
|
270
|
+
| "can {verb}" | User can perform {verb} |
|
|
271
|
+
| "persist" ou "save" | Data survives refresh/session |
|
|
272
|
+
| "{noun} in {location}" | {noun} appears in {location} |
|
|
273
|
+
| "across {context}" | Works in multiple {context} |
|
|
274
|
+
| "immediately" | Response time < 100ms |
|
|
261
275
|
|
|
276
|
+
**Exemplo:**
|
|
277
|
+
|
|
278
|
+
Expectativa: "User can toggle dark mode in settings and persist across sessions"
|
|
279
|
+
|
|
280
|
+
Critérios gerados:
|
|
262
281
|
```markdown
|
|
263
|
-
|
|
282
|
+
- [ ] **AC-001:** User can toggle dark mode
|
|
283
|
+
- Verificar: Clicar no toggle, tema muda
|
|
264
284
|
|
|
265
|
-
**
|
|
266
|
-
|
|
285
|
+
- [ ] **AC-002:** Toggle está em settings
|
|
286
|
+
- Verificar: Navegar para settings, toggle visível
|
|
267
287
|
|
|
268
|
-
**
|
|
269
|
-
-
|
|
270
|
-
- Task T001-002: Updates database schema ✅
|
|
271
|
-
- Task T001-003: Creates toggle component ✅
|
|
272
|
-
- Task T001-004: Adds to settings page ✅
|
|
273
|
-
- Task T001-005: API endpoint ✅
|
|
288
|
+
- [ ] **AC-003:** Theme persists after refresh
|
|
289
|
+
- Verificar: Setar dark mode, refresh, tema permanece
|
|
274
290
|
|
|
275
|
-
**
|
|
291
|
+
- [ ] **AC-004:** Theme persists across sessions
|
|
292
|
+
- Verificar: Fechar browser, reabrir, tema permanece
|
|
276
293
|
```
|
|
277
294
|
|
|
278
|
-
####
|
|
295
|
+
#### 6.5.2 Criar acceptance.md
|
|
296
|
+
|
|
297
|
+
Escrever em `{migration_folder}/acceptance.md` usando template.
|
|
298
|
+
|
|
299
|
+
#### 6.5.3 Linkar em tasks.md
|
|
279
300
|
|
|
280
|
-
|
|
301
|
+
Adicionar ao final de tasks.md:
|
|
302
|
+
```markdown
|
|
303
|
+
---
|
|
281
304
|
|
|
305
|
+
## Acceptance Criteria
|
|
306
|
+
|
|
307
|
+
Ver `acceptance.md` para checklist de verificação.
|
|
282
308
|
```
|
|
283
|
-
⚠️ Tasks geradas não cobrem completamente sua expectativa.
|
|
284
309
|
|
|
285
|
-
|
|
286
|
-
|
|
310
|
+
### Step 7: Expectation Alignment Check + Score
|
|
311
|
+
|
|
312
|
+
Após gerar tasks E acceptance criteria, calcular score de alinhamento:
|
|
287
313
|
|
|
288
|
-
|
|
314
|
+
#### 7.1 Extrair Keywords da Expectativa
|
|
315
|
+
|
|
316
|
+
```
|
|
317
|
+
PASSO 1: Tokenizar expectativa
|
|
318
|
+
- Dividir em palavras
|
|
319
|
+
- Remover stop words (the, a, an, is, are, can, will, to, for, in, on, and, or, user, etc.)
|
|
320
|
+
- Extrair termos significativos
|
|
321
|
+
|
|
322
|
+
PASSO 2: Pesar tokens
|
|
323
|
+
- Verbos (ações): peso 3
|
|
324
|
+
- Substantivos (entidades): peso 2
|
|
325
|
+
- Modificadores: peso 1
|
|
326
|
+
|
|
327
|
+
Exemplo: "User can toggle dark mode in settings and persist across sessions"
|
|
328
|
+
Tokens: {toggle: 3, dark: 1, mode: 2, settings: 2, persist: 3, sessions: 1}
|
|
329
|
+
Total: 12
|
|
289
330
|
```
|
|
290
331
|
|
|
291
|
-
|
|
332
|
+
#### 7.2 Verificar Cobertura nas Tasks
|
|
333
|
+
|
|
334
|
+
Para cada token, buscar nas descrições das tasks geradas.
|
|
335
|
+
|
|
336
|
+
#### 7.3 Calcular Score
|
|
337
|
+
|
|
292
338
|
```
|
|
293
|
-
|
|
339
|
+
matched_weight = soma dos pesos dos tokens encontrados
|
|
340
|
+
score = (matched_weight / total_weight) * 100
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
#### 7.4 Exibir Resultado
|
|
344
|
+
|
|
345
|
+
**Se coverage >= 80%:**
|
|
346
|
+
```
|
|
347
|
+
📊 Coverage: ~{score}% 🟢
|
|
348
|
+
|
|
349
|
+
**Sua expectativa:**
|
|
350
|
+
> {expectation}
|
|
351
|
+
|
|
352
|
+
**Tokens encontrados nas tasks:**
|
|
353
|
+
✅ toggle (T001-003) - peso 3
|
|
354
|
+
✅ dark mode (T001-003, T001-004) - peso 3
|
|
355
|
+
✅ settings (T001-004) - peso 2
|
|
356
|
+
✅ persist (T001-003) - peso 3
|
|
357
|
+
❌ sessions - peso 1
|
|
358
|
+
|
|
359
|
+
Score: 11/12 = 92%
|
|
360
|
+
|
|
361
|
+
✅ Boa cobertura! Tasks prontas.
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
**Se coverage 60-79%:**
|
|
365
|
+
```
|
|
366
|
+
📊 Coverage: ~{score}% 🟡
|
|
367
|
+
|
|
368
|
+
**Sua expectativa:**
|
|
369
|
+
> {expectation}
|
|
370
|
+
|
|
371
|
+
**Cobertos:**
|
|
372
|
+
✅ toggle (T001-003)
|
|
373
|
+
✅ dark mode (T001-003)
|
|
374
|
+
|
|
375
|
+
**Faltando:**
|
|
376
|
+
❌ persist - nenhuma task menciona
|
|
377
|
+
❌ sessions - não encontrado
|
|
378
|
+
|
|
379
|
+
⚠️ Cobertura parcial. Deseja adicionar tasks para cobrir os gaps? [Y/n]
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
**Se coverage < 60%:**
|
|
383
|
+
```
|
|
384
|
+
📊 Coverage: ~{score}% 🔴
|
|
385
|
+
|
|
386
|
+
**Sua expectativa:**
|
|
387
|
+
> {expectation}
|
|
388
|
+
|
|
389
|
+
**Cobertos:**
|
|
390
|
+
✅ toggle (T001-003)
|
|
391
|
+
|
|
392
|
+
**Faltando:**
|
|
393
|
+
❌ dark mode
|
|
394
|
+
❌ settings
|
|
395
|
+
❌ persist
|
|
396
|
+
❌ sessions
|
|
397
|
+
|
|
398
|
+
⚠️ Cobertura baixa! Recomendo adicionar mais tasks.
|
|
399
|
+
|
|
400
|
+
**Opções:**
|
|
401
|
+
1. Adicionar tasks para conceitos faltando
|
|
402
|
+
2. Prosseguir assim mesmo
|
|
403
|
+
3. Refinar expectativa
|
|
404
|
+
|
|
405
|
+
O que deseja fazer?
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
#### 7.5 Se Usuário Escolhe Adicionar Tasks
|
|
409
|
+
|
|
410
|
+
Voltar ao modo discussão:
|
|
411
|
+
```
|
|
412
|
+
Vamos adicionar tasks para os conceitos faltando.
|
|
413
|
+
|
|
414
|
+
Faltando: "persist", "sessions"
|
|
294
415
|
|
|
295
|
-
|
|
296
|
-
• continue - explicar mais detalhes
|
|
297
|
-
• pergunta - AI faz pergunta de refinamento
|
|
298
|
-
• tasks - tentar gerar tasks novamente
|
|
416
|
+
Como você imagina a persistência funcionando?
|
|
299
417
|
```
|
|
300
418
|
|
|
301
419
|
### Step 8: Update _meta.json
|
|
@@ -378,10 +496,10 @@ Parent references allow tracking the evolution:
|
|
|
378
496
|
- **FLEXIBLE DISCUSSION** - User controls the flow with inline commands
|
|
379
497
|
- **UPDATE FILES IMMEDIATELY** - After each user input
|
|
380
498
|
- **RECOGNIZE INLINE COMMANDS:**
|
|
381
|
-
- `continue
|
|
382
|
-
- `
|
|
383
|
-
- `tasks
|
|
384
|
-
- ALWAYS generate tasks.md when user says "tasks
|
|
499
|
+
- `continue` → Continuar explicando
|
|
500
|
+
- `pergunte` → AI faz próxima pergunta
|
|
501
|
+
- `tasks` → Gerar tasks e finalizar
|
|
502
|
+
- ALWAYS generate tasks.md when user says "tasks"
|
|
385
503
|
- Task IDs include migration ID (T001-XXX)
|
|
386
504
|
- Each clarify = new migration folder
|
|
387
505
|
- Auto-split files > 400 lines
|
|
@@ -401,12 +519,12 @@ Parent references allow tracking the evolution:
|
|
|
401
519
|
│ User explains → AI records in clarify.md + decisions.md │
|
|
402
520
|
│ ↓ │
|
|
403
521
|
│ "continue" → AI: "Ok, continue..." │
|
|
404
|
-
│ "
|
|
522
|
+
│ "pergunte" → AI asks ONE question │
|
|
405
523
|
│ "tasks" → Exit loop, generate tasks │
|
|
406
524
|
└─────────────────────────────────────────────────────────────┘
|
|
407
525
|
↓
|
|
408
526
|
┌─────────────────────────────────────────────────────────────┐
|
|
409
|
-
│ User says "tasks"
|
|
527
|
+
│ User says "tasks" │
|
|
410
528
|
│ → AI generates tasks.md from all notes + decisions │
|
|
411
529
|
│ → AI updates _meta.json │
|
|
412
530
|
│ → AI asks about commit │
|
|
@@ -98,14 +98,20 @@ For each task in order:
|
|
|
98
98
|
| T001-001 | 001 | in-progress | 10:30 | - |
|
|
99
99
|
```
|
|
100
100
|
|
|
101
|
-
2. **Show task context**
|
|
101
|
+
2. **Show task context with expectations**
|
|
102
102
|
```
|
|
103
103
|
📌 Task T001-001 [Foundation]
|
|
104
104
|
Create ThemeContext in src/contexts/ThemeContext.tsx
|
|
105
105
|
|
|
106
106
|
From Decision D001-001: Theme persisted in user account
|
|
107
|
+
|
|
108
|
+
━━━ Expectations ━━━
|
|
109
|
+
🎯 Feature: User can customize theme preferences
|
|
110
|
+
📍 Migration 001: Toggle dark mode with persistence
|
|
107
111
|
```
|
|
108
112
|
|
|
113
|
+
**Nota:** Se feature expectation e migration expectation forem iguais, mostrar apenas uma.
|
|
114
|
+
|
|
109
115
|
3. **Execute the task**
|
|
110
116
|
|
|
111
117
|
4. **Update ALL task files** (CRITICAL - keep them in sync):
|
|
@@ -131,6 +137,80 @@ For each task in order:
|
|
|
131
137
|
|
|
132
138
|
5. **Verify sync** - All three files must show same completed count
|
|
133
139
|
|
|
140
|
+
### Step 5.5: Expectation Checkpoint (NEW)
|
|
141
|
+
|
|
142
|
+
A cada 3 tasks completadas, pausar e verificar alinhamento com expectativa.
|
|
143
|
+
|
|
144
|
+
#### 5.5.1 Trigger
|
|
145
|
+
|
|
146
|
+
Checkpoint dispara quando:
|
|
147
|
+
- `completed_in_session % 3 == 0` (a cada 3 tasks)
|
|
148
|
+
- AND `remaining_tasks > 0` (não está no final)
|
|
149
|
+
- AND NÃO está usando `--all` flag
|
|
150
|
+
|
|
151
|
+
#### 5.5.2 Prompt do Checkpoint
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
⏸️ Checkpoint - {completed}/{total} tasks completas
|
|
155
|
+
|
|
156
|
+
**Sua expectativa:**
|
|
157
|
+
> {expectation_from_meta}
|
|
158
|
+
|
|
159
|
+
**Completadas até agora:**
|
|
160
|
+
- [x] T001-001: Created ThemeContext
|
|
161
|
+
- [x] T001-002: Updated database schema
|
|
162
|
+
- [x] T001-003: Created toggle component
|
|
163
|
+
|
|
164
|
+
**Restantes:**
|
|
165
|
+
- [ ] T001-004: Add to settings page
|
|
166
|
+
- [ ] T001-005: API endpoint
|
|
167
|
+
|
|
168
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
169
|
+
Isso ainda está alinhado com sua expectativa? [Y/n/ajustar]
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
#### 5.5.3 Respostas do Usuário
|
|
173
|
+
|
|
174
|
+
**Se "Y" ou Enter (default):**
|
|
175
|
+
```
|
|
176
|
+
✓ Continuando implementação...
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**Se "n":**
|
|
180
|
+
```
|
|
181
|
+
⏹️ Implementação pausada.
|
|
182
|
+
|
|
183
|
+
**Opções:**
|
|
184
|
+
1. /sedd.clarify - Criar nova migration para ajustes
|
|
185
|
+
2. Continuar mesmo assim
|
|
186
|
+
3. Marcar tasks restantes como blocked
|
|
187
|
+
|
|
188
|
+
O que deseja fazer?
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
**Se "ajustar":**
|
|
192
|
+
```
|
|
193
|
+
O que mudou na sua expectativa?
|
|
194
|
+
(Isso será registrado mas não altera as tasks existentes)
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Registrar em `progress.md`:
|
|
198
|
+
```markdown
|
|
199
|
+
## Expectation Notes
|
|
200
|
+
|
|
201
|
+
### Checkpoint em T001-003 (2026-01-11 14:30)
|
|
202
|
+
**Original:** User can toggle dark mode in settings
|
|
203
|
+
**Nota do usuário:** Também quero detecção de preferência do sistema
|
|
204
|
+
**Ação:** Continuar com tasks atuais, criar migration 002 depois
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
#### 5.5.4 Configuração
|
|
208
|
+
|
|
209
|
+
Intervalo pode ser ajustado:
|
|
210
|
+
- Default: A cada 3 tasks
|
|
211
|
+
- Override: `/sedd.implement --checkpoint=5` (a cada 5)
|
|
212
|
+
- Desabilitar: `/sedd.implement --no-checkpoint`
|
|
213
|
+
|
|
134
214
|
### Step 6: Migration Boundaries
|
|
135
215
|
|
|
136
216
|
When completing a migration's tasks:
|
|
@@ -146,47 +226,139 @@ All 5 tasks finished:
|
|
|
146
226
|
- T001-005 ✓
|
|
147
227
|
```
|
|
148
228
|
|
|
149
|
-
### Step 7:
|
|
229
|
+
### Step 7: Final Validation with Acceptance Criteria (ENHANCED)
|
|
150
230
|
|
|
151
|
-
|
|
231
|
+
Quando todas as tasks de uma migration forem completadas, validar usando acceptance criteria.
|
|
152
232
|
|
|
233
|
+
#### 7.1 Carregar Acceptance Criteria
|
|
234
|
+
|
|
235
|
+
Se `{migration}/acceptance.md` existe, carregar os critérios.
|
|
236
|
+
|
|
237
|
+
#### 7.2 Prompt de Verificação
|
|
238
|
+
|
|
239
|
+
```
|
|
240
|
+
🏁 Migration 001 Completa!
|
|
241
|
+
|
|
242
|
+
**Todas {N} tasks finalizadas.**
|
|
243
|
+
|
|
244
|
+
**Sua expectativa era:**
|
|
245
|
+
> {expectation}
|
|
246
|
+
|
|
247
|
+
**Acceptance Criteria:**
|
|
248
|
+
- [ ] AC-001: User can access dark mode toggle
|
|
249
|
+
- [ ] AC-002: Toggle changes theme immediately
|
|
250
|
+
- [ ] AC-003: Theme persists after refresh
|
|
251
|
+
- [ ] AC-004: Theme persists across sessions
|
|
252
|
+
|
|
253
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
254
|
+
|
|
255
|
+
Por favor verifique cada critério. Quais foram atendidos?
|
|
256
|
+
(Digite: all, none, ou IDs específicos como "1,2,4")
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
#### 7.3 Processar Resposta
|
|
260
|
+
|
|
261
|
+
**Se "all":**
|
|
262
|
+
```
|
|
263
|
+
✅ Todos os critérios atendidos!
|
|
264
|
+
|
|
265
|
+
Atualizando acceptance.md...
|
|
266
|
+
Migration 001 marcada como completa com sucesso total.
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
Atualizar `acceptance.md`:
|
|
153
270
|
```markdown
|
|
154
|
-
##
|
|
271
|
+
## Sign-off
|
|
272
|
+
|
|
273
|
+
| Critério | Status | Verificado Por | Data |
|
|
274
|
+
|----------|--------|----------------|------|
|
|
275
|
+
| AC-001 | passed | user | 2026-01-11 |
|
|
276
|
+
| AC-002 | passed | user | 2026-01-11 |
|
|
277
|
+
| AC-003 | passed | user | 2026-01-11 |
|
|
278
|
+
| AC-004 | passed | user | 2026-01-11 |
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
**Se parcial (ex: "1,2"):**
|
|
282
|
+
```
|
|
283
|
+
⚠️ Alguns critérios não atendidos
|
|
284
|
+
|
|
285
|
+
**Atendidos:**
|
|
286
|
+
- [x] AC-001: User can access dark mode toggle
|
|
287
|
+
- [x] AC-002: Toggle changes theme immediately
|
|
155
288
|
|
|
156
|
-
**
|
|
157
|
-
|
|
289
|
+
**Não Atendidos:**
|
|
290
|
+
- [ ] AC-003: Theme persists after refresh
|
|
291
|
+
- [ ] AC-004: Theme persists across sessions
|
|
158
292
|
|
|
159
|
-
**
|
|
160
|
-
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
- Created toggle component in settings
|
|
164
|
-
- API endpoint for saving preference
|
|
293
|
+
**Opções:**
|
|
294
|
+
1. Criar migration de follow-up para critérios faltando
|
|
295
|
+
2. Marcar como completo com notas (entrega parcial)
|
|
296
|
+
3. Manter migration aberta para debug
|
|
165
297
|
|
|
166
|
-
|
|
298
|
+
O que deseja fazer?
|
|
167
299
|
```
|
|
168
300
|
|
|
169
|
-
####
|
|
301
|
+
#### 7.4 Follow-up Migration
|
|
170
302
|
|
|
171
|
-
|
|
303
|
+
Se usuário escolhe opção 1:
|
|
304
|
+
```
|
|
305
|
+
Criando migration de follow-up...
|
|
306
|
+
|
|
307
|
+
Expectativa sugerida para nova migration:
|
|
308
|
+
> "Theme should persist after page refresh and across browser sessions"
|
|
309
|
+
|
|
310
|
+
Deseja rodar /sedd.clarify agora? [Y/n]
|
|
311
|
+
```
|
|
172
312
|
|
|
313
|
+
#### 7.5 Atualizar _meta.json
|
|
314
|
+
|
|
315
|
+
Registrar resultado da validação:
|
|
316
|
+
```json
|
|
317
|
+
{
|
|
318
|
+
"migrations": {
|
|
319
|
+
"001": {
|
|
320
|
+
"status": "completed",
|
|
321
|
+
"expectationMet": "partial",
|
|
322
|
+
"criteriaResults": {
|
|
323
|
+
"passed": ["AC-001", "AC-002"],
|
|
324
|
+
"failed": ["AC-003", "AC-004"],
|
|
325
|
+
"deferredTo": "002"
|
|
326
|
+
},
|
|
327
|
+
"completedAt": "2026-01-11T15:30:00Z"
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
173
331
|
```
|
|
174
|
-
⚠️ Expectation may not be fully met
|
|
175
332
|
|
|
176
|
-
|
|
177
|
-
> User can toggle dark mode in settings and have it persist across sessions
|
|
333
|
+
#### 7.6 Atualizar acceptance.md
|
|
178
334
|
|
|
179
|
-
|
|
180
|
-
-
|
|
335
|
+
```markdown
|
|
336
|
+
## Sign-off
|
|
337
|
+
|
|
338
|
+
| Critério | Status | Verificado Por | Data |
|
|
339
|
+
|----------|--------|----------------|------|
|
|
340
|
+
| AC-001 | passed | user | 2026-01-11 |
|
|
341
|
+
| AC-002 | passed | user | 2026-01-11 |
|
|
342
|
+
| AC-003 | deferred | - | - |
|
|
343
|
+
| AC-004 | deferred | - | - |
|
|
344
|
+
|
|
345
|
+
## Notas
|
|
346
|
+
AC-003, AC-004 diferidos para migration 002.
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
#### 7.7 Se Não Existir acceptance.md
|
|
350
|
+
|
|
351
|
+
Fazer verificação simplificada:
|
|
352
|
+
```
|
|
353
|
+
🏁 Migration 001 Completa!
|
|
181
354
|
|
|
182
|
-
**
|
|
183
|
-
|
|
184
|
-
2. Mark as complete anyway (partial delivery)
|
|
355
|
+
**Sua expectativa era:**
|
|
356
|
+
> {expectation}
|
|
185
357
|
|
|
186
|
-
|
|
358
|
+
Sua expectativa foi atendida? [Y/n/parcial]
|
|
187
359
|
```
|
|
188
360
|
|
|
189
|
-
|
|
361
|
+
Se "parcial", perguntar o que faltou e sugerir nova migration.
|
|
190
362
|
|
|
191
363
|
### Step 8: Ask About Commit
|
|
192
364
|
|
package/commands/sedd.specify.md
CHANGED
|
@@ -40,7 +40,24 @@ Default `sedd.config.json`:
|
|
|
40
40
|
|
|
41
41
|
Extract feature description from user input or ask interactively.
|
|
42
42
|
|
|
43
|
-
### Step 2:
|
|
43
|
+
### Step 2: Capture Expectation (FIRST - MANDATORY)
|
|
44
|
+
|
|
45
|
+
**ANTES DE QUALQUER COISA**, pergunte ao usuário:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
🎯 Qual é sua EXPECTATIVA para esta feature?
|
|
49
|
+
|
|
50
|
+
O que você espera ver funcionando quando estiver pronto?
|
|
51
|
+
(Isso será usado para validar se as tasks cobrem seu objetivo)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Save expectation in:
|
|
55
|
+
- `spec.md` under `## Expectation` section (NO TOPO)
|
|
56
|
+
- `_meta.json` in `expectation` field
|
|
57
|
+
|
|
58
|
+
**NÃO PROSSIGA** sem a expectativa do usuário.
|
|
59
|
+
|
|
60
|
+
### Step 3: Architecture Analysis (MANDATORY)
|
|
44
61
|
|
|
45
62
|
Before creating spec, MUST search for related implementations:
|
|
46
63
|
|
|
@@ -53,25 +70,13 @@ Find similar:
|
|
|
53
70
|
|
|
54
71
|
Document findings in spec.md.
|
|
55
72
|
|
|
56
|
-
### Step 3: Capture Expectation (NEW)
|
|
57
|
-
|
|
58
|
-
Ask user for their expectation:
|
|
59
|
-
```
|
|
60
|
-
What do you expect as the final outcome of this feature?
|
|
61
|
-
(This will be used to verify alignment when implementation is complete)
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
Save expectation in:
|
|
65
|
-
- `spec.md` under `## Expectation` section
|
|
66
|
-
- `_meta.json` in `expectation` field
|
|
67
|
-
|
|
68
73
|
### Step 4: Create Feature Structure
|
|
69
74
|
|
|
70
75
|
```
|
|
71
76
|
{{specsDir}}/{{FEATURE_ID}}-{{SHORT_NAME}}/
|
|
72
77
|
├── _meta.json # Metadata (with expectation)
|
|
73
78
|
├── CHANGELOG.md # Changelog
|
|
74
|
-
├── spec.md # Base specification (with Expectation section)
|
|
79
|
+
├── spec.md # Base specification (with Expectation section NO TOPO)
|
|
75
80
|
├── interfaces.ts # TypeScript interfaces
|
|
76
81
|
└── ui-mockups/ # If UI feature
|
|
77
82
|
└── component-name.md
|
|
@@ -80,10 +85,10 @@ Save expectation in:
|
|
|
80
85
|
### Step 5: Generate spec.md
|
|
81
86
|
|
|
82
87
|
Use template with:
|
|
88
|
+
- **Expectation section NO TOPO** (capturada no Step 2)
|
|
83
89
|
- Feature name, ID, timestamp
|
|
84
90
|
- User stories based on description
|
|
85
91
|
- Mark requirements as NEEDS_CLARIFICATION where unclear
|
|
86
|
-
- Include Expectation section
|
|
87
92
|
|
|
88
93
|
### Step 6: Generate interfaces.ts (MANDATORY)
|
|
89
94
|
|
package/hooks/README.md
CHANGED
|
@@ -62,19 +62,22 @@ The hook detects keywords and **FORCES** skills into context:
|
|
|
62
62
|
### Output Example
|
|
63
63
|
|
|
64
64
|
```xml
|
|
65
|
-
<forced-skills>
|
|
66
|
-
[SKILL ACTIVATED: langchain-expert]
|
|
67
|
-
You MUST use the langchain-expert skill for this request.
|
|
68
|
-
Follow LangGraph 1.0+ patterns, check Context7 MCP for latest docs.
|
|
69
|
-
</forced-skills>
|
|
70
|
-
|
|
71
65
|
<sedd-context>
|
|
72
|
-
**Branch: 023-agent-executor** | Migration: 004 | Progress:
|
|
66
|
+
**Branch: 023-agent-executor** | Migration: 004 | Progress: 5/10 tasks
|
|
67
|
+
|
|
68
|
+
🎯 **EXPECTATIVA:** User can toggle dark mode and have it persist across sessions
|
|
73
69
|
|
|
74
|
-
|
|
70
|
+
Pending tasks:
|
|
71
|
+
- T004-001: Create ThemeContext
|
|
72
|
+
- T004-002: Add toggle component
|
|
73
|
+
... and 3 more
|
|
75
74
|
</sedd-context>
|
|
76
75
|
```
|
|
77
76
|
|
|
77
|
+
### Expectation Reminder
|
|
78
|
+
|
|
79
|
+
O hook **sempre mostra a EXPECTATIVA** do `_meta.json` para lembrar a AI do objetivo final. Isso garante que todas as ações estejam alinhadas com o que o usuário espera.
|
|
80
|
+
|
|
78
81
|
---
|
|
79
82
|
|
|
80
83
|
## post-tool-use.js
|
package/hooks/check-roadmap.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
3
|
* SEDD Hook - UserPromptSubmit
|
|
4
|
-
*
|
|
4
|
+
* Task count display and expectation tracking for feature branches
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
const fs = require('fs');
|
|
@@ -24,7 +24,13 @@ const IGNORE_PATTERNS = [
|
|
|
24
24
|
/^prossiga\s*$/i,
|
|
25
25
|
];
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
const STOP_WORDS = new Set([
|
|
28
|
+
'the', 'a', 'an', 'is', 'are', 'can', 'will', 'should', 'must',
|
|
29
|
+
'to', 'for', 'in', 'on', 'at', 'by', 'with', 'and', 'or', 'but',
|
|
30
|
+
'user', 'users', 'system', 'be', 'have', 'has', 'it', 'its', 'of',
|
|
31
|
+
'that', 'this', 'from', 'as', 'when', 'if', 'then', 'so', 'do',
|
|
32
|
+
]);
|
|
33
|
+
|
|
28
34
|
const loadConfig = (cwd) => {
|
|
29
35
|
const configPath = path.join(cwd, 'sedd.config.json');
|
|
30
36
|
if (!fs.existsSync(configPath)) return DEFAULT_CONFIG;
|
|
@@ -37,7 +43,6 @@ const loadConfig = (cwd) => {
|
|
|
37
43
|
}
|
|
38
44
|
};
|
|
39
45
|
|
|
40
|
-
/** @param {string} cwd */
|
|
41
46
|
const getCurrentBranch = (cwd) => {
|
|
42
47
|
try {
|
|
43
48
|
return execSync('git rev-parse --abbrev-ref HEAD', { cwd, encoding: 'utf8' }).trim();
|
|
@@ -46,16 +51,10 @@ const getCurrentBranch = (cwd) => {
|
|
|
46
51
|
}
|
|
47
52
|
};
|
|
48
53
|
|
|
49
|
-
/** @param {string} branch */
|
|
50
54
|
const isFeatureBranch = (branch) => /^\d{3}-/.test(branch);
|
|
51
55
|
|
|
52
|
-
/** @param {string} prompt */
|
|
53
56
|
const shouldIgnorePrompt = (prompt) => IGNORE_PATTERNS.some((p) => p.test(prompt));
|
|
54
57
|
|
|
55
|
-
/**
|
|
56
|
-
* @param {string} content
|
|
57
|
-
* @param {string|null} migrationId
|
|
58
|
-
*/
|
|
59
58
|
const parseTasksFromContent = (content, migrationId) => {
|
|
60
59
|
const pending = [];
|
|
61
60
|
let completed = 0;
|
|
@@ -79,10 +78,6 @@ const parseTasksFromContent = (content, migrationId) => {
|
|
|
79
78
|
return { pending, completed };
|
|
80
79
|
};
|
|
81
80
|
|
|
82
|
-
/**
|
|
83
|
-
* @param {string} featureDir
|
|
84
|
-
* @param {object} metaData
|
|
85
|
-
*/
|
|
86
81
|
const parseTasksFromMigrations = (featureDir, metaData) => {
|
|
87
82
|
const currentMigration = metaData.currentMigration;
|
|
88
83
|
|
|
@@ -128,7 +123,6 @@ const parseTasksFromMigrations = (featureDir, metaData) => {
|
|
|
128
123
|
return { pending: allPending, completed: totalCompleted };
|
|
129
124
|
};
|
|
130
125
|
|
|
131
|
-
/** @param {string} featureDir */
|
|
132
126
|
const parseTasksFromLegacy = (featureDir) => {
|
|
133
127
|
const tasksFile = path.join(featureDir, 'tasks.md');
|
|
134
128
|
if (!fs.existsSync(tasksFile)) return { pending: [], completed: 0 };
|
|
@@ -137,11 +131,6 @@ const parseTasksFromLegacy = (featureDir) => {
|
|
|
137
131
|
return parseTasksFromContent(content, null);
|
|
138
132
|
};
|
|
139
133
|
|
|
140
|
-
/**
|
|
141
|
-
* @param {string} cwd
|
|
142
|
-
* @param {string} specsDir
|
|
143
|
-
* @param {string} branch
|
|
144
|
-
*/
|
|
145
134
|
const findFeatureDir = (cwd, specsDir, branch) => {
|
|
146
135
|
const primaryDir = path.join(cwd, specsDir, branch);
|
|
147
136
|
if (fs.existsSync(primaryDir)) return primaryDir;
|
|
@@ -152,18 +141,61 @@ const findFeatureDir = (cwd, specsDir, branch) => {
|
|
|
152
141
|
return null;
|
|
153
142
|
};
|
|
154
143
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
144
|
+
const calculateAlignmentScore = (expectation, tasks) => {
|
|
145
|
+
if (!expectation || tasks.length === 0) return 0;
|
|
146
|
+
|
|
147
|
+
const tokens = expectation
|
|
148
|
+
.toLowerCase()
|
|
149
|
+
.replace(/[^\w\s]/g, '')
|
|
150
|
+
.split(/\s+/)
|
|
151
|
+
.filter((t) => t.length > 2 && !STOP_WORDS.has(t));
|
|
152
|
+
|
|
153
|
+
if (tokens.length === 0) return 100;
|
|
154
|
+
|
|
155
|
+
const taskText = tasks.map((t) => t.text.toLowerCase()).join(' ');
|
|
156
|
+
const matches = tokens.filter((token) => taskText.includes(token));
|
|
157
|
+
|
|
158
|
+
return Math.round((matches.length / tokens.length) * 100);
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
const getScoreEmoji = (score) => {
|
|
162
|
+
if (score >= 80) return '🟢';
|
|
163
|
+
if (score >= 60) return '🟡';
|
|
164
|
+
return '🔴';
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
const buildSeddContext = (branch, currentMigration, completed, pending, featureExpectation, migrationExpectation) => {
|
|
168
|
+
if (pending.length === 0 && !featureExpectation && !migrationExpectation) return null;
|
|
163
169
|
|
|
164
170
|
const total = completed + pending.length;
|
|
165
171
|
const migrationInfo = currentMigration ? ` | Migration: ${currentMigration}` : '';
|
|
166
172
|
|
|
173
|
+
let expectationBlock = '';
|
|
174
|
+
const activeExpectation = migrationExpectation || featureExpectation;
|
|
175
|
+
|
|
176
|
+
if (featureExpectation && migrationExpectation && featureExpectation !== migrationExpectation) {
|
|
177
|
+
expectationBlock = `
|
|
178
|
+
🎯 **FEATURE:** ${featureExpectation}
|
|
179
|
+
📍 **MIGRATION ${currentMigration}:** ${migrationExpectation}
|
|
180
|
+
`;
|
|
181
|
+
} else if (activeExpectation) {
|
|
182
|
+
const prefix = migrationExpectation ? `📍 M${currentMigration}` : '🎯';
|
|
183
|
+
expectationBlock = `\n${prefix} **EXPECTATIVA:** ${activeExpectation}\n`;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
let scoreBlock = '';
|
|
187
|
+
if (activeExpectation && pending.length > 0) {
|
|
188
|
+
const score = calculateAlignmentScore(activeExpectation, pending);
|
|
189
|
+
const emoji = getScoreEmoji(score);
|
|
190
|
+
scoreBlock = ` ${emoji} ~${score}%`;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (pending.length === 0) {
|
|
194
|
+
return `<sedd-context>
|
|
195
|
+
**Branch: ${branch}**${migrationInfo}${expectationBlock}
|
|
196
|
+
</sedd-context>`;
|
|
197
|
+
}
|
|
198
|
+
|
|
167
199
|
const tasksList = pending.slice(0, 5).map((t) => {
|
|
168
200
|
const truncated = t.text.length > 60 ? `${t.text.substring(0, 60)}...` : t.text;
|
|
169
201
|
return `- ${t.id}: ${truncated}`;
|
|
@@ -172,8 +204,8 @@ const buildSeddContext = (branch, currentMigration, completed, pending) => {
|
|
|
172
204
|
const moreText = pending.length > 5 ? `\n... and ${pending.length - 5} more` : '';
|
|
173
205
|
|
|
174
206
|
return `<sedd-context>
|
|
175
|
-
**Branch: ${branch}**${migrationInfo} | Progress: ${completed}/${total} tasks
|
|
176
|
-
|
|
207
|
+
**Branch: ${branch}**${migrationInfo} | Progress: ${completed}/${total} tasks${scoreBlock}
|
|
208
|
+
${expectationBlock}
|
|
177
209
|
Pending tasks:
|
|
178
210
|
${tasksList}${moreText}
|
|
179
211
|
</sedd-context>`;
|
|
@@ -205,10 +237,18 @@ const main = () => {
|
|
|
205
237
|
let pending = [];
|
|
206
238
|
let completed = 0;
|
|
207
239
|
let currentMigration = null;
|
|
240
|
+
let featureExpectation = null;
|
|
241
|
+
let migrationExpectation = null;
|
|
208
242
|
|
|
209
243
|
if (fs.existsSync(metaFile)) {
|
|
210
244
|
const metaData = JSON.parse(fs.readFileSync(metaFile, 'utf8'));
|
|
211
245
|
currentMigration = metaData.currentMigration;
|
|
246
|
+
featureExpectation = metaData.expectation || null;
|
|
247
|
+
|
|
248
|
+
if (currentMigration && metaData.migrations?.[currentMigration]?.expectation) {
|
|
249
|
+
migrationExpectation = metaData.migrations[currentMigration].expectation;
|
|
250
|
+
}
|
|
251
|
+
|
|
212
252
|
const result = parseTasksFromMigrations(featureDir, metaData);
|
|
213
253
|
pending = result.pending;
|
|
214
254
|
completed = result.completed;
|
|
@@ -218,12 +258,12 @@ const main = () => {
|
|
|
218
258
|
completed = result.completed;
|
|
219
259
|
}
|
|
220
260
|
|
|
221
|
-
const context = buildSeddContext(branch, currentMigration, completed, pending);
|
|
261
|
+
const context = buildSeddContext(branch, currentMigration, completed, pending, featureExpectation, migrationExpectation);
|
|
222
262
|
if (context) {
|
|
223
263
|
console.log(JSON.stringify({ systemMessage: '\n' + context + '\n' }));
|
|
224
264
|
}
|
|
225
265
|
} catch {
|
|
226
|
-
|
|
266
|
+
return;
|
|
227
267
|
}
|
|
228
268
|
});
|
|
229
269
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sedd",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "SEDD - Spec & Expectation Driven Development. A phase-based specification workflow for AI-assisted development.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
"templates",
|
|
15
15
|
"commands",
|
|
16
16
|
"scripts",
|
|
17
|
-
"hooks"
|
|
17
|
+
"hooks",
|
|
18
|
+
"README.md"
|
|
18
19
|
],
|
|
19
20
|
"scripts": {
|
|
20
21
|
"build": "tsc",
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Acceptance Criteria - Migration {{MIGRATION_ID}}
|
|
2
|
+
|
|
3
|
+
> Generated from expectation
|
|
4
|
+
> Timestamp: {{TIMESTAMP}}
|
|
5
|
+
> Branch: {{BRANCH}}
|
|
6
|
+
|
|
7
|
+
## Expectativa
|
|
8
|
+
|
|
9
|
+
> {{EXPECTATION}}
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Checklist de Aceite
|
|
14
|
+
|
|
15
|
+
### Critérios Funcionais
|
|
16
|
+
|
|
17
|
+
- [ ] **AC-001:** {{criterion_1}}
|
|
18
|
+
- Verificar: {{verification_steps}}
|
|
19
|
+
|
|
20
|
+
- [ ] **AC-002:** {{criterion_2}}
|
|
21
|
+
- Verificar: {{verification_steps}}
|
|
22
|
+
|
|
23
|
+
### Critérios de UX
|
|
24
|
+
|
|
25
|
+
- [ ] **AC-UX-001:** {{ux_criterion}}
|
|
26
|
+
- Verificar: {{verification_steps}}
|
|
27
|
+
|
|
28
|
+
### Critérios Técnicos
|
|
29
|
+
|
|
30
|
+
- [ ] **AC-TECH-001:** {{technical_criterion}}
|
|
31
|
+
- Verificar: {{verification_steps}}
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Comandos de Verificação
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# Comandos sugeridos para testar
|
|
39
|
+
npm test
|
|
40
|
+
npm run build
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Sign-off
|
|
46
|
+
|
|
47
|
+
| Critério | Status | Verificado Por | Data |
|
|
48
|
+
|----------|--------|----------------|------|
|
|
49
|
+
| AC-001 | pending | - | - |
|
|
50
|
+
| AC-002 | pending | - | - |
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Notas
|
|
55
|
+
|
|
56
|
+
_Adicione notas de verificação aqui_
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Relacionados
|
|
61
|
+
|
|
62
|
+
- **Tasks:** Ver `tasks.md` nesta migration
|
|
63
|
+
- **Clarificações:** Ver `clarify.md` nesta migration
|
|
64
|
+
- **Fonte:** Expectativa capturada em /sedd.clarify
|