adi_dev_workflow 1.0.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/bin/index.js +0 -0
  2. package/frameworks/agents/qa-staff-engineer.md +311 -0
  3. package/frameworks/agents/qa-validation-expert.md +458 -0
  4. package/frameworks/agents/tech-review-conformance.md +200 -0
  5. package/frameworks/commands/generate-project-profile.md +68 -0
  6. package/frameworks/commands/generate-prompt.md +33 -98
  7. package/frameworks/commands/ministack/README.md +61 -46
  8. package/frameworks/commands/ministack/code-review.md +36 -49
  9. package/frameworks/commands/ministack/generate-intent.md +25 -2
  10. package/frameworks/commands/ministack/generate-scope.md +30 -6
  11. package/frameworks/commands/ministack/generate-tasks.md +191 -6
  12. package/frameworks/commands/ministack/generate-tech-direction.md +43 -0
  13. package/frameworks/commands/ministack/run-ministack-tasks.md +352 -33
  14. package/frameworks/commands/ministack/run-ministack-withlinear.md +23 -22
  15. package/frameworks/commands/ministack/status.md +153 -0
  16. package/frameworks/commands/sdd/code-review.md +10 -10
  17. package/frameworks/commands/sdd/generate-prd.md +32 -2
  18. package/frameworks/commands/sdd/generate-task-plan.md +199 -5
  19. package/frameworks/commands/sdd/generate-tech-direction.md +43 -0
  20. package/frameworks/commands/sdd/generate-tech-spec.md +218 -0
  21. package/frameworks/commands/sdd/generate-tests.md +2 -2
  22. package/frameworks/commands/sdd/run_tasks.md +391 -43
  23. package/frameworks/commands/sdd/run_tasks_withlinear.md +276 -37
  24. package/frameworks/commands/sdd/status.md +160 -0
  25. package/frameworks/commands/sdd/validate-sdd.md +18 -2
  26. package/frameworks/commands/sync-tasks-to-linear.md +588 -588
  27. package/frameworks/commands/taskcard/generate-taskcard.md +113 -25
  28. package/frameworks/commands/taskcard/run-taskcard.md +203 -34
  29. package/frameworks/skills/ministack-intent-expert/SKILL.md +16 -3
  30. package/frameworks/skills/ministack-intent-expert/templates/intent-template.md +1 -1
  31. package/frameworks/skills/ministack-scope-expert/SKILL.md +19 -11
  32. package/frameworks/skills/ministack-scope-expert/templates/scope-template.md +1 -1
  33. package/frameworks/skills/ministack-tasks-expert/SKILL.md +204 -0
  34. package/frameworks/skills/ministack-tasks-expert/templates/task_plan_template.md +78 -0
  35. package/frameworks/skills/ministack-tasks-expert/templates/task_template.md +103 -0
  36. package/frameworks/skills/ministack-tech-direction-expert/SKILL.md +230 -0
  37. package/frameworks/skills/ministack-tech-direction-expert/evals/evals.json +1 -0
  38. package/frameworks/skills/ministack-tech-direction-expert/templates/tech_direction-template.md +17 -0
  39. package/frameworks/skills/prompt-engineer-expert/SKILL.md +232 -0
  40. package/frameworks/skills/prompt-engineer-expert/templates/prompt_template.md +139 -0
  41. package/frameworks/skills/sdd-prd-expert/SKILL.md +155 -95
  42. package/frameworks/skills/sdd-prd-expert/evals/evals.json +59 -0
  43. package/frameworks/skills/sdd-prd-expert/templates/prd_template.md +46 -46
  44. package/frameworks/skills/sdd-prd-expert/templates/tech_direction-template.md +23 -0
  45. package/frameworks/skills/sdd-task-plan-expert/SKILL.md +191 -201
  46. package/frameworks/skills/sdd-task-plan-expert/evals/evals.json +109 -0
  47. package/frameworks/skills/sdd-task-plan-expert/templates/task_plan_template.md +33 -33
  48. package/frameworks/skills/sdd-task-plan-expert/templates/task_template.md +58 -32
  49. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-1/benchmark.json +99 -0
  50. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-1/benchmark.md +64 -0
  51. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-1/eval-1-happy-path/eval_metadata.json +12 -0
  52. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-1/eval-1-happy-path/with_skill/grading.json +32 -0
  53. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-1/eval-1-happy-path/with_skill/outputs/response.md +134 -0
  54. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-1/eval-1-happy-path/with_skill/outputs/transcript.md +68 -0
  55. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-1/eval-1-happy-path/with_skill/timing.json +5 -0
  56. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-1/eval-1-happy-path/without_skill/grading.json +32 -0
  57. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-1/eval-1-happy-path/without_skill/outputs/response.md +525 -0
  58. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-1/eval-1-happy-path/without_skill/outputs/transcript.md +30 -0
  59. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-1/eval-1-happy-path/without_skill/timing.json +5 -0
  60. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-1/eval-2-spec-simples/eval_metadata.json +12 -0
  61. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-1/eval-2-spec-simples/with_skill/grading.json +32 -0
  62. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-1/eval-2-spec-simples/with_skill/outputs/response.md +1126 -0
  63. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-1/eval-2-spec-simples/with_skill/outputs/transcript.md +131 -0
  64. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-1/eval-2-spec-simples/with_skill/timing.json +5 -0
  65. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-1/eval-2-spec-simples/without_skill/grading.json +32 -0
  66. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-1/eval-2-spec-simples/without_skill/outputs/response.md +452 -0
  67. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-1/eval-2-spec-simples/without_skill/outputs/transcript.md +78 -0
  68. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-1/eval-2-spec-simples/without_skill/timing.json +5 -0
  69. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-1/eval-3-sem-user-stories/eval_metadata.json +12 -0
  70. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-1/eval-3-sem-user-stories/with_skill/grading.json +32 -0
  71. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-1/eval-3-sem-user-stories/with_skill/outputs/response.md +101 -0
  72. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-1/eval-3-sem-user-stories/with_skill/outputs/transcript.md +133 -0
  73. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-1/eval-3-sem-user-stories/with_skill/timing.json +5 -0
  74. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-1/eval-3-sem-user-stories/without_skill/grading.json +32 -0
  75. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-1/eval-3-sem-user-stories/without_skill/outputs/response.md +248 -0
  76. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-1/eval-3-sem-user-stories/without_skill/outputs/transcript.md +49 -0
  77. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-1/eval-3-sem-user-stories/without_skill/timing.json +5 -0
  78. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-1/review.html +1325 -0
  79. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-2/benchmark.json +94 -0
  80. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-2/benchmark.md +67 -0
  81. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-2/eval-1-happy-path/eval_metadata.json +12 -0
  82. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-2/eval-1-happy-path/with_skill/grading.json +32 -0
  83. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-2/eval-1-happy-path/with_skill/outputs/response.md +117 -0
  84. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-2/eval-1-happy-path/with_skill/outputs/transcript.md +91 -0
  85. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-2/eval-1-happy-path/with_skill/timing.json +1 -0
  86. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-2/eval-1-happy-path/without_skill/grading.json +32 -0
  87. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-2/eval-1-happy-path/without_skill/outputs/response.md +694 -0
  88. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-2/eval-1-happy-path/without_skill/outputs/transcript.md +45 -0
  89. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-2/eval-1-happy-path/without_skill/timing.json +1 -0
  90. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-2/eval-2-spec-simples/eval_metadata.json +12 -0
  91. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-2/eval-2-spec-simples/with_skill/grading.json +32 -0
  92. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-2/eval-2-spec-simples/with_skill/outputs/response.md +1087 -0
  93. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-2/eval-2-spec-simples/with_skill/outputs/transcript.md +124 -0
  94. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-2/eval-2-spec-simples/with_skill/timing.json +1 -0
  95. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-2/eval-2-spec-simples/without_skill/grading.json +32 -0
  96. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-2/eval-2-spec-simples/without_skill/outputs/response.md +458 -0
  97. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-2/eval-2-spec-simples/without_skill/outputs/transcript.md +84 -0
  98. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-2/eval-2-spec-simples/without_skill/timing.json +1 -0
  99. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-2/eval-3-sem-user-stories/eval_metadata.json +12 -0
  100. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-2/eval-3-sem-user-stories/with_skill/grading.json +32 -0
  101. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-2/eval-3-sem-user-stories/with_skill/outputs/response.md +70 -0
  102. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-2/eval-3-sem-user-stories/with_skill/outputs/transcript.md +148 -0
  103. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-2/eval-3-sem-user-stories/with_skill/timing.json +1 -0
  104. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-2/eval-3-sem-user-stories/without_skill/grading.json +32 -0
  105. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-2/eval-3-sem-user-stories/without_skill/outputs/response.md +249 -0
  106. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-2/eval-3-sem-user-stories/without_skill/outputs/transcript.md +80 -0
  107. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-2/eval-3-sem-user-stories/without_skill/timing.json +1 -0
  108. package/frameworks/skills/sdd-task-plan-expert-workspace/iteration-2/review.html +1325 -0
  109. package/frameworks/skills/sdd-tech-direction-expert/SKILL.md +235 -0
  110. package/frameworks/skills/sdd-tech-direction-expert/evals/evals.json +1 -0
  111. package/frameworks/skills/sdd-tech-direction-expert/templates/tech_direction-template.md +23 -0
  112. package/frameworks/skills/sdd-tech-spec-expert/SKILL.md +317 -0
  113. package/frameworks/skills/sdd-tech-spec-expert/evals/evals.json +199 -0
  114. package/frameworks/skills/sdd-tech-spec-expert/templates/spec_tech_template.md +290 -0
  115. package/frameworks/skills/sdd-tech-spec-expert/templates/tech_direction-template.md +23 -0
  116. package/frameworks/skills/taskcard-expert/SKILL.md +40 -77
  117. package/frameworks/skills/taskcard-expert/templates/template.md +0 -2
  118. package/frameworks/templates/prompt_template.md +44 -1
  119. package/package.json +1 -1
  120. package/frameworks/commands/ministack/generate-tests.md +0 -37
  121. package/frameworks/commands/sdd/generate-spec-tech.md +0 -37
  122. package/frameworks/commands/taskcard/generate-tests.md +0 -37
  123. package/frameworks/skills/ministack-expert/SKILL.md +0 -415
  124. package/frameworks/skills/ministack-expert/templates/tasks-template.md +0 -141
  125. package/frameworks/skills/ministack-qa-expert/SKILL.md +0 -273
  126. package/frameworks/skills/ministack-qa-expert/templates/task_tests_template.md +0 -24
  127. package/frameworks/skills/ministack-qa-expert/templates/test_strategy_template.md +0 -75
  128. package/frameworks/skills/sdd-qa-expert/SKILL.md +0 -284
  129. package/frameworks/skills/sdd-qa-expert/templates/task_tests_template.md +0 -24
  130. package/frameworks/skills/sdd-qa-expert/templates/test_strategy_template.md +0 -75
  131. package/frameworks/skills/sdd-spec-tech-expert/SKILL.md +0 -387
  132. package/frameworks/skills/sdd-spec-tech-expert/templates/spec_tech_template.md +0 -246
  133. package/frameworks/skills/sdd-spec-tech-expert/templates/tech_direction-template.md +0 -23
  134. package/frameworks/skills/taskcard-qa-expert/SKILL.md +0 -265
  135. package/frameworks/skills/taskcard-qa-expert/templates/task_tests_template.md +0 -78
@@ -0,0 +1,525 @@
1
+ # TASK PLAN -- Modulo de Usuario v1
2
+
3
+ **Baseado em:** `docs/feature-user/v1/spec_tech.md`
4
+ **Data:** 2026-03-07
5
+ **Branch:** `user-feature`
6
+
7
+ ---
8
+
9
+ ## Visao Geral
10
+
11
+ Este Task Plan detalha a ordem de implementacao da feature de usuario conforme definido no SPEC_TECH v1. As tasks estao organizadas em ordem de dependencia (bottom-up), seguindo o fluxo: Infraestrutura -> Persistencia -> Repository -> Service -> Handler -> Testes de Integracao/E2E.
12
+
13
+ ---
14
+
15
+ ## Task 1: Pacote Identity (JWT + Contexto)
16
+
17
+ **Arquivos a CRIAR:**
18
+ - `internal/pkg/identity/identity.go`
19
+ - `internal/pkg/identity/identity_test.go`
20
+
21
+ **Descricao:**
22
+ Criar o pacote `internal/pkg/identity` com as seguintes funcoes publicas:
23
+
24
+ 1. **Tipo `Claims`** -- struct com `UserID`, `Email` e `jwt.RegisteredClaims`
25
+ 2. **`GenerateToken(userID, email, secret string, duration time.Duration) (string, time.Time, error)`** -- gera JWT assinado com HS256
26
+ 3. **`ParseToken(tokenString, secret string) (*Claims, error)`** -- valida e extrai claims; rejeita algoritmos que nao sejam HS256
27
+ 4. **`WithUserID(ctx context.Context, userID string) context.Context`** -- injeta user_id no contexto via chave unexportada
28
+ 5. **`UserIDFromContext(ctx context.Context) (string, bool)`** -- recupera user_id do contexto
29
+
30
+ **Testes unitarios (`identity_test.go`):**
31
+ - `TestGenerateToken_Success` -- token nao vazio, expiresAt no futuro
32
+ - `TestGenerateToken_TokenIsParseable` -- roundtrip generate -> parse
33
+ - `TestGenerateToken_ClaimsContainCorrectData` -- userID e email corretos
34
+ - `TestParseToken_WrongSecret` -- erro retornado
35
+ - `TestParseToken_ExpiredToken` -- erro retornado
36
+ - `TestParseToken_MalformedToken` -- erro retornado
37
+ - `TestContextRoundtrip_UserID` -- WithUserID + UserIDFromContext retorna valor correto
38
+ - `TestUserIDFromContext_Missing` -- retorna "", false
39
+
40
+ **Criterio de conclusao:** Todos os testes passando com `CGO_ENABLED=1 go test ./internal/pkg/identity/... -v`
41
+
42
+ **Dependencias:** Nenhuma (pacote isolado).
43
+
44
+ ---
45
+
46
+ ## Task 2: Configuracao -- Adicionar JWTExpirationHours
47
+
48
+ **Arquivos a MODIFICAR:**
49
+ - `internal/infra/config/config.go`
50
+ - `configs/config.yaml`
51
+
52
+ **Descricao:**
53
+
54
+ 1. Em `config.go`: adicionar campo `JWTExpirationHours int` na struct `Config` e ler via `v.GetInt("jwt.expiration_hours")`
55
+ 2. Em `config.yaml`: adicionar `expiration_hours: 24` dentro da secao `jwt`
56
+
57
+ **Criterio de conclusao:** `make build` compila sem erros; config carrega o novo campo corretamente.
58
+
59
+ **Dependencias:** Nenhuma.
60
+
61
+ ---
62
+
63
+ ## Task 3: Migracao -- Adicionar coluna `endereco`
64
+
65
+ **Arquivos a CRIAR:**
66
+ - `internal/db/migrations/002_add_endereco_usuarios.sql`
67
+
68
+ **Descricao:**
69
+
70
+ Criar migracao com:
71
+ ```sql
72
+ ALTER TABLE usuarios ADD COLUMN endereco TEXT NOT NULL DEFAULT '';
73
+ ```
74
+
75
+ Seguir a convencao do projeto (arquivo unico `.sql`, sem `.up`/`.down`).
76
+
77
+ **Criterio de conclusao:** Aplicacao inicia sem erros; `PRAGMA table_info(usuarios)` lista coluna `endereco`.
78
+
79
+ **Dependencias:** Nenhuma.
80
+
81
+ ---
82
+
83
+ ## Task 4: Queries SQLC -- Atualizar queries de usuario
84
+
85
+ **Arquivos a MODIFICAR:**
86
+ - `internal/db/queries/user.sql` (substituicao total do conteudo)
87
+
88
+ **Descricao:**
89
+
90
+ Substituir o conteudo do arquivo de queries por:
91
+
92
+ 1. **`CreateUser :one`** -- INSERT com campos `id, nome, email, senha_hash, endereco, data_criacao, data_atualizacao` + RETURNING *
93
+ 2. **`GetUserByID :one`** -- SELECT * WHERE id = ? LIMIT 1
94
+ 3. **`GetUserByEmail :one`** -- SELECT * WHERE email = ? LIMIT 1
95
+ 4. **`UpdateUser :one`** -- UPDATE SET nome, email, senha_hash, endereco, data_atualizacao WHERE id = ? RETURNING *
96
+
97
+ **Pos-execucao:** Executar `make generate` para regenerar `internal/db/sqlc/`.
98
+
99
+ **Criterio de conclusao:** `make generate` executa sem erros; codigo gerado em `internal/db/sqlc/` contem as novas queries.
100
+
101
+ **Dependencias:** Task 3 (migracao deve existir para o schema estar correto).
102
+
103
+ ---
104
+
105
+ ## Task 5: Protobuf -- Atualizar contratos gRPC
106
+
107
+ **Arquivos a MODIFICAR:**
108
+ - `api/proto/v1/user.proto` (substituicao total do conteudo)
109
+
110
+ **Descricao:**
111
+
112
+ Substituir o conteudo do proto conforme SPEC_TECH secao 8.1:
113
+
114
+ 1. Mensagem `User` com campos: id, name, email, address, created_at, updated_at
115
+ 2. `CreateUserRequest` com name, email, password, address
116
+ 3. `CreateUserResponse` com id, name, email, created_at
117
+ 4. `LoginRequest` com email, password
118
+ 5. `LoginResponse` com token, expires_at, id, name, email
119
+ 6. `GetUserLoggedRequest` (vazio)
120
+ 7. `GetUserLoggedResponse` com User
121
+ 8. `UpdateUserRequest` com optional string para name, email, address, new_password, current_password
122
+ 9. `UpdateUserResponse` com User
123
+ 10. Servico `UserService` com 4 RPCs: CreateUser, Login, GetUserLogged, UpdateUser
124
+
125
+ **Pos-execucao:** Executar `make generate` para regenerar `gen/proto/v1/`.
126
+
127
+ **Criterio de conclusao:** `make generate` e `make build` executam sem erros.
128
+
129
+ **Dependencias:** Nenhuma (pode ser feita em paralelo com Tasks 1-4).
130
+
131
+ ---
132
+
133
+ ## Task 6: Repository -- Estender UserRepository
134
+
135
+ **Arquivos a MODIFICAR:**
136
+ - `internal/repository/user_repository.go`
137
+
138
+ **Descricao:**
139
+
140
+ 1. Adicionar campo `Address string` ao modelo `User`
141
+ 2. Adicionar metodos a interface `UserRepository`:
142
+ - `GetByEmail(ctx context.Context, email string) (*User, error)`
143
+ - `Update(ctx context.Context, user *User) (*User, error)`
144
+ 3. Implementar os novos metodos na struct `userRepository`
145
+ 4. Atualizar mapeamento SQLC->dominio no `Create` e `GetByID` para incluir `Address` (endereco -> Address)
146
+ 5. Implementar mapeamento no `GetByEmail` e `Update`
147
+
148
+ **Criterio de conclusao:** `make build` compila sem erros.
149
+
150
+ **Dependencias:** Task 4 (queries SQLC regeneradas).
151
+
152
+ ---
153
+
154
+ ## Task 7: Service -- Estender UserService
155
+
156
+ **Arquivos a MODIFICAR:**
157
+ - `internal/service/user_service.go`
158
+
159
+ **Descricao:**
160
+
161
+ 1. **Adicionar dependencias ao construtor:**
162
+ - `*config.Config` e `*zap.Logger` como parametros de `NewUserService`
163
+ - FX resolve automaticamente (sem alterar `fx.go`)
164
+
165
+ 2. **Adicionar variaveis de erro exportadas:**
166
+ - `ErrInvalidName`, `ErrInvalidEmail`, `ErrEmailAlreadyExists`, `ErrPasswordTooShort`, `ErrAddressRequired`
167
+ - `ErrInvalidCredentials`, `ErrUserNotFound`, `ErrNoFieldsToUpdate`
168
+ - `ErrCurrentPasswordRequired`, `ErrCurrentPasswordWrong`
169
+
170
+ 3. **Adicionar tipos:**
171
+ - `CreateUserInput` -- atualizar com campo `Address`
172
+ - `LoginResult` -- novo (Token, ExpiresAt, User)
173
+ - `UpdateUserInput` -- novo (ponteiros *string para campos opcionais)
174
+
175
+ 4. **Adicionar metodos a interface `UserService`:**
176
+ - `Login(ctx context.Context, email, password string) (*LoginResult, error)`
177
+ - `GetUserLogged(ctx context.Context, userID string) (*repository.User, error)`
178
+ - `UpdateUser(ctx context.Context, userID string, input UpdateUserInput) (*repository.User, error)`
179
+
180
+ 5. **Implementar `CreateUser` (atualizar):**
181
+ - Adicionar validacoes: name vazio, email (net/mail), senha >= 8 chars, address vazio
182
+ - Verificar email unico via `repo.GetByEmail`
183
+ - Hash com bcrypt, UUID, timestamps
184
+ - Persistir via `repo.Create`
185
+ - Logging: Info "usuario criado com sucesso"
186
+
187
+ 6. **Implementar `Login`:**
188
+ - `repo.GetByEmail` -- se nao existe: `ErrInvalidCredentials`
189
+ - `bcrypt.CompareHashAndPassword` -- se falha: `ErrInvalidCredentials`
190
+ - `identity.GenerateToken(userID, email, secret, duration)`
191
+ - Limpar PasswordHash antes de retornar
192
+ - Logging: Info "login bem-sucedido" / Warn "tentativa de login falha"
193
+
194
+ 7. **Implementar `GetUserLogged`:**
195
+ - `repo.GetByID(userID)` -- se nao encontra: `ErrUserNotFound`
196
+ - Limpar PasswordHash
197
+ - Retornar User
198
+
199
+ 8. **Implementar `UpdateUser`:**
200
+ - Validar ao menos 1 campo nao-nil
201
+ - Buscar user atual via `repo.GetByID`
202
+ - Se email: validar formato + unicidade
203
+ - Se new_password: exigir current_password, validar tamanho, verificar hash, gerar novo hash
204
+ - Aplicar campos nao-nil sobre user atual
205
+ - Persistir via `repo.Update`
206
+ - Limpar PasswordHash antes de retornar
207
+ - Logging: Info "dados atualizados" / Info "senha alterada"
208
+
209
+ **Criterio de conclusao:** `make build` compila sem erros.
210
+
211
+ **Dependencias:** Task 1 (identity), Task 2 (config), Task 6 (repository).
212
+
213
+ ---
214
+
215
+ ## Task 8: Interceptor Auth -- Integrar com identity
216
+
217
+ **Arquivos a MODIFICAR:**
218
+ - `internal/infra/grpc/interceptors/auth.go`
219
+
220
+ **Descricao:**
221
+
222
+ 1. Adicionar `/proto.v1.UserService/Login` em `skipMethods`
223
+ 2. Substituir parse manual do token por `identity.ParseToken(tokenString, cfg.JWTSecret)`
224
+ 3. Apos validacao bem-sucedida: `ctx = identity.WithUserID(ctx, claims.UserID)`
225
+ 4. Passar ctx atualizado ao handler
226
+
227
+ **Criterio de conclusao:** `make build` compila sem erros.
228
+
229
+ **Dependencias:** Task 1 (identity).
230
+
231
+ ---
232
+
233
+ ## Task 9: Handler gRPC -- Estender UserHandler
234
+
235
+ **Arquivos a MODIFICAR:**
236
+ - `internal/handler/grpc/user_handler.go`
237
+
238
+ **Descricao:**
239
+
240
+ 1. **Atualizar `CreateUser`:**
241
+ - Extrair `address` do request
242
+ - Mapear response com `CreateUserResponse{id, name, email, created_at}`
243
+
244
+ 2. **Implementar `Login`:**
245
+ - Extrair email e password do request
246
+ - Chamar `service.Login`
247
+ - Retornar `LoginResponse{token, expires_at, id, name, email}`
248
+
249
+ 3. **Implementar `GetUserLogged`:**
250
+ - `identity.UserIDFromContext(ctx)` -- se ausente: `codes.Unauthenticated`
251
+ - Chamar `service.GetUserLogged(userID)`
252
+ - Retornar `GetUserLoggedResponse{User{...}}`
253
+
254
+ 4. **Implementar `UpdateUser`:**
255
+ - `identity.UserIDFromContext(ctx)` -- se ausente: `codes.Unauthenticated`
256
+ - Construir `UpdateUserInput` com ponteiros (nil = campo ausente)
257
+ - Chamar `service.UpdateUser(userID, input)`
258
+ - Retornar `UpdateUserResponse{User{...}}`
259
+
260
+ 5. **Remover `GetUser`** (substituido por `GetUserLogged`)
261
+
262
+ 6. **Atualizar `mapServiceError`:**
263
+ - Adicionar mapeamento para todos os novos erros conforme SPEC_TECH secao 11.2
264
+
265
+ 7. **Criar funcao auxiliar `domainUserToProto`:**
266
+ - Converte `*repository.User` para `*pb.User`
267
+
268
+ **Criterio de conclusao:** `make build` compila sem erros.
269
+
270
+ **Dependencias:** Task 5 (proto gerado), Task 7 (service).
271
+
272
+ ---
273
+
274
+ ## Task 10: Configuracao de Rotas Publicas
275
+
276
+ **Arquivos a MODIFICAR:**
277
+ - `configs/config.yaml`
278
+
279
+ **Descricao:**
280
+
281
+ Garantir que `skip_methods` no config inclua:
282
+ - `/proto.v1.UserService/CreateUser`
283
+ - `/proto.v1.UserService/Login`
284
+
285
+ **Criterio de conclusao:** Servidor inicia sem erros; rotas publicas acessiveis sem token.
286
+
287
+ **Dependencias:** Task 8 (interceptor), Task 9 (handler).
288
+
289
+ ---
290
+
291
+ ## Task 11: Testes Unitarios -- Service
292
+
293
+ **Arquivos a MODIFICAR:**
294
+ - `internal/service/user_service_test.go`
295
+
296
+ **Descricao:**
297
+
298
+ Atualizar mock `MockUserRepository` com metodos `GetByEmail` e `Update`.
299
+
300
+ **CreateUser (atualizar existentes + novos):**
301
+ - `TestCreateUser_Success` -- incluir Address
302
+ - `TestCreateUser_PasswordIsHashed` -- bcrypt roundtrip
303
+ - `TestCreateUser_GeneratesValidUUID`
304
+ - `TestCreateUser_ErrorEmptyName`
305
+ - `TestCreateUser_ErrorInvalidEmailFormat` (novo)
306
+ - `TestCreateUser_ErrorPasswordTooShort_7Chars` (novo)
307
+ - `TestCreateUser_PasswordExactly8Chars` (novo)
308
+ - `TestCreateUser_ErrorEmptyAddress` (novo)
309
+ - `TestCreateUser_ErrorRepositoryFailure`
310
+
311
+ **Login (novos):**
312
+ - `TestLogin_Success`
313
+ - `TestLogin_ResultDoesNotExposePasswordHash`
314
+ - `TestLogin_TokenExpiresAtRespectsConfig`
315
+ - `TestLogin_EmailNotFound_GenericError`
316
+ - `TestLogin_WrongPassword_GenericError`
317
+ - `TestLogin_ErrorRepositoryFailure`
318
+
319
+ **GetUserLogged (novos):**
320
+ - `TestGetUserLogged_Success`
321
+ - `TestGetUserLogged_UserNotFound`
322
+ - `TestGetUserLogged_RepositoryError`
323
+
324
+ **UpdateUser (novos):**
325
+ - `TestUpdateUser_NameOnly`
326
+ - `TestUpdateUser_EmailOnly`
327
+ - `TestUpdateUser_AddressOnly`
328
+ - `TestUpdateUser_PasswordChange_Success`
329
+ - `TestUpdateUser_MultipleFields`
330
+ - `TestUpdateUser_NoFieldsToUpdate`
331
+ - `TestUpdateUser_InvalidEmailFormat`
332
+ - `TestUpdateUser_EmailAlreadyExists`
333
+ - `TestUpdateUser_CurrentPasswordMissing`
334
+ - `TestUpdateUser_WrongCurrentPassword`
335
+ - `TestUpdateUser_NewPasswordTooShort`
336
+ - `TestUpdateUser_UserNotFound`
337
+ - `TestUpdateUser_RepositoryFailure`
338
+
339
+ **Criterio de conclusao:** `CGO_ENABLED=1 go test ./internal/service/... -v` -- todos passando.
340
+
341
+ **Dependencias:** Task 7 (service implementado).
342
+
343
+ ---
344
+
345
+ ## Task 12: Testes Unitarios -- Handler
346
+
347
+ **Arquivos a MODIFICAR:**
348
+ - `internal/handler/grpc/user_handler_test.go`
349
+
350
+ **Descricao:**
351
+
352
+ Atualizar mock `MockUserService` com metodos `Login`, `GetUserLogged`, `UpdateUser`. Remover testes de `GetUser`.
353
+
354
+ **CreateUser:**
355
+ - `TestUserHandler_CreateUser_Success`
356
+ - `TestUserHandler_CreateUser_ResponseDoesNotExposePasswordHash`
357
+ - `TestUserHandler_CreateUser_EmptyName`
358
+ - `TestUserHandler_CreateUser_EmptyEmail`
359
+ - `TestUserHandler_CreateUser_ShortPassword`
360
+ - `TestUserHandler_CreateUser_EmptyAddress`
361
+ - `TestUserHandler_CreateUser_DuplicateEmail`
362
+ - `TestUserHandler_CreateUser_InternalError`
363
+
364
+ **Login:**
365
+ - `TestUserHandler_Login_Success`
366
+ - `TestUserHandler_Login_InvalidCredentials`
367
+ - `TestUserHandler_Login_InternalError`
368
+
369
+ **GetUserLogged:**
370
+ - `TestUserHandler_GetUserLogged_Success`
371
+ - `TestUserHandler_GetUserLogged_MissingUserID`
372
+ - `TestUserHandler_GetUserLogged_NotFound`
373
+
374
+ **UpdateUser:**
375
+ - `TestUserHandler_UpdateUser_NameOnly`
376
+ - `TestUserHandler_UpdateUser_EmailOnly`
377
+ - `TestUserHandler_UpdateUser_PasswordChange`
378
+ - `TestUserHandler_UpdateUser_MultipleFields`
379
+ - `TestUserHandler_UpdateUser_NoFields`
380
+ - `TestUserHandler_UpdateUser_EmailAlreadyExists`
381
+ - `TestUserHandler_UpdateUser_CurrentPasswordMissing`
382
+ - `TestUserHandler_UpdateUser_WrongCurrentPassword`
383
+ - `TestUserHandler_UpdateUser_NewPasswordTooShort`
384
+ - `TestUserHandler_UpdateUser_UserNotFound`
385
+
386
+ **Criterio de conclusao:** `CGO_ENABLED=1 go test ./internal/handler/grpc/... -v` -- todos passando.
387
+
388
+ **Dependencias:** Task 9 (handler implementado).
389
+
390
+ ---
391
+
392
+ ## Task 13: Testes Unitarios -- Interceptor Auth
393
+
394
+ **Arquivos a MODIFICAR:**
395
+ - `internal/infra/grpc/interceptors/auth_test.go`
396
+
397
+ **Descricao:**
398
+
399
+ Adicionar testes:
400
+ - `TestAuthInterceptor_ValidToken_InjectsUserID` -- ctx contem user_id correto
401
+ - `TestAuthInterceptor_SkipsLogin` -- table-driven com CreateUser e Login
402
+ - `TestAuthInterceptor_ProtectedMethodsRequireAuth` -- table-driven com GetUserLogged e UpdateUser
403
+
404
+ **Criterio de conclusao:** `CGO_ENABLED=1 go test ./internal/infra/grpc/interceptors/... -v` -- todos passando.
405
+
406
+ **Dependencias:** Task 8 (interceptor atualizado).
407
+
408
+ ---
409
+
410
+ ## Task 14: Testes de Integracao -- Repository
411
+
412
+ **Arquivos a CRIAR:**
413
+ - `internal/repository/user_repository_integration_test.go`
414
+
415
+ **Descricao:**
416
+
417
+ Setup com SQLite em `t.TempDir()` + migracoes aplicadas via `database.NewDatabase`.
418
+
419
+ Testes:
420
+ - `TestUserRepository_Create_Success` -- todos os campos persistidos
421
+ - `TestUserRepository_CreateAndGetByID` -- roundtrip create + get
422
+ - `TestUserRepository_GetByEmail` -- retorna user correto com Address
423
+ - `TestUserRepository_Create_DuplicateEmail` -- erro UNIQUE constraint
424
+ - `TestUserRepository_GetByID_NotFound` -- erro
425
+ - `TestUserRepository_GetByEmail_NotFound` -- erro
426
+ - `TestUserRepository_Update_NameOnly`
427
+ - `TestUserRepository_Update_Email`
428
+ - `TestUserRepository_Update_PasswordHash`
429
+ - `TestUserRepository_Update_Address`
430
+ - `TestUserRepository_Update_UpdatedAtChanges`
431
+ - `TestUserRepository_Create_GeneratesValidUUID`
432
+
433
+ **Criterio de conclusao:** `CGO_ENABLED=1 go test ./internal/repository/... -v -tags=integration` -- todos passando.
434
+
435
+ **Dependencias:** Task 6 (repository implementado), Task 3 (migracao).
436
+
437
+ ---
438
+
439
+ ## Task 15: Testes de Integracao -- Migracao
440
+
441
+ **Arquivos a MODIFICAR:**
442
+ - `internal/infra/database/sqlite_test.go`
443
+
444
+ **Descricao:**
445
+
446
+ Adicionar testes:
447
+ - `TestRunMigrations_TableSchema_IncludesEndereco` -- PRAGMA table_info confirma coluna
448
+ - `TestRunMigrations_EnderecocolumnDefaultEmpty` -- INSERT sem endereco retorna ""
449
+ - `TestRunMigrations_IdempotentWithEndereco` -- segunda chamada NewDatabase sem erro
450
+
451
+ **Criterio de conclusao:** `CGO_ENABLED=1 go test ./internal/infra/database/... -v` -- todos passando.
452
+
453
+ **Dependencias:** Task 3 (migracao criada).
454
+
455
+ ---
456
+
457
+ ## Task 16: Testes E2E
458
+
459
+ **Arquivos a CRIAR:**
460
+ - `internal/e2e/user_e2e_test.go`
461
+
462
+ **Descricao:**
463
+
464
+ Setup: servidor gRPC real em porta efemera + cliente gRPC + SQLite em `t.TempDir()`.
465
+
466
+ Fluxos:
467
+ - `TestE2E_CreateUser_FullFlow` -- cadastro completo, verifica response sem token, UUID valido
468
+ - `TestE2E_LoginAndGetUserLogged_FullFlow` -- login + consulta dados com Bearer token
469
+ - `TestE2E_UpdateUser_PartialUpdate` -- login + update nome + get confirma persistencia
470
+ - `TestE2E_ProtectedRoutes_RequireAuth` -- GetUserLogged e UpdateUser sem token retornam Unauthenticated
471
+ - `TestE2E_UpdateUser_PasswordChangeAndReauth` -- troca senha + login nova senha ok + login senha antiga falha
472
+
473
+ **Criterio de conclusao:** `CGO_ENABLED=1 go test ./internal/e2e/... -v` -- todos passando.
474
+
475
+ **Dependencias:** Todas as tasks anteriores (1-15).
476
+
477
+ ---
478
+
479
+ ## Task 17: Validacao Final
480
+
481
+ **Descricao:**
482
+
483
+ 1. Executar `make build` -- compilacao sem erros
484
+ 2. Executar `make test` -- todos os testes passando
485
+ 3. Executar `make lint` -- sem problemas de lint nos protos
486
+ 4. Verificar que `PasswordHash` e tokens JWT nao aparecem em nenhum log ou response
487
+ 5. Verificar que rotas publicas (`CreateUser`, `Login`) funcionam sem token
488
+ 6. Verificar que rotas protegidas (`GetUserLogged`, `UpdateUser`) exigem token valido
489
+
490
+ **Criterio de conclusao:** Todos os checks passam. Feature pronta para code review.
491
+
492
+ **Dependencias:** Task 16.
493
+
494
+ ---
495
+
496
+ ## Diagrama de Dependencias
497
+
498
+ ```
499
+ Task 1 (identity) ─────────────┬──────> Task 7 (service) ──────> Task 9 (handler) ──> Task 12 (test handler)
500
+ │ │ │
501
+ Task 2 (config) ────────────────┘ │ │
502
+ ▼ ▼
503
+ Task 3 (migracao) ──> Task 4 (sqlc) ──> Task 6 (repo) ──> Task 11 (test service) Task 10 (rotas publicas)
504
+ │ │
505
+ ▼ ▼
506
+ Task 15 (test migracao) Task 14 (test integracao repo)
507
+
508
+ Task 1 ──> Task 8 (interceptor) ──> Task 13 (test interceptor)
509
+
510
+ Todas as tasks ──> Task 16 (E2E) ──> Task 17 (validacao final)
511
+ ```
512
+
513
+ ## Resumo de Execucao
514
+
515
+ | Fase | Tasks | Descricao |
516
+ |------|-------|-----------|
517
+ | **Fase 1 -- Infraestrutura** | Tasks 1, 2, 3 | Identity, Config, Migracao (paralelas) |
518
+ | **Fase 2 -- Persistencia** | Tasks 4, 5 | Queries SQLC, Protobuf (paralelas) |
519
+ | **Fase 3 -- Camadas de Negocio** | Tasks 6, 7, 8 | Repository, Service, Interceptor |
520
+ | **Fase 4 -- Exposicao** | Tasks 9, 10 | Handler gRPC, Rotas publicas |
521
+ | **Fase 5 -- Testes Unitarios** | Tasks 11, 12, 13 | Testes service, handler, interceptor (paralelas) |
522
+ | **Fase 6 -- Testes Integracao** | Tasks 14, 15 | Repository + Migracao (paralelas) |
523
+ | **Fase 7 -- Testes E2E + Validacao** | Tasks 16, 17 | Fluxos completos + validacao final |
524
+
525
+ **Total: 17 tasks organizadas em 7 fases.**
@@ -0,0 +1,30 @@
1
+ # Transcript of Tool Calls
2
+
3
+ ## Call 1: ToolSearch
4
+ - **Query:** `select:Read,Write,Glob`
5
+ - **Purpose:** Load the Read, Write, and Glob tools for file operations.
6
+
7
+ ## Call 2: Read
8
+ - **File:** `H:\repos\flutter_experience\04_2026\cb_vakinhaburger_2025\vakinha-api-review\docs\feature-user\v1\spec_tech.md`
9
+ - **Purpose:** Read the approved SPEC_TECH document to understand all technical requirements for the user feature.
10
+ - **Result:** File was large (914 lines). First 41 lines loaded in preview, full content saved to persistent output.
11
+
12
+ ## Call 3: Read (continued)
13
+ - **File:** `H:\repos\flutter_experience\04_2026\cb_vakinhaburger_2025\vakinha-api-review\docs\feature-user\v1\spec_tech.md`
14
+ - **Offset:** 42
15
+ - **Purpose:** Read the remainder of the SPEC_TECH starting from line 42 (architecture section onwards).
16
+ - **Result:** Read complete document including all 16 sections: architecture, data structures, user stories, business rules, technical flows, proto contracts, persistence, security (identity package), error handling, configuration, logging, test strategy, and file listing.
17
+
18
+ ## Call 4: Glob
19
+ - **Pattern:** `internal/**/*.go`
20
+ - **Path:** `H:\repos\flutter_experience\04_2026\cb_vakinhaburger_2025\vakinha-api-review`
21
+ - **Purpose:** Understand the current codebase structure and existing files to properly plan which files need to be created vs modified.
22
+ - **Result:** Found 17 existing Go files across handler, infra (config, database, di, grpc, logger), repository, and service packages.
23
+
24
+ ## Call 5: Write
25
+ - **File:** `H:\repos\flutter_experience\04_2026\cb_vakinhaburger_2025\vakinha-api-review\.claude\skills\sdd-task-plan-expert-workspace\iteration-1\eval-1-happy-path\without_skill\outputs\response.md`
26
+ - **Purpose:** Save the generated Task Plan document with 17 tasks organized in 7 phases.
27
+
28
+ ## Call 6: Write
29
+ - **File:** `H:\repos\flutter_experience\04_2026\cb_vakinhaburger_2025\vakinha-api-review\.claude\skills\sdd-task-plan-expert-workspace\iteration-1\eval-1-happy-path\without_skill\outputs\transcript.md`
30
+ - **Purpose:** Save this transcript of tool calls.
@@ -0,0 +1,5 @@
1
+ {
2
+ "total_tokens": 40363,
3
+ "duration_ms": 141273,
4
+ "total_duration_seconds": 141.3
5
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "eval_id": 2,
3
+ "eval_name": "spec-tech-simples-alteracao-pontual",
4
+ "prompt": "Preciso de um TASK PLAN para esta feature simples. O SPEC_TECH aprovado esta abaixo:\n\n---\n# SPEC_TECH — Adicionar Telefone ao Usuario v1\n\n## 1. Identificacao\n| Campo | Valor |\n|-------|-------|\n| **Feature/Projeto** | Adicionar Telefone ao Modulo de Usuario |\n| **Versao** | v1 |\n| **Data** | 2026-03-07 |\n| **PRD** | docs/feature-telefone-usuario/v1/prd.md |\n\n## 2. Resumo Tecnico\nAdicionar campo `telefone` (opcional) a tabela `usuarios` e expor via gRPC nos endpoints CreateUser e UpdateUser.\n\n## 3. Definicoes Tecnicas\n\n### 3.1 Banco de Dados\n- Nova migracao: `ALTER TABLE usuarios ADD COLUMN telefone TEXT;`\n\n### 3.2 SQLC\n- Atualizar queries CreateUser e UpdateUser para incluir coluna `telefone`\n\n### 3.3 Repository\n- Adicionar campo `Phone` ao modelo User\n- Mapear `telefone` (banco) para `Phone` (Go)\n\n### 3.4 Service\n- Aceitar campo opcional phone em CreateUser e UpdateUser\n- Validacao: se informado, deve ter entre 10 e 15 caracteres\n\n### 3.5 Handler gRPC\n- Adicionar campo `phone` nas mensagens proto CreateUserRequest, UpdateUserRequest e User\n\n### 3.6 Proto\n- Atualizar user.proto com campo `string phone = X;`\n\n## 4. User Stories Relacionadas\n- US-10: Como usuario, quero informar meu telefone para receber notificacoes por SMS\n---",
5
+ "assertions": [
6
+ {"id": "b1", "text": "Gera um numero proporcional de tasks (entre 3 e 6) — nao over-engineers com tasks demais para uma alteracao simples", "type": "llm_judge"},
7
+ {"id": "b2", "text": "Respeita a ordem de dependencias das camadas (migracao > SQLC > repository > service > handler > proto)", "type": "llm_judge"},
8
+ {"id": "b3", "text": "Mapeia a US-10 na tabela de rastreabilidade do task_plan", "type": "llm_judge"},
9
+ {"id": "b4", "text": "Cada task segue o template completo (secoes 1-8) ou marca secoes N/A com justificativa", "type": "llm_judge"},
10
+ {"id": "b5", "text": "Salva task_plan.md como documento de REFERENCIA (sem corpo detalhado de tasks dentro dele)", "type": "llm_judge"}
11
+ ]
12
+ }
@@ -0,0 +1,32 @@
1
+ {
2
+ "eval_id": 2,
3
+ "eval_name": "spec-tech-simples-alteracao-pontual",
4
+ "configuration": "with_skill",
5
+ "expectations": [
6
+ {
7
+ "text": "Gera um numero proporcional de tasks (entre 3 e 6) — nao over-engineers com tasks demais para uma alteracao simples",
8
+ "passed": true,
9
+ "evidence": "Gerou exatamente 6 tasks (T1-T6), dentro da faixa esperada de 3-6. Proporcional a complexidade da feature."
10
+ },
11
+ {
12
+ "text": "Respeita a ordem de dependencias das camadas (migracao > SQLC > repository > service > handler > proto)",
13
+ "passed": true,
14
+ "evidence": "Dependencias: T1(migracao)->T2(SQLC)->T3(repo)->T4(service)->T6(handler), T5(proto)->T6(handler). Proto em paralelo com migracao. Ordem correta."
15
+ },
16
+ {
17
+ "text": "Mapeia a US-10 na tabela de rastreabilidade do task_plan",
18
+ "passed": true,
19
+ "evidence": "Secao 5 do task_plan contem tabela de rastreabilidade mapeando US-10 para todas as 6 tasks com definicoes tecnicas correspondentes."
20
+ },
21
+ {
22
+ "text": "Cada task segue o template completo (secoes 1-8) ou marca secoes N/A com justificativa",
23
+ "passed": true,
24
+ "evidence": "Todas as 6 tasks (T1-T6) seguem o template com secoes 1-8 preenchidas. Secoes N/A possuem justificativa (ex: T1 secao 6.1: 'N/A -- migracao SQL nao possui testes unitarios isolados')."
25
+ },
26
+ {
27
+ "text": "Salva task_plan.md como documento de REFERENCIA (sem corpo detalhado de tasks dentro dele)",
28
+ "passed": true,
29
+ "evidence": "O task_plan contem apenas identificacao, macro-fases, tabela de tasks com IDs/links, rastreabilidade, dependencias e criterios. Tasks detalhadas estao separadas (T1-T6). Embora tudo esteja em um arquivo de output por ser eval, a estrutura esta correta."
30
+ }
31
+ ]
32
+ }