@spec-wave/cli 0.26.0 → 0.28.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.
- package/package.json +1 -1
- package/src/api/github-rest.mjs +52 -0
- package/src/cli.mjs +12 -0
- package/src/commands/decompose.mjs +166 -39
- package/src/commands/doctor.mjs +214 -3
- package/src/commands/generate-bug.mjs +22 -16
- package/src/commands/generate-plan.mjs +72 -23
- package/src/commands/generate-spec.mjs +19 -15
- package/src/commands/implement.mjs +47 -22
- package/src/commands/install-skill.mjs +18 -8
- package/src/commands/preflight.mjs +322 -0
- package/src/commands/run.mjs +51 -30
- package/src/commands/update.mjs +143 -12
- package/src/commands/validate.mjs +84 -17
- package/src/config.mjs +18 -0
- package/src/lib/artifact-pr.mjs +272 -0
- package/src/lib/artifact-publish.mjs +169 -0
- package/src/lib/doc-availability.mjs +23 -1
- package/src/lib/doc-source.mjs +162 -0
- package/src/lib/flow-run.mjs +9 -218
- package/src/lib/next-step.mjs +27 -4
- package/src/lib/pr-branch.mjs +106 -7
- package/src/lib/repo-links.mjs +8 -2
- package/src/plugin/.claude-plugin/plugin.json +1 -1
- package/src/plugin/README.md +5 -0
- package/src/plugin/skills/bug/SKILL.md +2 -2
- package/src/plugin/skills/decompose/SKILL.md +4 -4
- package/src/plugin/skills/plan/SKILL.md +1 -1
- package/src/plugin/skills/preparar-feature/SKILL.md +245 -0
- package/src/plugin/skills/preparar-feature/reference/critica.md +88 -0
- package/src/plugin/skills/preparar-specs/SKILL.md +171 -0
- package/src/plugin/skills/preparar-specs/reference/armadilhas.md +209 -0
- package/src/plugin/skills/preparar-specs/reference/revisao.md +107 -0
- package/src/plugin/skills/run/SKILL.md +3 -1
- package/src/plugin/skills/spec/SKILL.md +4 -4
- package/src/plugin/skills/update/SKILL.md +10 -4
- package/src/plugin/skills/workflow/SKILL.md +8 -3
- package/src/templates/skill/SKILL.md +13 -10
- package/src/templates/workflows/code-review.yml +13 -2
- package/src/templates/workflows/critique.yml +1 -1
- package/src/templates/workflows/decompose.yml +13 -2
- package/src/templates/workflows/generate-bug.yml +17 -6
- package/src/templates/workflows/generate-plan.yml +20 -7
- package/src/templates/workflows/generate-spec.yml +20 -7
- package/src/templates/workflows/qa.yml +13 -0
|
@@ -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,107 @@
|
|
|
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:** para cada dependência declarada, confira se o
|
|
55
|
+
diretório/arquivo existe e se a outra ponta concorda com a direção e o escopo.
|
|
56
|
+
|
|
57
|
+
## Classe 3 — afirmação que a própria rodada tornou falsa
|
|
58
|
+
|
|
59
|
+
Esta é sutil e específica de gerar várias specs de uma vez: a spec gerada às 10h afirma
|
|
60
|
+
"tal feature ainda não possui spec" e às 10h20 essa spec passa a existir — gerada pela
|
|
61
|
+
mesma rodada.
|
|
62
|
+
|
|
63
|
+
**Cuidado ao corrigir:** a mesma frase costuma aparecer várias vezes no documento, sobre
|
|
64
|
+
alvos diferentes, e só algumas ficaram obsoletas. Verifique alvo por alvo antes de editar.
|
|
65
|
+
Corrigir por padrão de texto transforma afirmação verdadeira em falsa.
|
|
66
|
+
|
|
67
|
+
E note *como* corrigir: quando a afirmação obsoleta era a **justificativa** de um TODO, a
|
|
68
|
+
pergunta não desaparece — ela muda de razão. Reescreva a justificativa apontando onde a
|
|
69
|
+
questão vive agora, em vez de apagar a frase e deixar o TODO sem explicação.
|
|
70
|
+
|
|
71
|
+
## Também procure
|
|
72
|
+
|
|
73
|
+
- **Sobreposição com feature já entregue.** Se uma spec descreve algo que uma feature
|
|
74
|
+
fechada já faz, há risco de duplicar comportamento em produção. Confira o estado da issue
|
|
75
|
+
antiga — "fechada" muda a conversa de "coordenar" para "não quebrar o que existe".
|
|
76
|
+
- **Regra que contradiz outra regra da mesma spec.** Raro, mas acontece quando uma regra é
|
|
77
|
+
categórica ("nunca expor dado individual") e outra define um recorte fino o bastante para
|
|
78
|
+
violá-la na prática. Vale destacar: costuma ser o achado de maior severidade.
|
|
79
|
+
- **Parâmetro declarado como "definido previamente" que ninguém definiu.** Limiares, prazos,
|
|
80
|
+
número de tentativas. Individualmente parecem detalhe; juntos costumam ser uma decisão só,
|
|
81
|
+
sem dono.
|
|
82
|
+
|
|
83
|
+
## Como classificar o que encontrou
|
|
84
|
+
|
|
85
|
+
**Achado material** — muda o desenho de uma feature, ou tem risco em produção. Vai como
|
|
86
|
+
comentário na issue correspondente, contendo: a regra que o originou (citada), por que não
|
|
87
|
+
se resolve no `plan`, e a decisão necessária. Se o achado tem dois lados (duas features
|
|
88
|
+
discordando), comente **nos dois**, apontando um para o outro — quem abrir só uma issue
|
|
89
|
+
precisa enxergar o quadro inteiro.
|
|
90
|
+
|
|
91
|
+
**Lacuna paramétrica** — falta um número. Não bloqueia o `plan`. Agrupe por tema no
|
|
92
|
+
relatório final: doze lacunas espalhadas costumam ser seis decisões, e uma lista de doze
|
|
93
|
+
itens soltos não é acionável.
|
|
94
|
+
|
|
95
|
+
O teste para separar as duas: *se ninguém decidir isso, o que acontece?* Se a resposta é
|
|
96
|
+
"implementam errado" ou "duas partes se comportam de formas incompatíveis", é material. Se
|
|
97
|
+
é "implementam com um valor provisório e ajustam depois", é paramétrico.
|
|
98
|
+
|
|
99
|
+
## O que não fazer
|
|
100
|
+
|
|
101
|
+
Não reescreva a spec para consertar o que encontrou. A spec é registro do que foi gerado a
|
|
102
|
+
partir da fonte normativa; a correção de regra é decisão do PO, e o lugar dela é a issue.
|
|
103
|
+
Editar o documento direto faz a decisão parecer tomada — e ninguém consegue rastrear quem
|
|
104
|
+
a tomou.
|
|
105
|
+
|
|
106
|
+
A exceção é o erro factual puro (Classe 3), que não é decisão de ninguém — e, mesmo aí,
|
|
107
|
+
só com pedido explícito do usuário.
|
|
@@ -50,13 +50,15 @@ O comando **explica e para**, saindo com código 2. Não force sem entender:
|
|
|
50
50
|
- **`trigger-pending`** — há label de gatilho na issue: um Action está em voo (ou falhou deixando-a). Rodar por cima duplicaria documento e comentário. `--force` fura, quando você tem certeza.
|
|
51
51
|
- **`needs-human` / `critique-failed`** — portões humanos da crítica. O caminho é corrigir o documento e remover a label; para o `critique-failed` o passo de retomada é **re-criticar**, nunca regerar.
|
|
52
52
|
- **`stale-checkout`** — o documento existe no repositório e não no seu clone. `git pull` e repita; seguir sobrescreveria o que já foi publicado.
|
|
53
|
+
- **`pr-pending`** — o documento foi gerado e está num **Pull Request ainda não mergeado**. Revise o PR (edite ali mesmo, se precisar) e faça o merge; o passo seguinte lê o documento da branch base. Rodar por cima regeraria o arquivo, descartando a revisão e pagando a IA de novo.
|
|
54
|
+
- **`branch-without-pr`** — o documento foi commitado numa branch `spec-wave/*` e **nenhum PR foi aberto** para ela. Quase sempre a abertura do PR falhou: opção *"Allow GitHub Actions to create and approve pull requests"* desligada, ou secret `GH_PR_TOKEN` ausente. Rode `spec-wave doctor`, corrija e abra o PR — reaplicar o gatilho **regera** o documento.
|
|
53
55
|
- **`needs-confirmation`** — o passo cria issues (`decompose-apply`) ou gasta IA repetindo a crítica de um rascunho existente. Revise antes e confirme com `--apply` / `--yes`.
|
|
54
56
|
- **`inconsistent-state`** — as labels afirmam um documento que não existe. Quase sempre o título da issue mudou depois de gerar (o slug vira outro diretório).
|
|
55
57
|
|
|
56
58
|
## Regras que o `run` respeita — e você também
|
|
57
59
|
|
|
58
60
|
- **Nunca aplique label de gatilho no modo local.** Ela dispararia o Action e o passo aconteceria duas vezes. O `run` não aplica nenhuma.
|
|
59
|
-
- **Um passo por invocação.** `--max-steps <n>` encadeia, mas cada passo de IA custa dinheiro — encadeie só quando o usuário pedir.
|
|
61
|
+
- **Um passo por invocação.** `--max-steps <n>` encadeia, mas cada passo de IA custa dinheiro — encadeie só quando o usuário pedir. Na prática o encadeamento agora para sozinho: cada documento vai para um Pull Request, e o passo seguinte depende do merge.
|
|
60
62
|
- A **Regra fundamental** continua valendo: nunca escreva `spec.md`/`plan.md`/`decomposition.md` à mão. Quem gera é a CLI, aqui como no Action.
|
|
61
63
|
|
|
62
64
|
## `mode` — o interruptor
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: spec-wave-spec
|
|
3
|
-
description: "Use para iniciar a geração da especificação funcional (spec.md) de uma Feature do spec-wave — o PRIMEIRO documento do ciclo, antes do plano técnico. Aplica a label spec-wave:spec e deixa o GitHub Action gerar e
|
|
3
|
+
description: "Use para iniciar a geração da especificação funcional (spec.md) de uma Feature do spec-wave — o PRIMEIRO documento do ciclo, antes do plano técnico. Aplica a label spec-wave:spec e deixa o GitHub Action gerar o arquivo e abrir um Pull Request. Gatilhos: 'gerar a spec da feature 12', 'criar especificação funcional', 'rodar o spec-wave:spec'. Só vale para Features — Spike, RFC e Bug não usam spec."
|
|
4
4
|
allowed-tools:
|
|
5
5
|
- Bash(gh issue *)
|
|
6
6
|
- Bash(npx @spec-wave/cli@latest *)
|
|
@@ -9,7 +9,7 @@ allowed-tools:
|
|
|
9
9
|
|
|
10
10
|
# spec-wave spec — especificação funcional (1º documento)
|
|
11
11
|
|
|
12
|
-
> **Regra fundamental: nunca escreva o `spec.md` à mão.** Quem gera é o spec-wave — pelo Action ou pela CLI local. É isso que garante que o arquivo
|
|
12
|
+
> **Regra fundamental: nunca escreva o `spec.md` à mão.** Quem gera é o spec-wave — pelo Action ou pela CLI local. É isso que garante que o arquivo chegue à main por Pull Request e seja referenciado na issue. Exceção: revisar/melhorar um `spec.md` já gerado (aí sim use Edit).
|
|
13
13
|
|
|
14
14
|
## Dois modos, mesmo resultado
|
|
15
15
|
|
|
@@ -18,7 +18,7 @@ allowed-tools:
|
|
|
18
18
|
| **Action** | aplicar a label `spec-wave:spec` | fluxo assíncrono; roda no CI, você acompanha pela issue |
|
|
19
19
|
| **Local** | `npx @spec-wave/cli@latest generate-spec --issue-number <n>` | você quer o documento **agora**, nesta sessão, e iterar em cima dele |
|
|
20
20
|
|
|
21
|
-
O modo é detectado pelo ambiente — fora do Actions, a CLI roda em modo local automaticamente. Os dois geram o arquivo,
|
|
21
|
+
O modo é detectado pelo ambiente — fora do Actions, a CLI roda em modo local automaticamente. Os dois geram o arquivo, abrem um **Pull Request** com ele, comentam na issue e removem a label de gatilho. **Pergunte ao usuário qual ele quer** se não estiver claro; na dúvida numa sessão interativa, prefira o local (o resultado aparece em segundos, em vez de exigir acompanhar o Action).
|
|
22
22
|
|
|
23
23
|
> Local exige a credencial de IA no seu ambiente (`OPENROUTER_API_KEY`, `ANTHROPIC_API_KEY` ou o login do Claude Code, se o provider for `claude-oauth`) e um `.spec-wave.json` no repositório. Para conduzir o fluxo inteiro sem gastar minutos de Actions, veja a skill **run**.
|
|
24
24
|
|
|
@@ -36,7 +36,7 @@ O modo é detectado pelo ambiente — fora do Actions, a CLI roda em modo local
|
|
|
36
36
|
```bash
|
|
37
37
|
npx @spec-wave/cli@latest generate-spec --issue-number <número>
|
|
38
38
|
```
|
|
39
|
-
O comando imprime `Modo de execução: local`, gera
|
|
39
|
+
O comando imprime `Modo de execução: local`, gera e abre o Pull Request. Nada é gravado no seu clone — o documento vive no PR até o merge.
|
|
40
40
|
|
|
41
41
|
**Action** — assíncrono:
|
|
42
42
|
```bash
|
|
@@ -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
|
-
- **
|
|
39
|
-
-
|
|
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 *)
|
|
@@ -31,7 +31,7 @@ Toda a CLI é invocada como `npx @spec-wave/cli@latest <comando>`.
|
|
|
31
31
|
- **Action:** aplique a label de gatilho (`spec-wave:spec`, `spec-wave:plan`, `spec-wave:decompose`);
|
|
32
32
|
- **Local:** `npx @spec-wave/cli@latest generate-spec|generate-plan|decompose --issue-number <n>` na sua sessão.
|
|
33
33
|
|
|
34
|
-
O modo é detectado pelo ambiente (`GITHUB_ACTIONS`), sem flag. Os dois geram,
|
|
34
|
+
O modo é detectado pelo ambiente (`GITHUB_ACTIONS`), sem flag. Os dois geram, abrem um **Pull Request** com o documento, comentam na issue e sincronizam o board — o board é a fonte de verdade independentemente de onde rodou. Local exige a chave de IA no seu ambiente e um `.spec-wave.json`. Exceção à regra: revisar/melhorar um documento já gerado.
|
|
35
35
|
2. **Nunca crie Story ou Task avulsa.** Elas nascem do `decompose`, já em **✅ Ready** e vinculadas ao pai. Criadas à mão caem em 📥 Backlog e **não aparecem em tela nenhuma** da UI (o inbox do PM lista Features, a tela do Dev lê 🚧 Desenvolvimento, a fila do TL lê ✅ Ready).
|
|
36
36
|
3. **Nunca use `gh issue create`** para work items — não adiciona ao Project, a issue fica sem Etapa e some das telas. Use `npx @spec-wave/cli@latest issue`.
|
|
37
37
|
4. **A Etapa só avança, nunca retrocede.** O campo **Status** (Todo / In Progress / Done) mede o progresso *dentro* da Etapa e reinicia a cada avanço. Prefira `move`, `task start|done` e `story review` a mutações GraphQL manuais — os comandos embutem essas regras.
|
|
@@ -88,7 +88,7 @@ Depois do `generate-plan` e **antes** de qualquer issue nascer no `decompose`, u
|
|
|
88
88
|
| Reprovou depois de | O que corrigir | Como retomar |
|
|
89
89
|
|--------------------|----------------|--------------|
|
|
90
90
|
| `generate-plan` | `plan.md` (ou a `spec.md` que o embasa) | corrija/regere → remova `critique-failed` → reaplique `spec-wave:ready` |
|
|
91
|
-
| `decompose` | **`decomposition.md`** — os achados citam `Story N` / `Task N.M`, títulos **desse arquivo** | edite
|
|
91
|
+
| `decompose` | **`decomposition.md`** — os achados citam `Story N` / `Task N.M`, títulos **desse arquivo** | edite no Pull Request → remova `critique-failed` → reaplique `spec-wave:decompose` (critica o arquivo como está, sem regerar) |
|
|
92
92
|
|
|
93
93
|
> ⚠️ No `decompose` os achados são sobre as **Stories propostas**, não sobre o `plan.md`. Corrigir o plan não muda o rascunho já gravado.
|
|
94
94
|
|
|
@@ -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` |
|
|
@@ -86,7 +86,7 @@ O `run` decide o passo pelo estado da issue (documentos existentes + labels), re
|
|
|
86
86
|
|
|
87
87
|
## Regra fundamental
|
|
88
88
|
|
|
89
|
-
**Nunca gere `spec.md` ou `plan.md` diretamente.** Acione o passo — a label (modo actions) ou o `run` (modo local) — e deixe o spec-wave gerar o arquivo. Isso garante que o arquivo
|
|
89
|
+
**Nunca gere `spec.md` ou `plan.md` diretamente.** Acione o passo — a label (modo actions) ou o `run` (modo local) — e deixe o spec-wave gerar o arquivo. Isso garante que o arquivo chegue à main por **Pull Request** e seja referenciado na issue.
|
|
90
90
|
|
|
91
91
|
Exceção: se o usuário pedir explicitamente para revisar ou melhorar um documento já gerado, use o Write tool para editar o arquivo local.
|
|
92
92
|
|
|
@@ -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
|
-
>
|
|
219
|
+
> As **labels** nunca entram no PR: são metadado do repositório, não há 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
|
|
|
@@ -294,7 +297,7 @@ A saída da crítica é **estruturada e validada por schema**: `severity` só ac
|
|
|
294
297
|
| Reprovou depois de | O que corrigir | Como retomar |
|
|
295
298
|
|--------------------|----------------|--------------|
|
|
296
299
|
| `generate-plan` | `plan.md` (ou a `spec.md` que o embasa) | corrija → remova `spec-wave:critique-failed` → reaplique **`spec-wave:critique`** (re-critica o arquivo como está). `spec-wave:ready` apenas valida, **não** re-critica; e `spec-wave:plan` **regera** o plano, descartando a correção. |
|
|
297
|
-
| `decompose` (rascunho) | **`decomposition.md`** — os achados citam **`Story N`** e **`Task N.M`**, que são os títulos desse arquivo | edite o arquivo
|
|
300
|
+
| `decompose` (rascunho) | **`decomposition.md`** — os achados citam **`Story N`** e **`Task N.M`**, que são os títulos desse arquivo | edite o arquivo **no Pull Request** → remova `spec-wave:critique-failed` → reaplique `spec-wave:decompose` (ele **critica o arquivo como está**, sem regerar) |
|
|
298
301
|
|
|
299
302
|
> ⚠️ No contexto do `decompose`, os achados são sobre as **Stories propostas**, não sobre o `plan.md`. Corrigir o plan não influencia o rascunho já gravado — edite o `decomposition.md` diretamente. Foi exatamente essa confusão que fazia o ciclo não convergir.
|
|
300
303
|
|
|
@@ -309,7 +312,7 @@ O `decompose` **não cria issues direto**. São dois passos, com um artefato rev
|
|
|
309
312
|
|
|
310
313
|
```
|
|
311
314
|
spec-wave:decompose
|
|
312
|
-
├─ decomposition.md ausente → gera via IA →
|
|
315
|
+
├─ decomposition.md ausente → gera via IA → abre Pull Request → critica
|
|
313
316
|
└─ decomposition.md presente → critica o arquivo COMO ESTÁ (preserva suas edições)
|
|
314
317
|
├─ grave → +critique-failed, comentário citando Story N / Task N.M, exit 1
|
|
315
318
|
└─ limpo → +decompose-ready, comentário "revise e aplique"
|
|
@@ -341,7 +344,7 @@ Corpo técnico.
|
|
|
341
344
|
- a **posição** manda, não o número escrito — inserir uma Story no meio sem renumerar funciona;
|
|
342
345
|
- `**Depende de:**` aceita **irmãs** (`Story 1, Story 3`, 1-based, só para trás — apontar para si mesma ou para frente é **erro**, não filtro silencioso) e **issues de outras Features** (`#412`, que precisam JÁ existir); as duas formas convivem na mesma linha (`Story 1, #412`), e `—` significa nenhuma;
|
|
343
346
|
- o corpo aceita markdown livre (`## Backend`, cercas de código) — só `## Story N` e `### Task N.M` são estrutura;
|
|
344
|
-
- **para gerar outro rascunho do zero:** apague o arquivo e reaplique `spec-wave:decompose`.
|
|
347
|
+
- **para gerar outro rascunho do zero:** feche o Pull Request e apague a branch `spec-wave/<n>-decompose` (ou apague o arquivo, se já mergeado) e reaplique `spec-wave:decompose`.
|
|
345
348
|
|
|
346
349
|
### Guard de idempotência do decompose (`spec-wave:decomposed`)
|
|
347
350
|
|
|
@@ -459,8 +462,8 @@ Traz tudo para a versão atual da CLI, atualizando **só o que mudou**: a skill
|
|
|
459
462
|
- Escopos podem ser limitados com `--skip-skill`, `--skip-config`, `--skip-repo`.
|
|
460
463
|
- **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
464
|
- **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
|
|
463
|
-
- **`.spec-wave.json
|
|
465
|
+
- **Nos dois modos**, as **labels** são aplicadas direto na base (metadado do repositório, não versionável) e nunca entram no PR.
|
|
466
|
+
- **`.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
467
|
4. Se a skill foi atualizada, oriente recarregar/reiniciar o agente para pegar a nova versão.
|
|
465
468
|
|
|
466
469
|
---
|
|
@@ -649,10 +652,10 @@ Para qualquer outro tipo (Spike, Bug, Story, Task, …) o Action **recusa** e co
|
|
|
649
652
|
```bash
|
|
650
653
|
gh issue edit <número> --add-label "spec-wave:decompose"
|
|
651
654
|
```
|
|
652
|
-
Informe: "Rascunho iniciado — vai
|
|
655
|
+
Informe: "Rascunho iniciado — vai abrir um Pull Request com o `decomposition.md` e passar pela crítica. **Nenhuma issue é criada nesta etapa.**"
|
|
653
656
|
3. Quando o Action terminar, leia o comentário na issue:
|
|
654
657
|
- **`spec-wave:decompose-ready`** → o rascunho passou pela crítica. **Leia o `decomposition.md`** e mostre ao usuário o que será criado (Stories, Tasks, dependências). Ofereça editar o arquivo antes de aplicar.
|
|
655
|
-
- **`spec-wave:critique-failed`** → o Action **falhou (exit 1)** e nada foi criado. Os achados citam `Story N` / `Task N.M` do `decomposition.md`. **Corrija esse arquivo** (não o `plan.md`)
|
|
658
|
+
- **`spec-wave:critique-failed`** → o Action **falhou (exit 1)** e nada foi criado. Os achados citam `Story N` / `Task N.M` do `decomposition.md`. **Corrija esse arquivo** (não o `plan.md`) no Pull Request e reaplique `spec-wave:decompose` — o arquivo é criticado como está, sem ser regerado.
|
|
656
659
|
- **`spec-wave:needs-human`** → a crítica esgotou as tentativas. Pare e envolva o usuário: as duas labels precisam sair à mão.
|
|
657
660
|
4. **Etapa 2 — aplicar o rascunho aprovado** (só depois da revisão):
|
|
658
661
|
```bash
|
|
@@ -728,7 +731,7 @@ Gera o **`bug.md`** de um defeito: `docs/bugs/<slug>/bug.md`, com reprodução,
|
|
|
728
731
|
|
|
729
732
|
1. Confirme que a issue é do tipo **Bug** (para outros tipos o Action pula, remove a label e comenta).
|
|
730
733
|
2. `gh issue edit <n> --add-label "spec-wave:bug"`
|
|
731
|
-
3. Avise: o Action `generate-bug.yml` gera e
|
|
734
|
+
3. Avise: o Action `generate-bug.yml` gera o arquivo e abre um Pull Request com ele.
|
|
732
735
|
4. Ofereça revisar **duas seções**: **Causa Raiz** e **Teste de Regressão**. São elas que decidem se a correção ataca o defeito ou o sintoma.
|
|
733
736
|
5. Validar: `spec-wave:ready` → confere as seis seções e aplica `spec-wave:bug-approved`.
|
|
734
737
|
|
|
@@ -18,7 +18,15 @@ jobs:
|
|
|
18
18
|
# Modo de execução: `spec-wave mode local` cria a variável de repositório
|
|
19
19
|
# SPEC_WAVE_EXECUTION=local e este job passa a ser PULADO — run aparece como
|
|
20
20
|
# skipped e job que não roda não é faturado. `mode actions` remove a variável.
|
|
21
|
-
|
|
21
|
+
# PR de DOCUMENTO não é PR de implementação. O fluxo publica spec.md,
|
|
22
|
+
# plan.md, bug.md e decomposition.md em branches `spec-wave/*`, e deixar este
|
|
23
|
+
# workflow rodar em cima delas move o board por um PR que não implementa
|
|
24
|
+
# nada. Nos Actions um PR aberto pelo GITHUB_TOKEN não dispara workflow, mas
|
|
25
|
+
# um aberto no modo local (ou via GH_PR_TOKEN) dispara.
|
|
26
|
+
#
|
|
27
|
+
# A guarda cobre também `spec-wave/update-v*`, do `update --branch` — que
|
|
28
|
+
# tampouco implementa uma Story.
|
|
29
|
+
if: vars.SPEC_WAVE_EXECUTION != 'local' && !startsWith(github.event.pull_request.head.ref, 'spec-wave/')
|
|
22
30
|
runs-on: ubuntu-latest
|
|
23
31
|
permissions:
|
|
24
32
|
issues: read
|
|
@@ -44,7 +52,10 @@ jobs:
|
|
|
44
52
|
move:
|
|
45
53
|
needs: resolve
|
|
46
54
|
# PR sem vínculo explícito não resolve Feature nenhuma — e não move nada.
|
|
47
|
-
if:
|
|
55
|
+
if: >
|
|
56
|
+
vars.SPEC_WAVE_EXECUTION != 'local' &&
|
|
57
|
+
!startsWith(github.event.pull_request.head.ref, 'spec-wave/') &&
|
|
58
|
+
needs.resolve.outputs.feature != ''
|
|
48
59
|
runs-on: ubuntu-latest
|
|
49
60
|
# MESMO namespace do decompose.yml: um `decompose-apply` em curso na Feature
|
|
50
61
|
# segura este job na fila em vez de disputar a subárvore com ele. Foi essa
|
|
@@ -35,7 +35,7 @@ jobs:
|
|
|
35
35
|
permissions:
|
|
36
36
|
issues: write
|
|
37
37
|
# read: a crítica LÊ o plan.md do checkout e não escreve arquivo nenhum —
|
|
38
|
-
# ao contrário do generate-plan, que
|
|
38
|
+
# ao contrário do generate-plan, que publica o documento gerado.
|
|
39
39
|
contents: read
|
|
40
40
|
|
|
41
41
|
steps:
|
|
@@ -16,7 +16,7 @@ on:
|
|
|
16
16
|
# proteção.
|
|
17
17
|
#
|
|
18
18
|
# generate-spec, generate-plan e generate-bug usam o MESMO namespace por outro
|
|
19
|
-
# motivo: os quatro
|
|
19
|
+
# motivo: os quatro publicam documentos em branch própria + Pull Request, e este aqui ainda lê
|
|
20
20
|
# o spec.md/plan.md do checkout — que uma geração concorrente estaria trocando
|
|
21
21
|
# debaixo dele.
|
|
22
22
|
concurrency:
|
|
@@ -56,8 +56,18 @@ jobs:
|
|
|
56
56
|
runs-on: ubuntu-latest
|
|
57
57
|
permissions:
|
|
58
58
|
issues: write
|
|
59
|
-
# A etapa de rascunho commita docs/**/decomposition.md no branch default.
|
|
60
59
|
contents: write
|
|
60
|
+
# `contents: write` continua necessário: o commit vai por Git Data API
|
|
61
|
+
# (createTree/createCommit/createRef), que é autorizada por ele. O que
|
|
62
|
+
# mudou foi o DESTINO — branch própria do documento, nunca a default.
|
|
63
|
+
#
|
|
64
|
+
# `pull-requests: write` é a permissão NOVA deste fluxo. Sem ela o commit
|
|
65
|
+
# é criado e o PR não, e o documento fica numa branch que ninguém vê.
|
|
66
|
+
#
|
|
67
|
+
# Atenção: o GITHUB_TOKEN só abre PR se "Allow GitHub Actions to create and
|
|
68
|
+
# approve pull requests" estiver ligado (Settings → Actions → General) —
|
|
69
|
+
# desligado por padrão em muitas organizações. `GH_PR_TOKEN` é a saída.
|
|
70
|
+
pull-requests: write
|
|
61
71
|
|
|
62
72
|
steps:
|
|
63
73
|
- uses: actions/checkout@v4
|
|
@@ -78,6 +88,7 @@ jobs:
|
|
|
78
88
|
${{ github.event.label.name == 'spec-wave:decompose-apply' && '--apply' || '' }}
|
|
79
89
|
env:
|
|
80
90
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
91
|
+
GH_PR_TOKEN: ${{ secrets.GH_PR_TOKEN }}
|
|
81
92
|
PROJECT_TOKEN: ${{ secrets.GH_PROJECT_TOKEN }}
|
|
82
93
|
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
83
94
|
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|