@spec-wave/cli 0.29.0 → 0.30.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/cli.mjs +35 -5
- package/src/commands/doctor.mjs +83 -2
- package/src/commands/generate-qa-plan.mjs +421 -0
- package/src/commands/qa-run.mjs +813 -0
- package/src/commands/run.mjs +5 -1
- package/src/config.mjs +17 -1
- package/src/lib/artifact-pr.mjs +2 -0
- package/src/lib/critique.mjs +38 -9
- package/src/lib/decomposition-doc.mjs +5 -1
- package/src/lib/doc-paths.mjs +5 -2
- package/src/lib/next-step.mjs +15 -3
- package/src/lib/qa-exec.mjs +314 -0
- package/src/lib/qa-plan-doc.mjs +340 -0
- package/src/lib/qa-report.mjs +340 -0
- package/src/plugin/.claude-plugin/plugin.json +1 -1
- package/src/plugin/skills/qa/SKILL.md +105 -0
- package/src/plugin/skills/qa/model-prompt.critique.md +44 -0
- package/src/plugin/skills/qa/model-prompt.md +68 -0
- package/src/templates/skill/SKILL.md +48 -1
- package/src/templates/workflows/generate-qa-plan.yml +64 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: spec-wave-qa
|
|
3
|
+
description: "Use para a etapa 🧪 QA do spec-wave — gerar o plano de QA de uma Feature (label spec-wave:qa → qa-plan.md), revisá-lo, e EXECUTAR os cenários localmente com `spec-wave qa <issue>` (Feature, Story ou Bug). Verde move o board sozinho; vermelho abre um Bug por cenário reprovado. Gatilhos: 'rodar o QA', 'validar a feature 12', 'gerar o plano de QA', 'testar a story 34', 're-testar o cenário 2'."
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- Bash(npx @spec-wave/cli@latest qa *)
|
|
6
|
+
- Bash(npx @spec-wave/cli@latest generate-qa-plan *)
|
|
7
|
+
- Bash(npx @spec-wave/cli@latest doctor)
|
|
8
|
+
- Bash(gh issue *)
|
|
9
|
+
- Read
|
|
10
|
+
- Write
|
|
11
|
+
- Edit
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# spec-wave qa — etapa 🧪 QA
|
|
15
|
+
|
|
16
|
+
Duas metades, em ordem obrigatória:
|
|
17
|
+
|
|
18
|
+
1. **Gerar o plano** (label + Action): `spec-wave:qa` na **Feature** → o Action gera `docs/features/<slug>/qa-plan.md`, valida, critica e aplica `spec-wave:qa-ready`.
|
|
19
|
+
2. **Executar** (sempre local): `npx @spec-wave/cli@latest qa <issue>` roda os cenários contra o checkout e emite o veredito.
|
|
20
|
+
|
|
21
|
+
**Nunca rode o `qa` sem a `spec-wave:qa-ready` na Feature** — o comando recusa, e o motivo é de desenho (D-QA3/D-QA4): o veredito **verde avança a Etapa sozinho, sem confirmação humana**, então o portão humano é a **revisão do plano**, antes de executar.
|
|
22
|
+
|
|
23
|
+
## 0. Detecção de configuração (antes de qualquer coisa)
|
|
24
|
+
|
|
25
|
+
Confirme que existe `.spec-wave.json` no repositório (senão → skill **setup**). Para executar de fato, o comando do executor precisa estar em `qa.command` no `.spec-wave.json` (ou na env `SPEC_WAVE_QA_CMD`, que tem precedência):
|
|
26
|
+
|
|
27
|
+
```json
|
|
28
|
+
{
|
|
29
|
+
"qa": {
|
|
30
|
+
"command": "claude -p \"Execute o QA descrito em {contextFile}\"",
|
|
31
|
+
"setup": "npm ci && npm run build",
|
|
32
|
+
"env": { "BASE_URL": "http://localhost:3000" },
|
|
33
|
+
"defaultBugPriority": "P2"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Placeholders: `{contextFile} {qaPlanFile} {specFile} {issue} {type} {title}`. Sem `qa.command`, o comando monta o contexto, imprime como configurar e **não executa** — não é erro.
|
|
39
|
+
|
|
40
|
+
## 1. Gerar o plano (Feature)
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
gh issue edit <feature> --add-label "spec-wave:qa"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
- **Só em Feature** (D-QA1: o plano é por Feature, arquivo único, seções `## Cenário N — Story #X`). Numa Story o Action comenta apontando a Feature-pai; num Bug, não se aplica (ver §5).
|
|
47
|
+
- Arquivo **ausente** → gera via IA e publica em Pull Request. Arquivo **presente** → valida + critica **COMO ESTÁ** (edições manuais são preservadas — mesma semântica do decompose). Para regerar do zero: apague o arquivo e reaplique a label.
|
|
48
|
+
- Requer `spec.md` e `plan.md` já na base.
|
|
49
|
+
- Desfechos: limpo → `spec-wave:qa-ready` + comentário com o resumo; grave → `spec-wave:critique-failed`; reprovas repetidas → `spec-wave:needs-human`.
|
|
50
|
+
|
|
51
|
+
## 2. Revisar e editar o qa-plan.md (o portão humano)
|
|
52
|
+
|
|
53
|
+
Leia o plano com o usuário ANTES de executar. Regras do arquivo:
|
|
54
|
+
|
|
55
|
+
- A estrutura é só `## Cenário N — Story #X`; o corpo aceita markdown livre.
|
|
56
|
+
- **A posição manda, não o número escrito** — inserir um cenário no meio sem renumerar funciona.
|
|
57
|
+
- `Story #X` é obrigatório e precisa ser sub-issue da Feature.
|
|
58
|
+
- `**Critério:**` e `**Esperado:**` são obrigatórios; `**Pré-condições:**` e `**Passos:**` opcionais.
|
|
59
|
+
- Depois de editar, reaplique `spec-wave:qa` para uma nova crítica (o arquivo NÃO é regerado).
|
|
60
|
+
|
|
61
|
+
> ⚠️ O slug vem do **título** da Feature. Renomeá-la depois da geração órfã o arquivo — o comando falha citando o slug órfão.
|
|
62
|
+
|
|
63
|
+
## 3. Executar — SEMPRE `--dry-run` primeiro
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
npx @spec-wave/cli@latest qa <issue> --dry-run # mostra cenários-alvo e o comando; ZERO escrita no GitHub
|
|
67
|
+
npx @spec-wave/cli@latest qa <issue> # executa de fato
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Mostre ao usuário o contexto montado em `.spec-wave/qa-<n>.md` antes de rodar sem `--dry-run`.
|
|
71
|
+
|
|
72
|
+
Alvos: `qa <feature>` roda todos os cenários das Stories ainda sem `qa-approved`; `qa <story>` só os daquela Story; `qa <bug>` o Teste de Regressão do `bug.md`; `--only <n[,m]>` filtra por número posicional.
|
|
73
|
+
|
|
74
|
+
**PROIBIDO corrigir código durante a execução.** QA não conserta: cenário reprovado vira Bug, e alterar o código no meio invalida o veredito. Se você for o executor (via `qa.command`), siga as instruções do contexto à risca — um cenário por vez, evidência bruta, `blocked` (nunca `fail`) para o que não pôde rodar.
|
|
75
|
+
|
|
76
|
+
## 4. Os três desfechos
|
|
77
|
+
|
|
78
|
+
| Veredito | O que aconteceu | O que fazer |
|
|
79
|
+
|---|---|---|
|
|
80
|
+
| ✅ **verde** (todos pass) | `qa-approved` aplicada; Story → 📋 Homologação; Feature move quando TODAS as Stories liberarem; Bug → 🚀 Deploy | Nada — o board já andou. Se a Story tinha **Bug filho aberto**, ela NÃO avança (guarda dura): feche o Bug primeiro. |
|
|
81
|
+
| ❌ **vermelho** (algum fail) | 1 Bug por cenário reprovado (filho da Story dona, ✅ Ready, `bug.md` commitado, `bug-approved` aplicada); item fica em 🧪 QA; exit 1 | Corrija os Bugs (skill **implement**) e re-teste (§6). |
|
|
82
|
+
| ⚪ **inconclusivo** (blocked, sem fail) | Ambiente quebrado não é defeito: nada move, nenhum Bug; exit 1 | Destrave o ambiente (seed, serviço fora do ar) e rode de novo. |
|
|
83
|
+
|
|
84
|
+
## 5. Bug — exceção documentada (§2.1 da spec)
|
|
85
|
+
|
|
86
|
+
O QA de um **Bug** usa a seção `Teste de Regressão` do próprio `bug.md` (não há qa-plan). Verde move o Bug para **🚀 Deploy** (D-QA6 — Bug não passa por Homologação).
|
|
87
|
+
|
|
88
|
+
E quando um cenário reprova, o `bug.md` do Bug novo **é escrito pelo comando, sem IA e sem a label `spec-wave:bug`** — exceção explícita à regra "nunca escreva o bug.md à mão": a reprodução, o esperado/obtido e o teste de regressão já existem e são determinísticos (são o cenário + a saída real). O arquivo é commitado e a `spec-wave:bug-approved` aplicada pelo próprio comando. **Não** aplique `spec-wave:bug` nesses Bugs — regeraria por IA um documento que registra uma execução observada.
|
|
89
|
+
|
|
90
|
+
## 6. Ciclo de re-teste
|
|
91
|
+
|
|
92
|
+
1. Fix do Bug (skill **implement**, PR, merge).
|
|
93
|
+
2. Re-teste só o cenário: `npx @spec-wave/cli@latest qa <story> --only <cenário>`.
|
|
94
|
+
3. O comando NÃO duplica Bug: se o cenário reprovar de novo, ele comenta no Bug existente (marcador `spec-wave:qa-origin`).
|
|
95
|
+
4. Verde com o Bug ainda aberto não avança a Story — feche o Bug (o fix mergeado + regressão verde justificam) e rode o `qa` de novo.
|
|
96
|
+
|
|
97
|
+
## Recusas que você vai encontrar (e o que significam)
|
|
98
|
+
|
|
99
|
+
- Sem `.spec-wave.json` → rode a skill **setup**.
|
|
100
|
+
- `spec-wave:qa` ainda na issue → geração em voo; aguarde o Action.
|
|
101
|
+
- `critique-failed`/`needs-human` → portão humano da crítica; corrija o documento apontado.
|
|
102
|
+
- Feature sem `qa-ready` → gere/critique o plano primeiro (§1).
|
|
103
|
+
- Etapa **anterior** a 🧪 QA → o `qa` não promove item; quem move até QA é o merge (`spec-wave merge` / `run --pr`).
|
|
104
|
+
- Etapa **posterior** → informa e sai 0 (a Etapa nunca retrocede).
|
|
105
|
+
- Nenhum cenário casando com a Story → plano desatualizado (re-decompose criou Stories novas) ou Feature renomeada (slug órfão).
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: critique-qa-plan
|
|
3
|
+
action: critique
|
|
4
|
+
description: Critério da crítica adversarial do qa-plan.md contra spec, plan e decomposição, antes da liberação para execução.
|
|
5
|
+
tools: [Read, Glob, Grep]
|
|
6
|
+
maxTurns: 20
|
|
7
|
+
lenses:
|
|
8
|
+
- "cobertura — algum critério de aceite da spec ficou sem cenário correspondente?"
|
|
9
|
+
- "vacuidade — algum cenário passaria mesmo sem a implementação, ou tem esperado não observável?"
|
|
10
|
+
- "fidelidade — algum cenário testa implementação em vez de comportamento, ou contradiz a spec?"
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Crítica adversarial do plano de QA
|
|
14
|
+
|
|
15
|
+
Você audita o `qa-plan.md` proposto contra o `spec.md`, o `plan.md` e a decomposição. Seu papel é encontrar problemas, não elogiar.
|
|
16
|
+
|
|
17
|
+
Este portão importa mais que os outros: o veredito **verde da execução avança a Etapa sozinho, sem confirmação humana** (D-QA3). Um plano fraco aprovado aqui vira aprovação automática de trabalho não validado.
|
|
18
|
+
|
|
19
|
+
## O que caracteriza um achado GRAVE
|
|
20
|
+
|
|
21
|
+
- **Critério de aceite da spec sem cenário correspondente** — a lacuna faz a Feature ser aprovada sem aquele comportamento ter sido validado.
|
|
22
|
+
- **Cenário que passaria SEM a implementação** — ex.: "a página carrega", "o comando não dá erro" num fluxo que existia antes da Feature. É o mesmo vício já caçado no bug.md: um teste que não falharia não valida nada.
|
|
23
|
+
- **Resultado esperado não observável** — "verificar se funciona", "conferir se está correto", "validar o comportamento". Esperado sem critério objetivo torna o veredito arbitrário.
|
|
24
|
+
- **Cenário que testa implementação em vez de comportamento** — "a classe PedidoService existe", "a função retorna um array" — em vez do que o usuário/consumidor observa.
|
|
25
|
+
- **Cenário que contradiz a spec** — esperado que inverte uma regra de negócio explícita.
|
|
26
|
+
- **Cenário atribuído à Story errada** — o comportamento validado pertence a outra Story da decomposição (a reprova abriria o Bug no lugar errado).
|
|
27
|
+
|
|
28
|
+
## O que é MENOR
|
|
29
|
+
|
|
30
|
+
Pré-condições vagas mas completáveis, passos que poderiam ser mais concretos, ordem subótima, redundância parcial entre cenários.
|
|
31
|
+
|
|
32
|
+
<!-- requires-tools -->
|
|
33
|
+
## Como verificar
|
|
34
|
+
|
|
35
|
+
Você tem `Read`, `Glob` e `Grep`. Confira os passos contra o repositório real: a rota citada existe? O comando citado existe? Um plano cujos passos apontam para o que não existe produziria só `blocked` — e isso é um achado.
|
|
36
|
+
<!-- /requires-tools -->
|
|
37
|
+
|
|
38
|
+
## Barra de rigor
|
|
39
|
+
|
|
40
|
+
NÃO invente problemas. Um plano enxuto que cobre os critérios de aceite com esperados observáveis é um resultado legítimo e frequente — diga isso. O inverso também vale: "não consegui confirmar" não é aprovação.
|
|
41
|
+
|
|
42
|
+
## Consequência
|
|
43
|
+
|
|
44
|
+
Um achado **grave** aplica `spec-wave:critique-failed` e o plano NÃO é liberado (`spec-wave:qa-ready` não é aplicada): nenhuma execução de QA roda até a correção. Um achado **menor** é comentado e o plano segue. Reserve o grave para o que tornaria o verde automático enganoso.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: qa-plan
|
|
3
|
+
action: qa
|
|
4
|
+
description: Gera o plano de QA (qa-plan.md) de uma Feature a partir dos critérios de aceite da spec, com um ou mais cenários por Story.
|
|
5
|
+
tools: [Read, Glob, Grep]
|
|
6
|
+
maxTurns: 30
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Plano de QA de uma Feature
|
|
10
|
+
|
|
11
|
+
Você é um analista de QA experiente. A partir da Feature fornecida (spec.md, plan.md e a lista de Stories reais), escreva o **qa-plan.md**: os cenários de validação funcional que um executor vai rodar contra o checkout, um por critério de aceite relevante.
|
|
12
|
+
|
|
13
|
+
## Entrada
|
|
14
|
+
|
|
15
|
+
O payload JSON traz:
|
|
16
|
+
|
|
17
|
+
- `feature` — número e título da issue da Feature
|
|
18
|
+
- `stories` — as Stories REAIS (número da issue, título, corpo). **Todo cenário pertence a exatamente uma destas Stories, pelo número.**
|
|
19
|
+
- `spec` — o conteúdo de `spec.md` (critérios de aceite, fluxos, regras de negócio)
|
|
20
|
+
- `plan` — o conteúdo de `plan.md` (estratégia técnica — útil para saber COMO exercitar: endpoints, comandos, telas)
|
|
21
|
+
|
|
22
|
+
## Formato de saída (obrigatório)
|
|
23
|
+
|
|
24
|
+
Responda APENAS com o documento markdown, neste formato exato:
|
|
25
|
+
|
|
26
|
+
```markdown
|
|
27
|
+
# Plano de QA — [FEATURE] Título da Feature
|
|
28
|
+
<!-- spec-wave:qa-plan v1 issue=NUMERO_DA_FEATURE -->
|
|
29
|
+
|
|
30
|
+
## Cenário 1 — Story #412
|
|
31
|
+
|
|
32
|
+
**Critério:** AC-2 — cliente vê apenas os próprios pedidos
|
|
33
|
+
**Pré-condições:** dois usuários autenticáveis, cada um com ao menos um pedido
|
|
34
|
+
**Passos:**
|
|
35
|
+
1. Autenticar como usuário A
|
|
36
|
+
2. `GET /pedidos`
|
|
37
|
+
**Esperado:** resposta 200 contendo somente pedidos de A; nenhum pedido de B
|
|
38
|
+
|
|
39
|
+
## Cenário 2 — Story #412
|
|
40
|
+
...
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Regras do formato:
|
|
44
|
+
|
|
45
|
+
- O título de cada seção é `## Cenário N — Story #X`, onde `#X` é o número REAL de uma Story da lista `stories`. **Nunca invente números de issue.**
|
|
46
|
+
- `**Critério:**` e `**Esperado:**` são obrigatórios em todo cenário. `**Pré-condições:**` e `**Passos:**` são opcionais, mas quase sempre necessários.
|
|
47
|
+
- **Toda Story da lista precisa de ao menos um cenário** — uma Story sem cenário reprova o plano na validação determinística.
|
|
48
|
+
- Escreva em português (pt-BR).
|
|
49
|
+
|
|
50
|
+
## O que faz um cenário BOM
|
|
51
|
+
|
|
52
|
+
- **Deriva de um critério de aceite da spec** — cite-o no campo `**Critério:**` (ex.: "AC-3 — pedido cancelado não aparece na listagem"). Todo critério de aceite relevante da spec deve ter um cenário correspondente.
|
|
53
|
+
- **Resultado esperado OBSERVÁVEL**: um status HTTP, uma saída de comando, um registro no banco, um texto na tela. "Verificar se funciona" e "conferir se está correto" não são resultados — são a ausência de um.
|
|
54
|
+
- **Falharia sem a implementação**: um cenário que passaria num checkout sem a Feature não valida nada. Pense: "se ninguém tivesse implementado isso, este cenário quebraria?"
|
|
55
|
+
- **Testa COMPORTAMENTO, não implementação**: valide o que o usuário/consumidor observa, não a existência de uma classe ou o nome de uma função.
|
|
56
|
+
- **Executável por alguém sem contexto**: passos concretos (comandos, URLs, payloads), pré-condições explícitas (dados de teste, usuários, estado inicial).
|
|
57
|
+
|
|
58
|
+
<!-- requires-tools -->
|
|
59
|
+
## Exploração antes de escrever
|
|
60
|
+
|
|
61
|
+
Você tem `Read`, `Glob` e `Grep` no repositório. Use-os para ancorar os passos no que existe de verdade: os endpoints reais (rotas registradas), os comandos reais (scripts do package.json, Makefile), os seeds/fixtures disponíveis. Um passo `GET /api/pedidos` só vale se essa rota existe com esse nome. Não gaste mais do que o necessário: explore o suficiente para os passos serem executáveis, e então escreva o documento completo.
|
|
62
|
+
<!-- /requires-tools -->
|
|
63
|
+
|
|
64
|
+
## O que NÃO fazer
|
|
65
|
+
|
|
66
|
+
- Não inventar suíte de testes automatizada: o plano descreve validação funcional executável contra o checkout, não `describe/it`.
|
|
67
|
+
- Não cobrir requisitos não-funcionais genéricos (performance, segurança) a menos que a spec traga critério de aceite explícito e testável sobre eles.
|
|
68
|
+
- Não duplicar o mesmo critério em vários cenários — um cenário por comportamento distinto.
|
|
@@ -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|preflight|audit|issue|feature|spec|plan|ready|decompose|order|implement|merge|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|qa|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 *)
|
|
@@ -126,6 +126,7 @@ Labels de gatilho:
|
|
|
126
126
|
- `spec-wave:decompose` → dispara `decompose.yml` → gera (ou **re-critica**) o **rascunho** em `decomposition.md`. **Não cria issue nenhuma.**
|
|
127
127
|
- `spec-wave:decompose-apply` → dispara o mesmo workflow em modo aplicação → cria as Stories e Tasks **a partir do rascunho revisado**
|
|
128
128
|
- `spec-wave:bug` → dispara `generate-bug.yml` → gera `docs/bugs/<slug>/bug.md` (só para issues `[BUG]`)
|
|
129
|
+
- `spec-wave:qa` → dispara `generate-qa-plan.yml` → gera (ou **re-critica COMO ESTÁ**) o plano de QA em `docs/features/<slug>/qa-plan.md`. **Só em Feature** (o plano é por Feature; numa Story o Action aponta a Feature-pai). A **execução** é sempre local: `npx @spec-wave/cli@latest qa <issue>`.
|
|
129
130
|
|
|
130
131
|
Labels de **estado** (gravadas pelas automações — **não** são gatilhos, não as adicione por conta própria):
|
|
131
132
|
- `spec-wave:decompose-ready` → o rascunho da decomposição passou pela crítica e espera **revisão humana**; aplique `spec-wave:decompose-apply` para criar as issues
|
|
@@ -133,12 +134,16 @@ Labels de **estado** (gravadas pelas automações — **não** são gatilhos, n
|
|
|
133
134
|
- `spec-wave:needs-human` → a crítica reprovou N vezes seguidas (default 3); **para o fluxo** até uma pessoa revisar e remover a label
|
|
134
135
|
- `spec-wave:decomposed` → a Feature/RFC já foi decomposta; o `decompose` pula silenciosamente enquanto ela existir (veja *Guard de idempotência* abaixo)
|
|
135
136
|
- `spec-wave:bug-approved` → o `bug.md` passou na validação das seis seções obrigatórias
|
|
137
|
+
- `spec-wave:qa-ready` → o `qa-plan.md` passou na validação + crítica e espera **revisão humana** — é o pré-requisito de `qa <issue>` (o veredito verde avança a Etapa sozinho, então o portão humano é a revisão do plano). ⚠️ Não confunda com `spec-wave:ready` (gatilho da validação de spec/plan).
|
|
138
|
+
- `spec-wave:qa-approved` → a execução do QA passou. Aplicada na Story (e na Feature, quando todas as Stories passarem).
|
|
136
139
|
|
|
137
140
|
Label **modificadora** (esta você pode aplicar):
|
|
138
141
|
- `spec-wave:model:<apelido>` → força um modelo específico **naquela execução**, resolvido por `ai.modelAliases` no `.spec-wave.json`. Serve para reprocessar um caso difícil num modelo mais forte sem editar a configuração do repositório inteiro. Duas dessas labels na mesma issue = ambíguo, nenhuma vale.
|
|
139
142
|
|
|
140
143
|
A etapa **🚧 Desenvolvimento** é coberta pelo comando **local** `npx @spec-wave/cli@latest implement <número>` (não é uma label/Action): lê uma **Feature** (todas as Stories pendentes, em ordem de dependência), uma Story ou uma Task e aciona o spec-kit para implementar. Veja `/spec-wave implement`.
|
|
141
144
|
|
|
145
|
+
A etapa **🧪 QA** tem artefato e comando próprios: a label `spec-wave:qa` gera o `qa-plan.md` (validado + criticado → `spec-wave:qa-ready`), e a **execução é sempre local** — `npx @spec-wave/cli@latest qa <issue>` roda os cenários contra o checkout. Verde: `qa-approved` + Story → 📋 Homologação (Bug → 🚀 Deploy, sem Homologação). Vermelho: **um Bug por cenário reprovado**, já com `bug.md` commitado. Inconclusivo (`blocked` sem `fail`): nada move, nenhum Bug. Veja `/spec-wave qa`.
|
|
146
|
+
|
|
142
147
|
---
|
|
143
148
|
|
|
144
149
|
## Referência da CLI (conheça os parâmetros ANTES de executar)
|
|
@@ -281,6 +286,17 @@ Sem flags. Roda um checklist de diagnóstico no repositório atual: token GitHub
|
|
|
281
286
|
|
|
282
287
|
> 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`.
|
|
283
288
|
|
|
289
|
+
### `@spec-wave/cli qa <issue>` — executa o plano de QA localmente (e `qa --pr-number <n>` no Action)
|
|
290
|
+
| Flag/Arg | Tipo | Descrição |
|
|
291
|
+
|----------|------|-----------|
|
|
292
|
+
| `<issue>` | string | Número da **Feature** (todos os cenários das Stories ainda sem `qa-approved`), **Story** (os cenários dela) ou **Bug** (a seção `Teste de Regressão` do `bug.md`). |
|
|
293
|
+
| `--only <n[,m]>` | string | Só o(s) cenário(s) indicado(s) — número **posicional** no plano. O restante herda o veredito do último relatório. |
|
|
294
|
+
| `--severity <p>` | string | Severidade dos Bugs abertos na reprova: `P0`–`P3` (default: `qa.defaultBugPriority` ou `P2`). |
|
|
295
|
+
| `--dry-run` | boolean | Monta o contexto e imprime cenários + comando. **Zero escrita no GitHub.** |
|
|
296
|
+
| `--pr-number <n>` | string | Modo Action (mutuamente exclusivo com `<issue>`): move a Feature/Bug do PR aprovado/mergeado para 🧪 QA. |
|
|
297
|
+
|
|
298
|
+
> **Pré-requisitos:** Feature dona do plano com `spec-wave:qa-ready` (portão humano — D-QA4), item já em 🧪 QA (o comando **não promove**; Etapa posterior = informa e sai 0), executor em `qa.command` no `.spec-wave.json` (ou `SPEC_WAVE_QA_CMD`) — sem ele, só monta o contexto. **Sempre `--dry-run` primeiro.** Desfechos: verde → `qa-approved` + Story para 📋 Homologação (Bug → 🚀 Deploy; Feature quando TODAS as Stories liberarem; **Bug filho aberto segura a Story mesmo verde**); vermelho → 1 Bug por cenário reprovado (filho da Story, ✅ Ready, `bug.md` determinístico commitado — exceção documentada à regra do `spec-wave:bug`), exit 1; `blocked` sem `fail` → inconclusivo: nada move, nenhum Bug, exit 1. Re-teste após o fix: `qa <story> --only <cenário>` (não duplica Bug — comenta no existente).
|
|
299
|
+
|
|
284
300
|
### `@spec-wave/cli task <start|done> <n>` — transições de Task no board (comando LOCAL)
|
|
285
301
|
| Flag/Arg | Tipo | Descrição |
|
|
286
302
|
|----------|------|-----------|
|
|
@@ -793,6 +809,33 @@ Para criar um Bug: `npx @spec-wave/cli@latest bug --title "..." [--parent <n>] [
|
|
|
793
809
|
|
|
794
810
|
---
|
|
795
811
|
|
|
812
|
+
### `/spec-wave qa <número-da-issue>`
|
|
813
|
+
|
|
814
|
+
A etapa **🧪 QA**: plano por Feature + execução local com veredito. Duas metades, nesta ordem obrigatória:
|
|
815
|
+
|
|
816
|
+
**1. Gerar/criticar o plano (Feature):**
|
|
817
|
+
```bash
|
|
818
|
+
gh issue edit <feature> --add-label "spec-wave:qa"
|
|
819
|
+
```
|
|
820
|
+
- Arquivo ausente → gera `docs/features/<slug>/qa-plan.md` via IA (publicado em PR). Arquivo presente → valida + critica **COMO ESTÁ** (edições manuais preservadas). Regerar do zero = apagar o arquivo e reaplicar.
|
|
821
|
+
- Requer `spec.md` + `plan.md` na base. Limpo → `spec-wave:qa-ready`; grave → `critique-failed`.
|
|
822
|
+
- **Só em Feature** — numa Story o Action comenta apontando a Feature-pai; Bug usa o `Teste de Regressão` do `bug.md`.
|
|
823
|
+
|
|
824
|
+
**2. Revisar o plano e executar (sempre local, SEMPRE `--dry-run` primeiro):**
|
|
825
|
+
```bash
|
|
826
|
+
npx @spec-wave/cli@latest qa <issue> --dry-run # cenários-alvo + comando; zero escrita no GitHub
|
|
827
|
+
npx @spec-wave/cli@latest qa <issue> # executa e dá o veredito
|
|
828
|
+
```
|
|
829
|
+
- A revisão do plano é o **portão humano** (D-QA4): sem `qa-ready` na Feature o comando recusa — porque o verde avança a Etapa **sozinho** (D-QA3).
|
|
830
|
+
- Regras de edição do plano: seções `## Cenário N — Story #X` (posição manda, não o número escrito), `**Critério:**`/`**Esperado:**` obrigatórios.
|
|
831
|
+
- Desfechos: **verde** → `qa-approved`, Story → 📋 Homologação, Bug → 🚀 Deploy (D-QA6), Feature quando TODAS as Stories liberarem; Bug filho aberto **segura** a Story mesmo verde. **Vermelho** → 1 Bug por cenário reprovado (filho da Story, ✅ Ready, milestone herdado) com `bug.md` **determinístico commitado pelo comando e `bug-approved` aplicada** — exceção explícita à Regra fundamental: reprodução, esperado/obtido e regressão são a execução observada, e regenerar por IA só alucina; **não** aplique `spec-wave:bug` nesses Bugs. **Inconclusivo** (`blocked` sem `fail`) → nada move, nenhum Bug, exit 1.
|
|
832
|
+
- Re-teste após o fix: `npx @spec-wave/cli@latest qa <story> --only <cenário>` — não duplica Bug (comenta no existente).
|
|
833
|
+
- **PROIBIDO corrigir código durante a execução** — QA não conserta; alterar o código invalida o veredito.
|
|
834
|
+
|
|
835
|
+
Sem `qa.command` no `.spec-wave.json` (nem `SPEC_WAVE_QA_CMD`), o comando monta o contexto em `.spec-wave/qa-<n>.md` e orienta — configure como no `specKit.command` do implement.
|
|
836
|
+
|
|
837
|
+
---
|
|
838
|
+
|
|
796
839
|
### `/spec-wave fix-pr <número-do-pr>`
|
|
797
840
|
|
|
798
841
|
Audita um Pull Request e corrige automaticamente os problemas encontrados — segurança, arquitetura, infraestrutura e qualidade de código. Cada fix vira um commit separado no branch do PR. Cada review comment recebe uma resposta com o hash do commit.
|
|
@@ -910,6 +953,10 @@ docs/
|
|
|
910
953
|
decomposition.md ← rascunho gerado quando spec-wave:decompose é adicionado (3º).
|
|
911
954
|
REVISÁVEL e EDITÁVEL à mão; as issues só nascem com
|
|
912
955
|
spec-wave:decompose-apply
|
|
956
|
+
qa-plan.md ← plano de QA gerado quando spec-wave:qa é adicionado (4º,
|
|
957
|
+
com a Feature já em 🧪 QA). Um cenário por critério de
|
|
958
|
+
aceite, seções "## Cenário N — Story #X"; executado
|
|
959
|
+
localmente por `spec-wave qa <issue>`
|
|
913
960
|
rfcs/
|
|
914
961
|
<slug-do-rfc>/
|
|
915
962
|
decomposition.md ← mesmo papel, com "## Task N" (RFC não usa spec/plan)
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
name: Generate QA Plan
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
issues:
|
|
5
|
+
types: [labeled]
|
|
6
|
+
|
|
7
|
+
# Mesmo desenho do decompose.yml: `labeled` dispara para QUALQUER label, então o
|
|
8
|
+
# run que não vai fazer nada ganha um grupo único (`spec-wave-noop-<run_id>`) e
|
|
9
|
+
# não disputa a fila — com `cancel-in-progress: false`, um run inútil na fila
|
|
10
|
+
# cancelaria o que estava PENDENTE (ver o comentário longo no decompose.yml).
|
|
11
|
+
#
|
|
12
|
+
# O namespace `spec-wave-item-<issue>` é COMPARTILHADO com decompose.yml,
|
|
13
|
+
# generate-spec/plan/bug e o job `move` do code-review.yml: este workflow também
|
|
14
|
+
# publica documento em branch própria + Pull Request, e lê spec.md/plan.md que
|
|
15
|
+
# uma geração concorrente estaria trocando.
|
|
16
|
+
concurrency:
|
|
17
|
+
group: >-
|
|
18
|
+
${{ github.event.label.name == 'spec-wave:qa'
|
|
19
|
+
&& format('spec-wave-item-{0}', github.event.issue.number)
|
|
20
|
+
|| format('spec-wave-noop-{0}', github.run_id) }}
|
|
21
|
+
cancel-in-progress: false
|
|
22
|
+
|
|
23
|
+
jobs:
|
|
24
|
+
generate-qa-plan:
|
|
25
|
+
# `spec-wave:qa` numa Feature gera (ou re-critica) o qa-plan.md. O comando
|
|
26
|
+
# trata sozinho os outros tipos (Story → aponta a Feature-pai; Bug → usa o
|
|
27
|
+
# Teste de Regressão do bug.md), então o filtro de título fica amplo de
|
|
28
|
+
# propósito — o `if:` só corta o ruído de labels sem relação.
|
|
29
|
+
# Modo de execução: `spec-wave mode local` cria a variável de repositório
|
|
30
|
+
# SPEC_WAVE_EXECUTION=local e este job passa a ser PULADO.
|
|
31
|
+
if: >
|
|
32
|
+
vars.SPEC_WAVE_EXECUTION != 'local' &&
|
|
33
|
+
github.event.label.name == 'spec-wave:qa'
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
permissions:
|
|
36
|
+
issues: write
|
|
37
|
+
# O commit do qa-plan.md vai por Git Data API (contents: write) para uma
|
|
38
|
+
# branch própria (`spec-wave/<n>-qa-plan`), nunca a default; sem
|
|
39
|
+
# `pull-requests: write` o commit existe e o PR não.
|
|
40
|
+
contents: write
|
|
41
|
+
pull-requests: write
|
|
42
|
+
|
|
43
|
+
steps:
|
|
44
|
+
- uses: actions/checkout@v4
|
|
45
|
+
with:
|
|
46
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
47
|
+
|
|
48
|
+
- uses: actions/setup-node@v4
|
|
49
|
+
with:
|
|
50
|
+
node-version: '24'
|
|
51
|
+
|
|
52
|
+
- name: Instala a CLI
|
|
53
|
+
run: npm install -g @spec-wave/cli@{{CLI_VERSION}}
|
|
54
|
+
|
|
55
|
+
- name: Generate QA plan
|
|
56
|
+
run: spec-wave generate-qa-plan --issue-number ${{ github.event.issue.number }}
|
|
57
|
+
env:
|
|
58
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
59
|
+
GH_PR_TOKEN: ${{ secrets.GH_PR_TOKEN }}
|
|
60
|
+
PROJECT_TOKEN: ${{ secrets.GH_PROJECT_TOKEN }}
|
|
61
|
+
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
62
|
+
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
|
63
|
+
OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
|
|
64
|
+
GITHUB_REPOSITORY: ${{ github.repository }}
|