@spec-wave/cli 0.27.0 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/package.json +1 -1
  2. package/src/api/github-graphql.mjs +37 -0
  3. package/src/api/github-rest.mjs +48 -0
  4. package/src/cli.mjs +51 -2
  5. package/src/commands/audit.mjs +280 -0
  6. package/src/commands/doctor.mjs +40 -16
  7. package/src/commands/implement.mjs +19 -2
  8. package/src/commands/install-skill.mjs +18 -8
  9. package/src/commands/merge.mjs +292 -0
  10. package/src/commands/move.mjs +26 -11
  11. package/src/commands/order.mjs +42 -0
  12. package/src/commands/preflight.mjs +322 -0
  13. package/src/commands/run.mjs +4 -3
  14. package/src/commands/update.mjs +143 -12
  15. package/src/lib/board.mjs +18 -2
  16. package/src/lib/critique.mjs +64 -8
  17. package/src/lib/pr-branch.mjs +96 -7
  18. package/src/lib/pr-step.mjs +12 -7
  19. package/src/lib/spec-audit.mjs +372 -0
  20. package/src/lib/tech-context.mjs +20 -14
  21. package/src/plugin/.claude-plugin/plugin.json +1 -1
  22. package/src/plugin/README.md +5 -0
  23. package/src/plugin/skills/audit/SKILL.md +34 -0
  24. package/src/plugin/skills/audit/model-prompt.critique.md +34 -0
  25. package/src/plugin/skills/merge/SKILL.md +34 -0
  26. package/src/plugin/skills/order/SKILL.md +1 -0
  27. package/src/plugin/skills/plan/model-prompt.md +1 -0
  28. package/src/plugin/skills/plan/reference/tech-context.md +6 -0
  29. package/src/plugin/skills/preparar-feature/SKILL.md +247 -0
  30. package/src/plugin/skills/preparar-feature/reference/critica.md +88 -0
  31. package/src/plugin/skills/preparar-specs/SKILL.md +191 -0
  32. package/src/plugin/skills/preparar-specs/reference/armadilhas.md +209 -0
  33. package/src/plugin/skills/preparar-specs/reference/revisao.md +110 -0
  34. package/src/plugin/skills/update/SKILL.md +10 -4
  35. package/src/plugin/skills/workflow/SKILL.md +6 -1
  36. package/src/templates/config/tech_context.yml +13 -0
  37. package/src/templates/skill/SKILL.md +36 -7
  38. package/src/templates/workflows/qa.yml +9 -1
@@ -0,0 +1,209 @@
1
+ # Armadilhas operacionais deste fluxo
2
+
3
+ Cada item aqui custou uma investigação real. A causa vem junto porque o sintoma, sozinho,
4
+ costuma apontar para o lugar errado.
5
+
6
+ ## Índice
7
+
8
+ 1. Token do `gh` inválido no ambiente
9
+ 2. `gh issue edit --add-label` falha com 503
10
+ 3. A API do GitHub devolve 503 intermitente
11
+ 4. Working tree compartilhado com outros agentes
12
+ 5. Label de gatilho grudada impede o retry
13
+ 6. `spec-wave:spec` sobrescreve spec revisada
14
+ 7. `spec-wave update` reescreve os workflows
15
+ 8. Runs `skipped` são normais — não são falha
16
+ 9. `conclusion` vazia não é conclusão
17
+ 10. Geração leva minutos — não rode em primeiro plano
18
+ 11. Run interrompido deixa lock órfão
19
+ 12. O documento foi gerado e o PR não nasceu
20
+
21
+ ---
22
+
23
+ ## 1. Token do `gh` inválido no ambiente
24
+
25
+ **Sintoma:** `gh` falha com erro de autenticação, ou enxerga o repositório errado.
26
+
27
+ **Causa:** a variável `GH_TOKEN` do ambiente pode estar inválida ou pertencer a uma conta
28
+ sem acesso à organização, enquanto o keyring tem a conta certa.
29
+
30
+ **Como resolver:** exporte o token da conta correta antes dos comandos:
31
+
32
+ ```bash
33
+ export GH_TOKEN=$(env -u GH_TOKEN gh auth token -u <conta-com-acesso>)
34
+ ```
35
+
36
+ O `env -u GH_TOKEN` é necessário porque o `gh auth token` também consulta a variável
37
+ inválida se ela estiver setada.
38
+
39
+ A CLI tem a saída própria dela para o mesmo problema, que não depende do shell:
40
+ `spec-wave --account <login> <comando>`, ou `"github": { "account": "<login>" }` no
41
+ `.spec-wave.json`. Fora do CI, a conta declarada vence a variável de ambiente.
42
+
43
+ ## 2. `gh issue edit --add-label` falha com 503
44
+
45
+ **Sintoma:** o comando falha repetidamente, e parece que o gatilho não existe.
46
+
47
+ **Causa:** esse subcomando passa pelo GraphQL, que pode estar degradado enquanto o REST
48
+ funciona normalmente.
49
+
50
+ **Alternativa que funciona:**
51
+
52
+ ```bash
53
+ gh api -X POST repos/<owner>/<repo>/issues/<n>/labels -f "labels[]=spec-wave:spec"
54
+ ```
55
+
56
+ ## 3. A API do GitHub devolve 503 intermitente
57
+
58
+ **Sintoma:** comandos falham de forma aleatória e passam na tentativa seguinte.
59
+
60
+ **Como lidar:** envolva as chamadas em retry (3–5 tentativas com pausa) e **verifique o
61
+ resultado real**, não o código de saída isolado. Um `gh` que devolve string vazia sem erro
62
+ é indistinguível de "não encontrei nada" se você não conferir.
63
+
64
+ ## 4. Working tree compartilhado com outros agentes
65
+
66
+ **Sintoma:** arquivos modificados que você não criou; branch diferente da esperada.
67
+
68
+ **Causa:** outros processos (dev-agents, outras sessões) usam o mesmo checkout e trocam de
69
+ branch sem aviso.
70
+
71
+ **Regra:** nunca `checkout`, `stash` ou `reset` sem antes conferir `git branch --show-current`
72
+ e `git status --short`. A geração em si não disputa o checkout — ela publica por API, sem
73
+ tocar em disco —, mas tudo que você fizer à mão disputa.
74
+
75
+ Se precisar mesmo de uma branch checada — por exemplo, para editar arquivos de um PR já
76
+ aberto — use um worktree temporário fora do repositório, e remova depois:
77
+
78
+ ```bash
79
+ git worktree add /tmp/<dir> <branch>
80
+ # ... edições, commit, push ...
81
+ git worktree remove --force /tmp/<dir> && git worktree prune
82
+ ```
83
+
84
+ ## 5. Label de gatilho grudada impede o retry
85
+
86
+ **Sintoma:** reaplicar a label não dispara nada; ou o `run` local recusa executar com
87
+ `⛔ trigger-pending`.
88
+
89
+ **Causa:** o evento `issues: [labeled]` não redispara com a label já presente, e o `run`
90
+ recusa rodar com gatilho pendente — a label significa "Action em execução", ou uma que
91
+ falhou e a deixou para trás.
92
+
93
+ **Como resolver:** remover e reaplicar. No modo local, onde nenhuma Action está rodando, a
94
+ label é resíduo: **remova-a em vez de usar `--force`**, para a issue não mentir sobre o
95
+ estado.
96
+
97
+ ```bash
98
+ gh api -X DELETE "repos/<owner>/<repo>/issues/<n>/labels/spec-wave:spec"
99
+ ```
100
+
101
+ Nem sempre a label fica: em algumas falhas a CLI a remove sozinha no início do run.
102
+ Confira issue a issue em vez de supor — o `preflight` já lista as pendentes.
103
+
104
+ ## 6. `spec-wave:spec` sobrescreve spec revisada
105
+
106
+ A label **regenera** o documento do zero. Se a spec já foi revisada, editada à mão ou
107
+ corrigida, reaplicar joga tudo fora para consertar o que muitas vezes é uma frase.
108
+
109
+ Para correção pontual em documento já gerado, a edição direta é permitida **quando o
110
+ usuário pede explicitamente** — e só nesse caso. Edite no PR: as edições são preservadas.
111
+
112
+ ## 7. `spec-wave update` reescreve os workflows
113
+
114
+ O `update` compara os workflows com os templates da CLI e sobrescreve os divergentes. Toda
115
+ customização local neles é perdida no bump, silenciosamente, e o sintoma só aparece na
116
+ próxima geração.
117
+
118
+ Se o repositório tem workflows customizados de propósito, rode `update --skip-repo`, ou
119
+ reaplique a customização antes de commitar o bump. Confirme depois:
120
+
121
+ ```bash
122
+ git show origin/main:.github/workflows/generate-spec.yml | grep <marca-da-customizacao>
123
+ ```
124
+
125
+ ## 8. Runs `skipped` são normais — não são falha
126
+
127
+ O evento `issues: [labeled]` dispara **todos** os workflows que escutam labels; cada um se
128
+ filtra pelo próprio `if:`. Ver `generate-plan` e `decompose` como `skipped` depois de
129
+ aplicar `spec-wave:spec` é o comportamento correto, não um problema.
130
+
131
+ O mesmo vale para o repositório em modo `local`: todo job carrega
132
+ `if: vars.SPEC_WAVE_EXECUTION != 'local'`, então o run aparece verde e `skipped`, sem erro
133
+ e sem documento. Se você aplicou uma label e nada aconteceu, confira o modo antes de
134
+ procurar defeito: `npx @spec-wave/cli@latest mode`.
135
+
136
+ Ao procurar o run que interessa, filtre pelo workflow **e** pelo título da issue.
137
+
138
+ ## 9. `conclusion` vazia não é conclusão
139
+
140
+ O `gh run list` devolve `conclusion` como **string vazia** — não `null` — enquanto o run
141
+ está em andamento. Um filtro `select(.conclusion != null)` deixa passar runs que ainda
142
+ estão rodando, e você conclui cedo demais que tudo terminou.
143
+
144
+ Filtre por `.status == "completed"` **e** `conclusion` não-vazia.
145
+
146
+ ## 10. Geração leva minutos — não rode em primeiro plano
147
+
148
+ Uma spec é uma chamada de modelo gerando um documento longo: leva minutos. Rodar no
149
+ primeiro plano de uma ferramenta com timeout curto faz o comando morrer no meio — e o custo
150
+ já foi pago.
151
+
152
+ Rode em background, ou com timeout generoso (10 min por Feature). Numa milestone grande em
153
+ modo local isso passa de uma hora em série; combine com o usuário antes de começar.
154
+
155
+ ## 11. Run interrompido deixa lock órfão
156
+
157
+ **Sintoma:** `Já existe um 'spec-wave run' para <n> (pid NNNN, desde ...)` e a geração é
158
+ recusada, mesmo não havendo nada rodando.
159
+
160
+ **Causa:** o `run` grava `.git/spec-wave/run-<n>.lock` para impedir duas execuções na mesma
161
+ issue. Um run morto por timeout ou Ctrl-C não tem chance de limpar o próprio lock.
162
+
163
+ **Como resolver — confirmando antes:** o lock guarda o pid, então dá para verificar se o
164
+ processo realmente morreu em vez de apagar no escuro:
165
+
166
+ ```bash
167
+ cat .git/spec-wave/run-<n>.lock # {"pid":NNNN,"startedAt":"..."}
168
+ ps -p NNNN >/dev/null && echo VIVO || echo morto
169
+ rm .git/spec-wave/run-<n>.lock # só se morto
170
+ ```
171
+
172
+ O cuidado importa quando você rodou várias Features: pode haver um lock órfão e outro de um
173
+ run **em andamento** ao lado. Apagar o lock errado põe dois `run` na mesma issue.
174
+
175
+ A boa notícia é que a interrupção em si é limpa — o documento não é publicado pela metade.
176
+ Confirme com a ausência de PR novo antes de rerodar.
177
+
178
+ ## 12. O documento foi gerado e o PR não nasceu
179
+
180
+ **Sintoma:** o passo termina, o commit existe na branch `spec-wave/<n>-<doc>` — e nenhum PR
181
+ aparece. O documento fica numa branch que ninguém está olhando, e a próxima execução, se
182
+ ninguém perceber, **regera por cima**.
183
+
184
+ **Causa:** a publicação precisa de `pull-requests: write` **e** de a organização permitir
185
+ que Actions abram PRs. A segunda parte é a traiçoeira: *"Allow GitHub Actions to create and
186
+ approve pull requests"* (Settings → Actions → General) vem desligada por padrão em muitas
187
+ organizações, e o erro não se parece com falta de permissão.
188
+
189
+ **Como resolver:** ligar a opção, ou definir um PAT no secret `GH_PR_TOKEN`. O `preflight`
190
+ e o `doctor` verificam os dois; o estado `⚠ em branch sem PR` no inventário é exatamente
191
+ este caso.
192
+
193
+ Não se aplica ao modo `local`, onde o token é o seu.
194
+
195
+ ---
196
+
197
+ ## Nota histórica: o regime anterior à 0.27.0
198
+
199
+ Até a 0.26.0 a geração publicava com `commit` + `pull --rebase` + `push` **na branch
200
+ default**, a partir do checkout. Duas armadilhas vinham daí e **não valem mais**:
201
+
202
+ - **push rejeitado com `GH013`** em repositório que exige PR — a falha vinha *depois* de o
203
+ modelo ter gerado o documento, e o conteúdo se perdia com o runner;
204
+ - **working tree sujo quebrava toda geração local**, porque qualquer arquivo modificado
205
+ travava o `pull --rebase`.
206
+
207
+ Hoje a publicação é por API, em branch própria por documento, sem tocar no checkout. Se o
208
+ `preflight` apontar uma CLI antiga fixada nos workflows, as duas voltam a valer — e a
209
+ saída é `npx @spec-wave/cli@latest update --branch`.
@@ -0,0 +1,110 @@
1
+ # Fase 3 — revisão de conteúdo
2
+
3
+ O gerador escreve cada spec isoladamente, a partir do corpo de uma issue. Ele é bom nisso:
4
+ as seções vêm completas, os requisitos rastreados, os fluxos coerentes **dentro** do
5
+ documento. O que ele estruturalmente não consegue ver é a relação entre os documentos —
6
+ porque, quando escreveu o primeiro, os outros não existiam.
7
+
8
+ É exatamente aí que moram os problemas que custam caro depois. Por isso a regra desta fase:
9
+ **leia as specs como conjunto, não uma a uma.**
10
+
11
+ ## Como ler
12
+
13
+ Leia todas na íntegra antes de julgar qualquer uma. Ao ler a quinta, você reconhece na
14
+ primeira uma contradição que era invisível quando ela era o único documento.
15
+
16
+ Vale montar, enquanto lê, um mapa mental de três coisas:
17
+
18
+ - **regras compartilhadas** — um teto, uma ordem de prioridade, uma janela de tempo que
19
+ aparece em mais de uma feature;
20
+ - **quem depende de quem** — e em que direção cada spec declara a dependência;
21
+ - **afirmações sobre o mundo** — "tal feature ainda não existe", "isso é feito por X".
22
+
23
+ As três classes de problema abaixo saem desse mapa.
24
+
25
+ ## Classe 1 — contradição entre specs
26
+
27
+ Duas features descrevem a mesma regra de formas que não fecham: contagens diferentes,
28
+ prioridades diferentes, a mesma janela de tempo medida a partir de marcos diferentes.
29
+
30
+ Isso é grave porque cada spec, sozinha, parece certa. O erro só existe no par — e vira dois
31
+ comportamentos incompatíveis em produção, descobertos na integração.
32
+
33
+ Ao encontrar, verifique qual das duas está alinhada com a fonte normativa (o corpo da issue,
34
+ o documento de requisitos) antes de propor a correção. Frequentemente uma está certa e a
35
+ outra derivou.
36
+
37
+ ## Classe 2 — dependência que não fecha
38
+
39
+ Três formatos, todos vistos de verdade:
40
+
41
+ **Aponta para algo que não existe.** A feature A declara que seu componente vive na feature
42
+ B, e a spec de B não menciona esse componente em lugar nenhum. Alguém vai descobrir isso na
43
+ implementação, quando já for caro.
44
+
45
+ **Direção invertida ou circular.** A declara depender de B enquanto B declara depender de A.
46
+ Uma spec bem gerada às vezes corrige isso sozinha e **documenta a correção** — quando vir
47
+ uma nota dessas, confira se a outra ponta concorda.
48
+
49
+ **Inversão de sequenciamento entre milestones.** A dependência bloqueante está numa
50
+ milestone que vence *depois* da que depende dela. Não é erro de spec — é erro de
51
+ planejamento que só aparece quando se olha as datas junto com as dependências. Levante
52
+ sempre, porque ninguém mais vai olhar para os dois ao mesmo tempo.
53
+
54
+ **Como verificar de forma barata:** `spec-wave audit --milestone <nome>` cruza as
55
+ seções de Dependências de todas as specs e acusa ciclo, inversão de milestone,
56
+ referência sem alvo e sobreposição com código (Fase 3.5 da skill). O que sobra
57
+ para o olho é a parte semântica: a outra ponta concorda com a direção e o
58
+ escopo do que foi declarado?
59
+
60
+ ## Classe 3 — afirmação que a própria rodada tornou falsa
61
+
62
+ Esta é sutil e específica de gerar várias specs de uma vez: a spec gerada às 10h afirma
63
+ "tal feature ainda não possui spec" e às 10h20 essa spec passa a existir — gerada pela
64
+ mesma rodada.
65
+
66
+ **Cuidado ao corrigir:** a mesma frase costuma aparecer várias vezes no documento, sobre
67
+ alvos diferentes, e só algumas ficaram obsoletas. Verifique alvo por alvo antes de editar.
68
+ Corrigir por padrão de texto transforma afirmação verdadeira em falsa.
69
+
70
+ E note *como* corrigir: quando a afirmação obsoleta era a **justificativa** de um TODO, a
71
+ pergunta não desaparece — ela muda de razão. Reescreva a justificativa apontando onde a
72
+ questão vive agora, em vez de apagar a frase e deixar o TODO sem explicação.
73
+
74
+ ## Também procure
75
+
76
+ - **Sobreposição com feature já entregue.** Se uma spec descreve algo que uma feature
77
+ fechada já faz, há risco de duplicar comportamento em produção. Confira o estado da issue
78
+ antiga — "fechada" muda a conversa de "coordenar" para "não quebrar o que existe".
79
+ - **Regra que contradiz outra regra da mesma spec.** Raro, mas acontece quando uma regra é
80
+ categórica ("nunca expor dado individual") e outra define um recorte fino o bastante para
81
+ violá-la na prática. Vale destacar: costuma ser o achado de maior severidade.
82
+ - **Parâmetro declarado como "definido previamente" que ninguém definiu.** Limiares, prazos,
83
+ número de tentativas. Individualmente parecem detalhe; juntos costumam ser uma decisão só,
84
+ sem dono.
85
+
86
+ ## Como classificar o que encontrou
87
+
88
+ **Achado material** — muda o desenho de uma feature, ou tem risco em produção. Vai como
89
+ comentário na issue correspondente, contendo: a regra que o originou (citada), por que não
90
+ se resolve no `plan`, e a decisão necessária. Se o achado tem dois lados (duas features
91
+ discordando), comente **nos dois**, apontando um para o outro — quem abrir só uma issue
92
+ precisa enxergar o quadro inteiro.
93
+
94
+ **Lacuna paramétrica** — falta um número. Não bloqueia o `plan`. Agrupe por tema no
95
+ relatório final: doze lacunas espalhadas costumam ser seis decisões, e uma lista de doze
96
+ itens soltos não é acionável.
97
+
98
+ O teste para separar as duas: *se ninguém decidir isso, o que acontece?* Se a resposta é
99
+ "implementam errado" ou "duas partes se comportam de formas incompatíveis", é material. Se
100
+ é "implementam com um valor provisório e ajustam depois", é paramétrico.
101
+
102
+ ## O que não fazer
103
+
104
+ Não reescreva a spec para consertar o que encontrou. A spec é registro do que foi gerado a
105
+ partir da fonte normativa; a correção de regra é decisão do PO, e o lugar dela é a issue.
106
+ Editar o documento direto faz a decisão parecer tomada — e ninguém consegue rastrear quem
107
+ a tomou.
108
+
109
+ A exceção é o erro factual puro (Classe 3), que não é decisão de ninguém — e, mesmo aí,
110
+ só com pedido explícito do usuário.
@@ -16,6 +16,9 @@ Atualiza **somente o que divergiu** da versão da CLI: a **skill** instalada (po
16
16
  | `--skip-skill` | Não verifica/atualiza a skill instalada. |
17
17
  | `--skip-config` | Não verifica/atualiza o `.spec-wave.json`. |
18
18
  | `--skip-repo` | Não verifica/atualiza workflows e labels do repo. |
19
+ | `--branch [nome]` | Envia os arquivos do repo como **Pull Request** numa branch, em um único commit (sem valor: `spec-wave/update-v<versão>`). |
20
+ | `--config-in-pr` / `--no-config-in-pr` | Força incluir/excluir o `.spec-wave.json` do PR. |
21
+ | `--skill-in-pr` / `--no-skill-in-pr` | Força incluir/excluir a skill dos agentes do PR. |
19
22
  | `--dry-run` | Mostra o que seria atualizado sem alterar nada. |
20
23
  | `--yes` | Aplica sem pedir confirmação. |
21
24
 
@@ -28,15 +31,18 @@ Atualiza **somente o que divergiu** da versão da CLI: a **skill** instalada (po
28
31
 
29
32
  2. Mostre ao usuário o resumo por categoria (skill / config / arquivos do repo / labels). Se **nada** divergiu, informe que já está tudo na versão atual e encerre.
30
33
 
31
- 3. Com a aprovação, aplique:
34
+ 3. Com a aprovação, aplique — e **prefira o Pull Request**:
32
35
  ```bash
33
- npx @spec-wave/cli@latest update --yes
36
+ npx @spec-wave/cli@latest update --yes --branch # 1 commit atômico + PR (recomendado)
37
+ npx @spec-wave/cli@latest update --yes # commits diretos na branch default
34
38
  ```
35
39
  Limite o escopo com `--skip-skill`, `--skip-config` ou `--skip-repo` se o usuário só quiser parte.
36
40
 
37
41
  4. **Onde cada coisa aterrissa:**
38
- - **arquivos do repo** (workflows, labels) commitados no remoto pelo comando
39
- - **`.spec-wave.json`**arquivo **local**; lembre o usuário de commitá-lo
42
+ - **workflows e templates de issue** → no PR (com `--branch`) ou commitados direto na branch default
43
+ - **labels**sempre direto na base: são metadado do repositório, não há como versioná-las
44
+ - **`.spec-wave.json` e a skill** → o comando **consulta a base** e vai pelo mesmo caminho do arquivo: se o repositório já versiona aquele caminho, a atualização entra no PR; se não versiona, fica só local e o usuário precisa commitá-la. Force com `--config-in-pr` / `--skill-in-pr` se o projeto quiser passar a versionar.
45
+ - a skill é gravada em disco nos dois casos — é a cópia que o agente carrega
40
46
 
41
47
  5. Se a skill foi atualizada, oriente a **recarregar/reiniciar o agente** para pegar a nova versão.
42
48
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: spec-wave-workflow
3
- description: "Use quando a pergunta for sobre o fluxo spec-wave como um todo — qual é a próxima etapa de uma issue, o que cada coluna do Kanban significa, quais labels disparam quais Actions, como funciona a crítica adversarial, ou quando o usuário pedir spec-wave sem dizer qual comando. É o mapa do processo RFC-001; para executar uma ação específica, use a skill do comando correspondente (setup, issue, spec, plan, ready, decompose, implement, order, task, story, move, doctor, update, info, uninstall, rfc, fix-pr)."
3
+ description: "Use quando a pergunta for sobre o fluxo spec-wave como um todo — qual é a próxima etapa de uma issue, o que cada coluna do Kanban significa, quais labels disparam quais Actions, como funciona a crítica adversarial, ou quando o usuário pedir spec-wave sem dizer qual comando. É o mapa do processo RFC-001; para executar uma ação específica, use a skill do comando correspondente (setup, issue, spec, plan, ready, decompose, run, bug, triage, implement, order, task, story, move, doctor, update, info, uninstall, rfc, fix-pr); para conduzir um trecho inteiro do fluxo de uma vez, preparar-feature (uma Feature até Ready) ou preparar-specs (as specs de uma milestone)."
4
4
  allowed-tools:
5
5
  - Bash(npx @spec-wave/cli@latest *)
6
6
  - Bash(gh issue *)
@@ -148,6 +148,11 @@ O slug vem do **título**: `[FEATURE] Cadastro de Pedidos com PIX` → `cadastro
148
148
  | gerar o plano técnico | `plan` |
149
149
  | validar spec+plan | `ready` |
150
150
  | quebrar em Stories/Tasks | `decompose` |
151
+ | levar uma Feature da spec até ✅ Ready, de ponta a ponta | `preparar-feature` |
152
+ | gerar as specs de uma milestone inteira | `preparar-specs` |
153
+ | rodar o fluxo localmente / desarmar os workflows | `run` |
154
+ | registrar ou corrigir um Bug | `bug` |
155
+ | triar um Bug | `triage` |
151
156
  | implementar | `implement` |
152
157
  | ver ordem das Stories | `order` |
153
158
  | mover Task | `task` |
@@ -40,3 +40,16 @@ existing_services:
40
40
  internal_libraries:
41
41
  - "shared-logger"
42
42
  - "db-client (TypeORM)"
43
+
44
+ # Decisões de modelagem de recursos COMPARTILHADOS entre features (opcional).
45
+ #
46
+ # `criada_por:` é obrigatório em cada entrada: a Feature que cria o recurso
47
+ # (ex.: "FT-01.7" ou "#42"), ou o literal SEM DONO enquanto ninguém o criar.
48
+ # "Não existe feature para editar esses valores" escrito em prosa fica meses
49
+ # sem ninguém agir; SEM DONO aparece no `spec-wave audit` como pendência de
50
+ # checklist antes de planejar a milestone.
51
+ #
52
+ # decisoes_de_modelagem:
53
+ # - recurso: "custo_canal"
54
+ # decisao: "Tabela própria; valores editados por ADMIN, consumidos por 4 features"
55
+ # criada_por: "SEM DONO"
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: spec-wave
3
3
  description: "Use when the user wants to set up a spec-driven GitHub workflow, create a Feature issue, generate spec.md or plan.md, decompose a Feature into Stories/Tasks, write RFC documentation, or audit and fix a Pull Request. Implements the RFC-001 workflow with GitHub Projects v2, labels, and AI-powered GitHub Actions."
4
- argument-hint: "[info|setup|update|doctor|issue|feature|spec|plan|ready|decompose|order|implement|task|story|move|uninstall|rfc|bug|triage|fix-pr] [target]"
4
+ argument-hint: "[info|setup|update|doctor|preflight|audit|issue|feature|spec|plan|ready|decompose|order|implement|merge|task|story|move|uninstall|rfc|bug|triage|fix-pr] [target]"
5
5
  user-invocable: true
6
6
  allowed-tools:
7
7
  - Bash(npx @spec-wave/cli@latest *)
@@ -77,7 +77,7 @@ npx @spec-wave/cli@latest mode # estado atual dos dois lados do
77
77
  npx @spec-wave/cli@latest mode local # desarma os workflows
78
78
  npx @spec-wave/cli@latest run <issue> --dry-run # explica o próximo passo sem executar
79
79
  npx @spec-wave/cli@latest run <issue> # executa
80
- npx @spec-wave/cli@latest run --pr <n> # code-review (+ qa, se houver aprovação)
80
+ npx @spec-wave/cli@latest run --pr <n> # code-review (+ qa, se aprovado OU mergeado)
81
81
  ```
82
82
 
83
83
  O `run` decide o passo pelo estado da issue (documentos existentes + labels), respeita os portões humanos (`needs-human`, `critique-failed`), recusa rodar com uma label de gatilho pendente e **exige `--apply`** para o `decompose-apply`, que cria issues. Sempre mostre o `--dry-run` ao usuário antes de executar.
@@ -208,6 +208,7 @@ Mesmas flags do `issue` (exceto `--type`, fixo em `feature`). Mantido para o flu
208
208
  | `--skip-skill` / `--skip-config` / `--skip-repo` | flag | Pula a categoria correspondente. |
209
209
  | `--branch [nome]` | flag/string | Envia os arquivos do repo como **Pull Request** numa branch, em **um único commit**, em vez de commitar direto na branch default. Sem valor, usa `spec-wave/update-v<versão>`. |
210
210
  | `--config-in-pr` / `--no-config-in-pr` | flag | Força incluir/excluir o `.spec-wave.json` do PR (o default decide sozinho — veja abaixo). |
211
+ | `--skill-in-pr` / `--no-skill-in-pr` | flag | Força incluir/excluir a **skill dos agentes** do PR (o default decide sozinho — veja abaixo). |
211
212
  | `--dry-run` | flag | Mostra o que seria atualizado sem alterar nada. |
212
213
  | `--yes` | flag | Aplica sem pedir confirmação. |
213
214
 
@@ -215,7 +216,9 @@ Mesmas flags do `issue` (exceto `--type`, fixo em `feature`). Mantido para o flu
215
216
 
216
217
  > **`--branch` (modo Pull Request).** Sem a flag, os arquivos do repo vão em **commits diretos na branch default** — o que falha no meio da execução em repositório com proteção de branch, deixando parte aplicada, e contorna a revisão. Com a flag, todos os arquivos vão em **um commit atômico** numa branch nova e um PR é aberto: se algo falhar antes da criação da branch, **nada** é alterado no repositório. É **idempotente** — rodar duas vezes não gera um segundo commit nem um segundo PR.
217
218
  >
218
- > Duas coisas **não** entram no PR, porque não são versionáveis: as **labels** (metadado do repositório — já valem na base, com ou sem merge) e a **skill** (arquivo em máquina local). O corpo do PR diz isso explicitamente a quem revisa.
219
+ > As **labels** nunca entram no PR: são metadado do repositório, não como versioná-las — já valem na base, com ou sem o merge. O corpo do PR diz isso a quem revisa.
220
+ >
221
+ > A **skill** e o **`.spec-wave.json`** seguem a mesma regra, e ela é **verificada, não presumida**: o comando pergunta à base se aquele arquivo já é versionado. Se for (repos que commitam `.claude/skills/spec-wave/SKILL.md`, `.agents/skills/`, `AGENTS.md`, `.cursor/rules/…`), a atualização entra no PR junto com os workflows; se não for, fica só na máquina local. Passar a versionar (ou deixar de versionar) é decisão do projeto — use `--skill-in-pr` / `--no-skill-in-pr` para forçar.
219
222
  >
220
223
  > ⚠️ O modo PR exige **`pull_requests: write`** além de `contents: write` (ou o escopo `repo` num PAT classic). Sem essa permissão, a branch é criada e o PR falha — a mensagem oferece a URL de `compare` para abrir à mão.
221
224
 
@@ -250,7 +253,33 @@ Sem flags. Roda um checklist de diagnóstico no repositório atual: token GitHub
250
253
  |----------|------|-----------|
251
254
  | `<feature>` | string (obrigatório) | Número da issue da **Feature**, ex.: `12` ou `#12`. Argumento posicional. |
252
255
 
253
- > **Sem argumento**, monta o mapa de TODAS as Features abertas fora de 🎉 Done num grafo só (conjunto vindo do board), com a Feature de cada Story ao lado — nesse escopo a dependência entre Features entra na ordenação. Com `<feature>`, lista as Stories da Feature em **ordem topológica** pelas dependências (linha `Depende de: #N` no corpo + relação nativa *blocked by*, mescladas), com a Etapa atual de cada uma no board. Dependências para **fora da Feature** não entram na ordenação (não há como saber onde a Story de outra Feature entra nesta sequência), mas aparecem em **"Bloqueadas por fora desta Feature"**, com o estado de cada bloqueadora. Avisa sobre **ciclos de dependência** (essas Stories ficam fora da ordem — corrija as linhas `Depende de`) e sobre **dependências fora de ordem** (Story já em Desenvolvimento+ dependendo de outra que não está Done). Use antes de escolher qual Story implementar.
256
+ > **Sem argumento**, monta o mapa de TODAS as Features abertas fora de 🎉 Done num grafo só (conjunto vindo do board), com a Feature de cada Story ao lado — nesse escopo a dependência entre Features entra na ordenação. Com `<feature>`, lista as Stories da Feature em **ordem topológica** pelas dependências (linha `Depende de: #N` no corpo + relação nativa *blocked by*, mescladas), com a Etapa atual de cada uma no board. Dependências para **fora da Feature** não entram na ordenação (não há como saber onde a Story de outra Feature entra nesta sequência), mas aparecem em **"Bloqueadas por fora desta Feature"**, com o estado de cada bloqueadora. Avisa sobre **ciclos de dependência** (essas Stories ficam fora da ordem — corrija as linhas `Depende de`), sobre **dependências fora de ordem** (Story já em Desenvolvimento+ dependendo de outra que não está Done) e sobre **milestone divergente** (Story sem milestone ou em milestone diferente do da Feature — órfã de toda visão de release; sem milestone na Feature, nada é comparado). Use antes de escolher qual Story implementar, e logo após o `decompose --apply` como detector do pós-apply.
257
+
258
+ ### `@spec-wave/cli preflight --milestone <nome>` — confere tudo ANTES de gerar as specs (comando LOCAL)
259
+ | Flag/Arg | Tipo | Descrição |
260
+ |----------|------|-----------|
261
+ | `--milestone <nome>` | string (obrigatório) | Título da milestone a inventariar. |
262
+ | `--json` | boolean | O relatório em JSON, para ramificar. |
263
+
264
+ > Um comando reporta: token utilizável, modo de execução (config × variável do repositório), publicação por PR, e as Features da milestone com o **estado do `spec.md` de cada uma** (na base, no disco, em PR aberto, em branch sem PR, a gerar). Existe porque **cada geração paga um modelo**: um erro de configuração descoberto na sétima Feature custa sete gerações — e regenerar um documento que já vive num PR descarta a revisão em curso. Sai com código 1 quando há bloqueio. Rode SEMPRE antes de uma rodada de specs por milestone.
265
+
266
+ ### `@spec-wave/cli audit --milestone <nome>` — cruza as specs da milestone como CONJUNTO (comando LOCAL)
267
+ | Flag/Arg | Tipo | Descrição |
268
+ |----------|------|-----------|
269
+ | `--milestone <nome>` | string (obrigatório) | Título da milestone a auditar. |
270
+ | `--critique` | boolean | Roda também a **crítica adversarial de conjunto** — UMA chamada de modelo sobre todas as specs juntas, procurando contradição ENTRE documentos. |
271
+ | `--json` | boolean | O relatório em JSON (com `critica.markdown` pronto para comentar nas issues). |
272
+
273
+ > A crítica normal audita cada documento contra os insumos da **mesma** Feature; este comando olha o que só existe **no par**: dependência circular entre Features, bloqueante em milestone **posterior** à de quem depende dela, referência a issue inexistente (materiais — exit 1), dependência que nenhuma Feature cria ("recurso sem dono"), sobreposição do slug com código existente e decisão de modelagem com `criada_por: SEM DONO` no `tech_context.yml` (avisos heurísticos — **confira antes de reportar**). Rode depois que as specs existirem (PR aberto também conta), antes de gerar os planos. Achado material é decisão de PO: comente nas issues **dos dois lados**.
274
+
275
+ ### `@spec-wave/cli merge <feature>` — mergeia os PRs empilhados das Stories (comando LOCAL)
276
+ | Flag/Arg | Tipo | Descrição |
277
+ |----------|------|-----------|
278
+ | `<feature>` | string (obrigatório) | Número da issue da **Feature**, ex.: `12` ou `#12`. |
279
+ | `--yes` | boolean | Executa os merges. **Sem ela, só mostra o plano** (fila na ordem, retargets, avisos). |
280
+ | `--keep-branches` | boolean | Não apaga as branches das Stories após o merge. |
281
+
282
+ > O `implement` empilha os PRs (cada um baseado no anterior) e o merge da pilha é **ordem-dependente**: `--delete-branch` no primeiro PR fecha o segundo. Este comando encapsula a sequência segura — para cada PR na ordem topológica das Stories: reaponta a base para a default, mergeia com **merge commit**, atualiza o board (**merge move até 🧪 QA**) e **só no fim** apaga as branches. **PR em rascunho bloqueia o plano inteiro** (marcar pronto é a revisão humana — o comando não pula isso). Rodar de novo **retoma**: PR mergeado sai do plano. Use após a revisão, em vez de mergear à mão com `gh`.
254
283
 
255
284
  ### `@spec-wave/cli task <start|done> <n>` — transições de Task no board (comando LOCAL)
256
285
  | Flag/Arg | Tipo | Descrição |
@@ -459,8 +488,8 @@ Traz tudo para a versão atual da CLI, atualizando **só o que mudou**: a skill
459
488
  - Escopos podem ser limitados com `--skip-skill`, `--skip-config`, `--skip-repo`.
460
489
  - **Com `--branch`:** os arquivos do repo vão em **um único commit** numa branch nova e um PR é aberto — nada é escrito na branch default. Passe o link do PR ao usuário e lembre que o merge é dele. Exige `pull_requests: write` no token.
461
490
  - **Sem `--branch`:** cada arquivo é um commit direto na branch default. Em repositório com **proteção de branch** isso falha no meio e deixa parte aplicada — nesses casos use `--branch`.
462
- - **Nos dois modos**, as **labels** são aplicadas direto na base (metadado do repositório, não versionável) e a **skill** é gravada em máquina local. Nenhuma das duas entra no PR.
463
- - **`.spec-wave.json`:** com `--branch`, ele entra no PR se o repositório **já o versiona**; se não versiona, segue apenas local e o usuário precisa commitá-lo (ou use `--config-in-pr` para passar a versioná-lo). Sem `--branch`, é sempre só local.
491
+ - **Nos dois modos**, as **labels** são aplicadas direto na base (metadado do repositório, não versionável) e nunca entram no PR.
492
+ - **`.spec-wave.json` e skill:** com `--branch`, cada um entra no PR se o repositório **já o versiona** (o comando consulta a base, arquivo a arquivo); se não versiona, segue apenas local e o usuário precisa commitá-lo ou use `--config-in-pr` / `--skill-in-pr` para passar a versioná-lo. Sem `--branch`, os dois são sempre só locais. A skill é gravada em disco de qualquer forma, para o agente já pegar a versão nova.
464
493
  4. Se a skill foi atualizada, oriente recarregar/reiniciar o agente para pegar a nova versão.
465
494
 
466
495
  ---
@@ -689,7 +718,7 @@ Aciona o spec-kit para implementar uma **Feature** (todas as Stories pendentes,
689
718
  - Se o spec-kit **não** estiver configurado, o comando só monta o contexto e mostra como configurar (`specKit.command` / `SPEC_WAVE_IMPLEMENT_CMD`). Ajude o usuário a definir o template (placeholders: `{tasksFile} {specFile} {planFile} {issue} {type} {title}`).
690
719
  - Use `--feature-dir docs/features/<slug>` se a resolução automática da Feature falhar (a skill avisa com warning) e você quiser anexar `spec.md`/`plan.md` como contexto.
691
720
  6. **No modo Feature**, siga o contexto Story a Story, na ordem listada: para cada Story pendente, implemente as Tasks com `task start`/`task done`, depois commit + PR + `npx @spec-wave/cli@latest story review <n>`; só então passe à próxima Story. **Bug** tem modo próprio (RFC-004): sem tasks e sem spec/plan, com quatro fases — reproduzir → causa raiz → fix mínimo → teste de regressão — e o `bug.md` entrando como hipótese a confirmar. Se a issue não for Feature, Story, Task nem Bug (ex.: Spike, Epic), o comando recusa. Feature **sem Stories** → rode `/spec-wave decompose` primeiro. **Ciclo de dependências** → corrija as linhas `Depende de:` (veja `spec-wave order`).
692
- 7. Ao final (Tasks em **🎉 Done**, Story em **👀 Code Review**; a Feature só vai para Code Review quando a última Story concluir — no modo Feature, isso acontece dentro da mesma execução): confirme o resultado com o usuário e oriente a revisão dos PRs.
721
+ 7. Ao final (Tasks em **🎉 Done**, Story em **👀 Code Review**; a Feature só vai para Code Review quando a última Story concluir — no modo Feature, isso acontece dentro da mesma execução): confirme o resultado com o usuário e oriente a revisão dos PRs. **Avise que os PRs estão empilhados** e que o merge é ordem-dependente: depois da revisão (PRs marcados prontos), o caminho é `npx @spec-wave/cli@latest merge <feature>` — nunca `gh pr merge --delete-branch` à mão em PR de pilha.
693
722
 
694
723
  ---
695
724
 
@@ -1,8 +1,14 @@
1
1
  name: QA
2
2
 
3
+ # Dois gatilhos, um destino: aprovação formal OU merge movem a Feature para
4
+ # 🧪 QA. O de merge existe porque o autor não consegue aprovar o próprio PR —
5
+ # num fluxo solo, QA por aprovação nunca aconteceria — e porque homologação de
6
+ # verdade começa com o código integrado. Espelha o `run --pr` do modo local.
3
7
  on:
4
8
  pull_request_review:
5
9
  types: [submitted]
10
+ pull_request:
11
+ types: [closed]
6
12
 
7
13
  concurrency:
8
14
  group: spec-wave-qa-${{ github.event.pull_request.number }}
@@ -25,10 +31,12 @@ jobs:
25
31
  # Aqui a guarda é INDISPENSÁVEL, não defensiva: `pull_request_review`
26
32
  # dispara por uma aprovação HUMANA, independentemente de quem abriu o
27
33
  # PR. Aprovar o PR da spec moveria a Feature para 🧪 QA.
34
+ # A última linha aceita os dois eventos: review aprovada (pull_request_review)
35
+ # ou PR fechado COM merge (pull_request closed — fechado sem merge não conta).
28
36
  if: >
29
37
  vars.SPEC_WAVE_EXECUTION != 'local' &&
30
38
  !startsWith(github.event.pull_request.head.ref, 'spec-wave/') &&
31
- github.event.review.state == 'approved'
39
+ (github.event.review.state == 'approved' || github.event.pull_request.merged == true)
32
40
  runs-on: ubuntu-latest
33
41
  permissions:
34
42
  issues: write