@spec-wave/cli 0.29.0 → 0.32.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 (44) hide show
  1. package/package.json +5 -3
  2. package/protocol/qa-result.v1.json +62 -0
  3. package/protocol/qa-trail-report.v1.json +113 -0
  4. package/src/api/github-graphql.mjs +6 -1
  5. package/src/api/github-rest.mjs +21 -0
  6. package/src/cli.mjs +114 -9
  7. package/src/commands/decompose.mjs +29 -3
  8. package/src/commands/doctor.mjs +183 -3
  9. package/src/commands/generate-qa-plan.mjs +421 -0
  10. package/src/commands/implement.mjs +56 -44
  11. package/src/commands/merge.mjs +43 -14
  12. package/src/commands/order.mjs +350 -96
  13. package/src/commands/qa-lead.mjs +748 -0
  14. package/src/commands/qa-run.mjs +892 -0
  15. package/src/commands/run.mjs +5 -1
  16. package/src/config.mjs +32 -1
  17. package/src/lib/artifact-pr.mjs +2 -0
  18. package/src/lib/artifact-publish.mjs +5 -2
  19. package/src/lib/board.mjs +14 -0
  20. package/src/lib/critique.mjs +38 -9
  21. package/src/lib/decomposition-doc.mjs +5 -1
  22. package/src/lib/dependency-map.mjs +300 -0
  23. package/src/lib/doc-paths.mjs +9 -2
  24. package/src/lib/git-retry.mjs +82 -0
  25. package/src/lib/net-cache.mjs +142 -0
  26. package/src/lib/next-step.mjs +15 -3
  27. package/src/lib/qa-exec.mjs +335 -0
  28. package/src/lib/qa-lead-backend.mjs +213 -0
  29. package/src/lib/qa-lead.mjs +627 -0
  30. package/src/lib/qa-plan-doc.mjs +340 -0
  31. package/src/lib/qa-report.mjs +396 -0
  32. package/src/lib/skill-compose.mjs +234 -0
  33. package/src/lib/story-graph.mjs +256 -0
  34. package/src/plugin/.claude-plugin/plugin.json +1 -1
  35. package/src/plugin/skills/merge/SKILL.md +1 -0
  36. package/src/plugin/skills/order/SKILL.md +21 -5
  37. package/src/plugin/skills/qa/SKILL.md +107 -0
  38. package/src/plugin/skills/qa/model-prompt.critique.md +44 -0
  39. package/src/plugin/skills/qa/model-prompt.md +68 -0
  40. package/src/plugin/skills/qa-executor/SKILL.md +76 -0
  41. package/src/plugin/skills/qa-lead/SKILL.md +89 -0
  42. package/src/templates/skill/SKILL.md +981 -279
  43. package/src/templates/skill/core.md +584 -0
  44. package/src/templates/workflows/generate-qa-plan.yml +64 -0
@@ -0,0 +1,584 @@
1
+ ---
2
+ name: spec-wave
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|qa|qa-lead|task|story|move|uninstall|rfc|bug|triage|fix-pr] [target]"
5
+ user-invocable: true
6
+ allowed-tools:
7
+ - Bash(npx @spec-wave/cli@latest *)
8
+ - Bash(npx @spec-wave/cli *)
9
+ - Bash(gh issue *)
10
+ - Bash(gh project *)
11
+ - Bash(gh repo view *)
12
+ - Bash(gh auth status)
13
+ - Bash(gh pr *)
14
+ - Bash(gh api *)
15
+ - Bash(git add *)
16
+ - Bash(git commit *)
17
+ - Bash(git push *)
18
+ - Bash(git checkout *)
19
+ - Read
20
+ - Edit
21
+ - Write
22
+ - Agent
23
+ ---
24
+
25
+ # spec-wave Skill
26
+
27
+ Este skill guia o usuário pelo fluxo spec-driven definido no RFC-001.
28
+
29
+ > **Antes de responder a qualquer sub-comando**, leia o arquivo `rfc/rfc-integrate-spec-kit-into-kanban.md` se ele existir no diretório atual, para embasar suas respostas no processo real da equipe.
30
+
31
+ > **Verifique se esta skill está atualizada:** logo no topo deste arquivo há um banner `spec-wave skill vX.Y.Z` (inserido na instalação). Compare com `npx @spec-wave/cli@latest --version`. Se a CLI for **mais recente** (ou o banner estiver ausente = instalada por versão antiga), esta skill está desatualizada — avise o usuário e sugira `npx @spec-wave/cli@latest update` (detecta e atualiza só o que mudou: skill, `.spec-wave.json` e workflows/labels do repo) ou, para atualizar só a skill, `npx @spec-wave/cli@latest install-skill --force`. A skill é uma cópia estática e **não** acompanha o `npx` sozinha.
32
+
33
+ ---
34
+
35
+ ## Detecção de configuração (faça isto primeiro, sempre)
36
+
37
+ Antes de qualquer sub-comando, leia o arquivo `.spec-wave.json` na raiz do repositório atual (use o tool Read). Esse arquivo é gravado pelo `npx @spec-wave/cli@latest init` e é a fonte de estado persistente entre sessões.
38
+
39
+ - **Se existir**, o spec-wave já foi configurado. Use seus campos para contextualizar as respostas, sem perguntar de novo:
40
+ - `owner`/`repo` → repositório alvo dos comandos `gh`
41
+ - `project.url` / `project.title` → o GitHub Project a referenciar
42
+ - `version` → versão da CLI usada no `init` (compare com `npx @spec-wave/cli@latest --version`; se divergir, sugira `npx @spec-wave/cli@latest refresh --config` para atualizar o arquivo, ou re-rodar o `init` para atualizar workflows/labels)
43
+ - `initializedAt` → quando foi configurado
44
+ Não rode `/spec-wave setup` de novo a menos que o usuário peça explicitamente.
45
+ - **Se não existir**, o repositório provavelmente ainda não foi configurado. Sugira começar por `/spec-wave setup`.
46
+
47
+ Exemplo de `.spec-wave.json`:
48
+ ```json
49
+ {
50
+ "version": "0.1.0",
51
+ "owner": "acme",
52
+ "repo": "loja",
53
+ "project": {
54
+ "title": "loja — Spec Wave",
55
+ "url": "https://github.com/users/acme/projects/5",
56
+ "id": "PVT_..."
57
+ },
58
+ "initializedAt": "2026-06-18T13:40:00.000Z"
59
+ }
60
+ ```
61
+
62
+ ---
63
+
64
+ ## Modo de execução (Actions × local)
65
+
66
+ Leia `execution.mode` no `.spec-wave.json` **antes** de acionar qualquer passo do fluxo:
67
+
68
+ | `execution.mode` | Como acionar um passo | Custo |
69
+ |---|---|---|
70
+ | `actions` (default) | aplicar a label de gatilho (`spec-wave:spec`, `:plan`, …) | minutos de GitHub Actions |
71
+ | `local` | `npx @spec-wave/cli@latest run <issue>` | nenhum — roda nesta máquina |
72
+
73
+ **No modo `local`, NÃO aplique label de gatilho.** Os workflows estão desarmados por uma variável de repositório, mas a label continua sendo o contrato do outro modo — aplicá-la só polui a issue (e, se alguém religar o CI, dispara tarde).
74
+
75
+ ```bash
76
+ npx @spec-wave/cli@latest mode # estado atual dos dois lados do interruptor
77
+ npx @spec-wave/cli@latest mode local # desarma os workflows
78
+ npx @spec-wave/cli@latest run <issue> --dry-run # explica o próximo passo sem executar
79
+ npx @spec-wave/cli@latest run <issue> # executa
80
+ npx @spec-wave/cli@latest run --pr <n> # code-review (+ qa, se aprovado OU mergeado)
81
+ ```
82
+
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.
84
+
85
+ ---
86
+
87
+ ## Regra fundamental
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 chegue à main por **Pull Request** e seja referenciado na issue.
90
+
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
+
93
+ **Nunca crie Story ou Task avulsa com `/spec-wave issue`.** Story e Task nascem do `decompose`, já na Etapa **✅ Ready** e vinculadas ao pai. Criadas à mão elas caem em **📥 Backlog**, que é a coluna de descoberta de *produto* — e ali **não aparecem em tela nenhuma** da UI do spec-wave: o inbox do PM lista só Features, a tela do Dev lê a etapa 🚧 Desenvolvimento e a fila do TL lê ✅ Ready. Se o usuário insistir numa Story/Task avulsa, crie-a **com `--parent <n>`** e, logo em seguida, avance-a para ✅ Ready — explicando por que esse passo extra é necessário.
94
+
95
+ **Nunca use `gh issue create` para criar work items.** Ele não adiciona a issue ao Project, então ela fica **sem Etapa** — e some de todas as telas da UI. Use sempre `npx @spec-wave/cli issue` (ou os atalhos `initiative` / `feature`).
96
+
97
+ ---
98
+
99
+ ## Fluxo Kanban
100
+
101
+ ```
102
+ 📥 Backlog → 🐞 Triagem → 🎯 Priorizado → 📋 Spec → 📋 Plan → ✅ Ready
103
+ → 🚧 Desenvolvimento → 👀 Code Review
104
+ → 🧪 QA → 📋 Homologação → 🚀 Deploy → 🎉 Done
105
+ ```
106
+
107
+ Essa é a sequência completa, mas **cada tipo de artefato percorre só um trecho dela** — e, principalmente, **nasce numa Etapa diferente**. Consulte esta tabela antes de criar ou mover qualquer item.
108
+
109
+ | Artefato | Nasce em | Percorre | Observações |
110
+ |----------|----------|----------|-------------|
111
+ | **Initiative / Epic** | 📥 Backlog | — | Agrupadores. Não têm fluxo próprio; acompanham os filhos. |
112
+ | **Feature** | 📥 Backlog | 🎯 Priorizado → 📋 Spec → 📋 Plan → ✅ Ready → 🚧 Desenvolvimento → 👀 Code Review → 🧪 QA → 📋 Homologação → 🚀 Deploy → 🎉 Done | Fica parada em **✅ Ready** esperando um dev assumir — é ali que ela aparece na fila do TL. Só avança para 👀 Code Review quando **TODAS** as suas Stories já estiverem lá. |
113
+ | **Story** | **✅ Ready** (criada pelo `decompose-apply`) | 🚧 Desenvolvimento → 👀 Code Review → 🧪 QA → 📋 Homologação → 🎉 Done | **Nunca nasce em 📥 Backlog.** |
114
+ | **Task** | **✅ Ready** (criada pelo `decompose-apply`) | 🚧 Desenvolvimento → 🎉 Done | **Não** passa por Code Review, QA nem Homologação — só `task start` e `task done`. |
115
+ | **RFC** | 📥 Backlog | decompõe direto em **Tasks** (que nascem em ✅ Ready) | Não usa spec/plan. |
116
+ | **Bug** | **🐞 Triagem** (reportado) ou **✅ Ready** (achado em QA/Homologação/review) | ✅ Ready → 🚧 Desenvolvimento → 👀 Code Review → 🧪 QA → 🚀 Deploy → 🎉 Done | Não passa por 🎯 Priorizado, 📋 Spec, 📋 Plan nem 📋 Homologação. Bug **P0** nasce direto em ✅ Ready — a triagem é confirmada depois. |
117
+ | **Spike** | 📥 Backlog | **movido só à mão pelo usuário** | Nunca avance a Etapa de um Spike por conta própria. |
118
+
119
+ **Regra da Etapa:** 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 sempre os comandos da CLI (`move`, `task start|done`, `story review`) a mutações manuais no board — eles embutem essas regras.
120
+
121
+ Labels de gatilho:
122
+ - `spec-wave:spec` → dispara `generate-spec.yml` → gera `spec.md` (especificação funcional, primeiro)
123
+ - `spec-wave:plan` → dispara `generate-plan.yml` → gera `plan.md` (plano técnico, a partir da spec)
124
+ - `spec-wave:critique` → dispara `critique.yml` → **re-critica o `plan.md` COMO ESTÁ**, sem regerar. É o gatilho de retomada depois de corrigir o plano à mão — `spec-wave:plan` geraria outro do zero, descartando a correção.
125
+ - `spec-wave:ready` → dispara `validate.yml` → valida ambos os arquivos
126
+ - `spec-wave:decompose` → dispara `decompose.yml` → gera (ou **re-critica**) o **rascunho** em `decomposition.md`. **Não cria issue nenhuma.**
127
+ - `spec-wave:decompose-apply` → dispara o mesmo workflow em modo aplicação → cria as Stories e Tasks **a partir do rascunho revisado**
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>`.
130
+
131
+ Labels de **estado** (gravadas pelas automações — **não** são gatilhos, não as adicione por conta própria):
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
+ - `spec-wave:critique-failed` → a crítica adversarial apontou contradições **graves**; **bloqueia** o `spec-wave:ready` até ser removida (veja *Crítica adversarial* abaixo)
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
135
+ - `spec-wave:decomposed` → a Feature/RFC já foi decomposta; o `decompose` pula silenciosamente enquanto ela existir (veja *Guard de idempotência* abaixo)
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).
139
+
140
+ Label **modificadora** (esta você pode aplicar):
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.
142
+
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`.
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
+
147
+ ---
148
+
149
+ ## Referência da CLI (conheça os parâmetros ANTES de executar)
150
+
151
+ Esta skill é um **wrapper** da CLI `@spec-wave/cli`, sempre invocada como `npx @spec-wave/cli@latest <comando>`. Regra de ouro: **nunca rode um comando sem os parâmetros que ele aceita** esperando que ele pergunte — colete os valores com o usuário e passe via flags. Em especial, **`init` sem `--repo` abre um wizard interativo (@clack/prompts) que a skill NÃO consegue dirigir** — sempre passe `--repo`.
152
+
153
+ ### `@spec-wave/cli init` — configura o repositório
154
+ | Flag | Tipo | Descrição |
155
+ |------|------|-----------|
156
+ | `--repo <owner/repo>` | string | Repositório alvo. **Passe SEMPRE** para evitar o wizard interativo. |
157
+ | `--project-title <title>` | string | Nome do GitHub Project. Padrão: `<repo> — Spec Wave`. |
158
+ | `--skip-project` | flag | Pula a criação do Project (use ao re-rodar se já existe). |
159
+ | `--skip-labels` | flag | Pula a criação das labels. |
160
+ | `--skip-files` | flag | Pula a criação dos workflows + issue templates. |
161
+ | `--dry-run` | flag | Simula a configuração sem alterar nada. |
162
+
163
+ ### `@spec-wave/cli issue` — cria um work item tipado, opcionalmente como sub-issue, e adiciona ao board
164
+ | Flag | Tipo | Descrição |
165
+ |------|------|-----------|
166
+ | `--title <title>` | string (obrigatório) | Título, **sem** o prefixo de tipo (a CLI adiciona, ex.: `[STORY]`). |
167
+ | `--type <type>` | string | `initiative`, `epic`, `feature`, `story`, `task`, `bug`, `spike` ou `rfc`. Default: `feature`. |
168
+ | `--parent <n>` | string | Número da issue pai — cria como **sub-issue** dela (relação nativa do GitHub). |
169
+ | `--body <text>` | string | Descrição. |
170
+ | `--priority <p>` | string | **Opcional.** `P0`, `P1`, `P2` ou `P3`. Omita se o usuário não pediu — a prioridade fica `null` (sem prioridade). Nunca atribua por conta própria. |
171
+ | `--area <area>` | string | `Frontend`, `Backend`, `Mobile`, `Infra`, `DevOps` ou `Data`. |
172
+
173
+ > Faz tudo: cria a issue (label de tipo — e de prioridade **apenas se `--priority` for informado**), vincula ao parent como sub-issue, adiciona ao Project e define os campos **Etapa**, **Work Item Type**, **Area** e, **só se informada, Priority**. Grava `Parent: #N` no corpo. Lê o Project do `.spec-wave.json`. **Não use `gh issue create` direto** — ele não adiciona ao board nem vincula o parent.
174
+ >
175
+ > ⚠️ **A Etapa inicial é sempre 📥 Backlog, para qualquer `--type`.** Isso é o correto para **Initiative, Epic, Feature, RFC, Bug e Spike**. Para **Story e Task está errado** — elas pertencem a ✅ Ready (veja a *Regra fundamental*): prefira criá-las via `decompose`; se criar à mão, avance a Etapa logo depois.
176
+
177
+ ### `@spec-wave/cli initiative` — atalho de `issue --type initiative`
178
+ Cria o nó raiz da hierarquia (agrupa Epics). Mesmas flags do `issue` exceto `--type` (fixo em `initiative`) e `--parent` (Initiative é raiz, não tem pai).
179
+
180
+ ### `@spec-wave/cli feature` — atalho de `issue --type feature`
181
+ Mesmas flags do `issue` (exceto `--type`, fixo em `feature`). Mantido para o fluxo do RFC-001.
182
+
183
+ ### `@spec-wave/cli uninstall` — remove a configuração (mantém o Project)
184
+ | Flag | Tipo | Descrição |
185
+ |------|------|-----------|
186
+ | `--repo <owner/repo>` | string | Repositório (default: lê do `.spec-wave.json`). |
187
+ | `--skip-labels` | flag | Não remove as labels. |
188
+ | `--skip-files` | flag | Não remove os arquivos `.github`. |
189
+ | `--keep-config` | flag | Mantém o `.spec-wave.json` local. |
190
+ | `--dry-run` | flag | Mostra o que seria removido sem alterar nada. |
191
+ | `--yes` | flag | Não pede confirmação. |
192
+
193
+ > Remove labels + arquivos `.github` + `.spec-wave.json`. **NUNCA apaga o GitHub Project** (preserva o histórico do board) — o usuário deve excluí-lo manualmente se quiser.
194
+
195
+ ### `@spec-wave/cli info` — status de configuração do repo atual
196
+ | Flag | Tipo | Descrição |
197
+ |------|------|-----------|
198
+ | `--json` | flag | Saída JSON (`{"initialized":bool, ..., "skill":{...}}`) para parsing programático. |
199
+
200
+ > Além do `.spec-wave.json`, valida a **skill instalada**: para cada agente detectado no diretório, compara a cópia instalada com a versão empacotada na CLI (uma cópia **global** atualizada também conta). No JSON, o campo `skill` traz `{agentsDetected, installNeeded, pending:[{agent, reason, path}]}` — `installNeeded: true` significa que o usuário precisa rodar `install-skill` (ou `update`).
201
+
202
+ ### `@spec-wave/cli refresh` — atualiza o `.spec-wave.json` local
203
+ | Flag | Tipo | Descrição |
204
+ |------|------|-----------|
205
+ | `--config` | flag | Re-consulta o GitHub Project e reescreve o `.spec-wave.json` (IDs do campo Etapa, opções, number, versão da CLI). |
206
+
207
+ > Use quando o `.spec-wave.json` estiver desatualizado: repos inicializados por uma versão antiga (sem `etapaFieldId`/`stageOptions`), Project renomeado, ou versão da CLI divergente. Escreve no arquivo **local** — faça commit depois.
208
+
209
+ ### `@spec-wave/cli update` — atualiza tudo que ficou para trás (só o que mudou)
210
+ | Flag | Tipo | Descrição |
211
+ |------|------|-----------|
212
+ | `--global` | flag | Verifica a skill no escopo do usuário (padrão: projeto). |
213
+ | `--skip-skill` / `--skip-config` / `--skip-repo` | flag | Pula a categoria correspondente. |
214
+ | `--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>`. |
215
+ | `--config-in-pr` / `--no-config-in-pr` | flag | Força incluir/excluir o `.spec-wave.json` do PR (o default decide sozinho — veja abaixo). |
216
+ | `--skill-in-pr` / `--no-skill-in-pr` | flag | Força incluir/excluir a **skill dos agentes** do PR (o default decide sozinho — veja abaixo). |
217
+ | `--dry-run` | flag | Mostra o que seria atualizado sem alterar nada. |
218
+ | `--yes` | flag | Aplica sem pedir confirmação. |
219
+
220
+ > Detecta e atualiza **somente o que divergiu** da versão atual da CLI: a **skill** instalada (por agente), o **`.spec-wave.json`** local (se versão/formato divergir) e os **workflows/labels** do repo (compara com os templates empacotados). Interativo por padrão (mostra o plano e confirma). É o atalho recomendado após atualizar a CLI.
221
+
222
+ > **`--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.
223
+ >
224
+ > 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.
225
+ >
226
+ > 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.
227
+ >
228
+ > ⚠️ 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.
229
+
230
+ ### `@spec-wave/cli generate-plan` · `generate-spec` · `validate` · `decompose`
231
+ | Flag | Tipo | Descrição |
232
+ |------|------|-----------|
233
+ | `--issue-number <n>` | string (obrigatório) | Número da issue no GitHub. |
234
+ | `--apply` | flag (só `decompose`) | Cria as issues a partir do `decomposition.md` revisado. **Sem** a flag, o `decompose` apenas gera/critica o rascunho e não cria nada. |
235
+
236
+ > ⚠️ Esses quatro comandos são executados pelos **GitHub Actions** (disparados por labels), **não** pela skill diretamente. Veja a *Regra fundamental*: para gerar plan/spec/decompor, adicione a **label** correspondente — não rode o comando à mão (a não ser para debug local).
237
+ >
238
+ > **Por tipo de issue:**
239
+ > - `generate-spec` / `generate-plan` → **apenas Features**. Para **Spike, RFC e Bug** a geração é **pulada** (o Action remove a label e comenta) — esses tipos não usam spec/plan.
240
+ > - `decompose` → **Feature** (gera Stories + Tasks) e **RFC** (gera **Tasks** diretamente, sem Stories). Para outros tipos, o Action recusa.
241
+
242
+ ### `@spec-wave/cli implement` — aciona o spec-kit para uma Feature, Story ou Task (comando LOCAL)
243
+ | Flag/Arg | Tipo | Descrição |
244
+ |----------|------|-----------|
245
+ | `<issue>` | string (obrigatório) | Número da issue (Feature, Story ou Task), ex.: `12` ou `#12`. Argumento posicional. |
246
+ | `--feature-dir <path>` | string | Caminho `docs/features/<slug>` para anexar `spec.md`/`plan.md` como contexto (sobrescreve a resolução automática). |
247
+ | `--dry-run` | flag | Monta o contexto e imprime o comando do spec-kit **sem executar** e **sem escrever nada no GitHub** (não move cards, não adiciona itens ao Project). |
248
+
249
+ > Diferente dos quatro acima, `implement` roda **localmente** (lê `.spec-wave.json`, como `issue`), não por Action. Detecta o tipo da issue: **Feature** → lista as Stories (sub-issues), **ordena topologicamente pelas dependências** (`Depende de:` + *blocked by*), **pula** as já em 👀 Code Review+ (listadas no contexto como "não tocar") e monta **um único** contexto com todas as pendentes (cada uma com suas Tasks), acionando o spec-kit **uma vez** com `{issue}/{type}/{title}` da Feature — **ciclo de dependências entre Stories pendentes aborta o comando (exit 1)**; **Story** → coleta todas as Tasks (sub-issues) e aciona o spec-kit uma única vez; **Task** → só aquela task. Monta o contexto em `.spec-wave/implement-<n>.md` e chama o comando configurado em `specKit.command` (no `.spec-wave.json`) ou na env `SPEC_WAVE_IMPLEMENT_CMD`. Placeholders disponíveis no template: `{tasksFile} {specFile} {planFile} {issue} {type} {title}`. Se nada estiver configurado, ele apenas monta o contexto e mostra como configurar (não executa). O contexto inclui os **comentários da issue**, um **digest do código recente** e um **aviso de dependências pendentes** quando a issue depende (linha `Depende de: #N` ou relação nativa *blocked by*) de outra que ainda não foi concluída — nesse caso, confirme com o usuário antes de seguir. Inclui também instruções para o agente implementar as Tasks **sequencialmente, uma por vez** (nunca duas com Status "In Progress" ao mesmo tempo): cada Task usa o **Status** (In Progress) *dentro* da Etapa 🚧 Desenvolvimento e, **ao concluir, avança para a Etapa 🎉 Done com Status Done**. **Ao concluir toda a Story**: fazer o commit, abrir o PR e **avançar a Etapa da Story para 👀 Code Review** (Status → Todo) — as Tasks já estão em 🎉 Done. A **Feature só avança** para Code Review quando **TODAS as suas Stories** já estiverem em Code Review — enquanto houver Story pendente, a Feature fica em 🚧 Desenvolvimento. Etapa só avança (nunca volta); Status mede o progresso dentro da etapa.
250
+
251
+ ### `@spec-wave/cli doctor` — preflight de auth e configuração (comando LOCAL)
252
+ Sem flags. Roda um checklist de diagnóstico no repositório atual: token GitHub (e a fonte dele), escopos (`repo`, `project`, `workflow` — com degradação para checks funcionais em fine-grained PATs), conta ativa do `gh` vs. owner, `.spec-wave.json` (campos e sincronia com o Project real), acesso ao repositório, configuração de IA (provider/modelo/`ai.models`/escalada da crítica/apelidos de modelo/teto de saída + secrets do Actions), **higiene do board e das labels** (colunas fora do fluxo canônico, labels `spec-wave:*` descontinuadas ou ausentes), **spec-kit** (`specKit.command` / env `SPEC_WAVE_IMPLEMENT_CMD` — se ausente, avisa e sugere exemplos por agente: Claude Code, opencode, Codex, Copilot CLI, Kiro CLI, Qwen Code) e os workflows (presença + **versão da CLI fixada**, não `@latest`).
253
+
254
+ > Saída: `✓` ok, `✗` problema confirmado, `!` não verificável (best-effort — falha de rede nunca derruba o doctor). **Exit 1** se houver algum `✗`. **Quando rodar:** no início de uma sessão de trabalho, ou sempre que aparecer um erro estranho (ex.: **404 ao criar issues** — causa típica: token sem acesso ao repo/org, que o doctor aponta). É o primeiro passo de troubleshooting — prefira-o a depurar `gh api` na mão.
255
+
256
+ ### `@spec-wave/cli order <feature>` — ordem de execução das Stories (comando LOCAL)
257
+ | Flag/Arg | Tipo | Descrição |
258
+ |----------|------|-----------|
259
+ | `<feature>` | string (opcional) | Número da issue da **Feature**, ex.: `12` ou `#12`. Omitido: o mapa de todas as Features com trabalho. |
260
+ | `--milestone <ref>` | string | No mapa sem argumento: só as Features da milestone (número ou título). |
261
+ | `--json` | boolean | Saída JSON **estável** (sem ANSI) — o formato para agentes/scripts consumirem a ordem. |
262
+ | `--remote` | boolean | Une também o blocked_by da API (1 chamada por Story) — pega arestas criadas SÓ pela UI. |
263
+ | `--refresh` | boolean | Ignora o cache local e reconsulta a API. |
264
+ | `--sync` | boolean | Grava as dependências VIVAS (body + blocked_by) de volta no `decomposition.md` e regenera o `dependency-map.json`, com commit local escopado. |
265
+
266
+ > **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, com a Etapa atual de cada uma no board. As **arestas** vêm de fontes LOCAIS — `dependency-map.json` (escrito pelo `decompose --apply`), `decomposition.md` aplicado e linha `Depende de: #N` do corpo — **zero chamada de API por Story**; `--remote` acrescenta o *blocked by* nativo. A **Etapa** vem de um snapshot único do board, cacheado por `cache.ttlSec` do `.spec-wave.json` (default 600s; env `SPEC_WAVE_CACHE_TTL`; `0` desliga), com a idade impressa quando servido do cache. 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.
267
+
268
+ ### `@spec-wave/cli preflight --milestone <nome>` — confere tudo ANTES de gerar as specs (comando LOCAL)
269
+ | Flag/Arg | Tipo | Descrição |
270
+ |----------|------|-----------|
271
+ | `--milestone <nome>` | string (obrigatório) | Título da milestone a inventariar. |
272
+ | `--json` | boolean | O relatório em JSON, para ramificar. |
273
+
274
+ > 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.
275
+
276
+ ### `@spec-wave/cli audit --milestone <nome>` — cruza as specs da milestone como CONJUNTO (comando LOCAL)
277
+ | Flag/Arg | Tipo | Descrição |
278
+ |----------|------|-----------|
279
+ | `--milestone <nome>` | string (obrigatório) | Título da milestone a auditar. |
280
+ | `--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. |
281
+ | `--json` | boolean | O relatório em JSON (com `critica.markdown` pronto para comentar nas issues). |
282
+
283
+ > 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**.
284
+
285
+ ### `@spec-wave/cli merge <feature>` — mergeia os PRs empilhados das Stories (comando LOCAL)
286
+ | Flag/Arg | Tipo | Descrição |
287
+ |----------|------|-----------|
288
+ | `<feature>` | string (obrigatório) | Número da issue da **Feature**, ex.: `12` ou `#12`. |
289
+ | `--yes` | boolean | Executa os merges. **Sem ela, só mostra o plano** (fila na ordem, retargets, avisos). |
290
+ | `--keep-branches` | boolean | Não apaga as branches das Stories após o merge. |
291
+
292
+ > 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`.
293
+
294
+ ### `@spec-wave/cli qa <issue>` — executa o plano de QA localmente (e `qa --pr-number <n>` no Action)
295
+ | Flag/Arg | Tipo | Descrição |
296
+ |----------|------|-----------|
297
+ | `<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`). |
298
+ | `--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. |
299
+ | `--severity <p>` | string | Severidade dos Bugs abertos na reprova: `P0`–`P3` (default: `qa.defaultBugPriority` ou `P2`). |
300
+ | `--dry-run` | boolean | Monta o contexto e imprime cenários + comando. **Zero escrita no GitHub.** |
301
+ | `--pr-number <n>` | string | Modo Action (mutuamente exclusivo com `<issue>`): move a Feature/Bug do PR aprovado/mergeado para 🧪 QA. |
302
+
303
+ > **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).
304
+
305
+ ### `@spec-wave/cli qa-lead <plan|run|report> <milestone>` — orquestra o QA de uma TRILHA (comando LOCAL)
306
+ | Flag/Arg | Tipo | Descrição |
307
+ |----------|------|-----------|
308
+ | `<acao>` | string (obrigatório) | `plan` (prepara os planos e PARA no portão humano), `run` (executa o ciclo em containers paralelos) ou `report` (reimprime um ciclo já gravado). |
309
+ | `<milestone>` | string (obrigatório) | Milestone da trilha, por **número ou título** — trilha = milestone (D-QAL1). |
310
+ | `--watch` | boolean | No `plan`: acompanha os planos disparados até resolverem (teto `qa.lead.planWaitTimeoutMin`; estourar relata as pendentes e sai 1). |
311
+ | `--only <features>` | string | No `run`: sub-trilha explícita, ex.: `--only 318,320` (decisão humana declarada, não relaxamento do portão). |
312
+ | `--max-cycles <n>` | string | No `run`: teto de ciclos (default: `qa.lead.maxCycles`, 3). |
313
+ | `--cycle <n>` | string | No `report`: qual ciclo imprimir (default: o último). |
314
+ | `--dry-run` | boolean | Classifica/planeja e imprime — **nenhuma label, zero container, zero escrita**. |
315
+
316
+ > Duas fases separadas (D-QAL2): o `plan` aplica `spec-wave:qa` nas Features sem plano e **para** — o humano revisa os `qa-plan.md`; o `run` só inicia com a trilha inteira em `qa-ready` (recusa listando as pendentes). O `run` faz preflight global, despacha até `qa.lead.maxParallel` containers (um ambiente isolado por Feature — `qa.lead.container.image` obrigatória), coleta os comentários de veredito e grava `docs/qa/<slug-milestone>/cycle-<n>/{report.md,report.json}` + um **bloco delimitado** na descrição do milestone (substituído a cada ciclo, preservando as Release Notes). Ciclo N+1 só se um Bug fechou ou um bloqueio caiu (D-QAL7); teto de 3 ciclos. O Lead **não** aplica label de estado, **não** move card e **não** abre issue — toda mutação de board é do `qa` dentro dos containers.
317
+
318
+ ### `@spec-wave/cli task <start|done> <n>` — transições de Task no board (comando LOCAL)
319
+ | Flag/Arg | Tipo | Descrição |
320
+ |----------|------|-----------|
321
+ | `<action>` | string (obrigatório) | `start` (Etapa 🚧 Desenvolvimento + Status In Progress) ou `done` (Etapa 🎉 Done + Status Done). |
322
+ | `<n>` | string (obrigatório) | Número da issue da **Task**, ex.: `12` ou `#12`. |
323
+
324
+ > **Prefira este comando a mexer no board via GraphQL/`gh` manual** — ele embute as regras do fluxo: a **Etapa nunca retrocede** (se já estiver adiante, só o Status é ajustado) e **uma única Task "In Progress" por vez** dentro da mesma Story (`start` recusa, apontando a Task em andamento, se houver outra irmã em In Progress).
325
+
326
+ ### `@spec-wave/cli story review <n>` — move a Story para Code Review (comando LOCAL)
327
+ | Flag/Arg | Tipo | Descrição |
328
+ |----------|------|-----------|
329
+ | `<action>` | string (obrigatório) | `review` (única ação hoje). |
330
+ | `<n>` | string (obrigatório) | Número da issue da **Story**, ex.: `12` ou `#12`. |
331
+
332
+ > Avança a Story para a Etapa **👀 Code Review** com Status **Todo** (o Status reinicia ao trocar de etapa). Mesma regra do `task`: a **Etapa nunca retrocede** — se a Story já estiver em Code Review ou adiante, o comando apenas informa a Etapa atual. Use no fim do `implement` de uma Story, em vez de mutações GraphQL manuais.
333
+
334
+ ### `@spec-wave/cli move <n> <etapa>` — move QUALQUER item do board (comando LOCAL)
335
+ | Flag/Arg | Tipo | Descrição |
336
+ |----------|------|-----------|
337
+ | `<n>` | string (obrigatório) | Número da issue, ex.: `8` ou `#8`. |
338
+ | `<etapa>` | string (obrigatório) | Etapa de destino, com ou sem emoji, sem acento e em qualquer caixa: `"code review"`, `"Homologação"`, `"🎉 Done"`. |
339
+ | `--status <valor>` | string | Valor do campo Status no destino: `Todo`, `In Progress` ou `Done` (default: `Todo`). |
340
+
341
+ > Serve para **Feature, Story, Task, Bug e RFC** — é o comando a usar quando `story review` e `task start|done` não cobrem o movimento desejado (ex.: mover uma **Feature** para Homologação). Embute as mesmas guardas: a **Etapa nunca retrocede** (se o item já estiver adiante, o comando informa a Etapa atual e não faz nada) e **Spike** é recusado (sua Etapa é movida à mão). Um nome de etapa ambíguo (`"p"` casa com Priorizado e Plan) é recusado listando as candidatas.
342
+ >
343
+ > **Prefira `move` a `gh api graphql` manual.** Não existe escape hatch para retroceder — isso é a regra do fluxo, não uma limitação.
344
+
345
+ ---
346
+
347
+ ## Crítica adversarial, decomposição em duas etapas e dependências
348
+
349
+ ### Crítica adversarial (comentário 🔎)
350
+
351
+ Depois do `generate-plan` e **antes** de qualquer issue ser criada no `decompose`, um segundo agente de IA audita o artefato procurando contradições com a spec, o plan e o `tech_context`. O resultado vira um comentário **🔎 Crítica adversarial (spec-wave)** na issue, com cabeçalho informando a **tentativa** e o **modelo** usados.
352
+
353
+ A saída da crítica é **estruturada e validada por schema**: `severity` só aceita `grave` ou `menor`, e um payload fora do contrato **falha alto** em vez de virar um finding menor com JSON cru dentro. Se a crítica não conclui, ela **não** é registrada como aprovada.
354
+
355
+ **A remediação depende de ONDE a crítica reprovou — são superfícies diferentes:**
356
+
357
+ | Reprovou depois de | O que corrigir | Como retomar |
358
+ |--------------------|----------------|--------------|
359
+ | `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. |
360
+ | `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) |
361
+
362
+ > ⚠️ 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.
363
+
364
+ - Findings **graves** no `decompose` → **nenhuma Story/Task é criada** e o Action **falha (exit 1)**, com a label `spec-wave:critique-failed`. Um pipeline bloqueado nunca fica verde.
365
+ - Findings **menores** não bloqueiam — trate-os como revisão de qualidade.
366
+ - **Escalada:** na tentativa 2 a crítica roda em `ai.escalationModel` (se configurado). Ao atingir `ai.maxCritiqueAttempts` (default 3), o fluxo aplica **`spec-wave:needs-human`**, comenta e **para** — sem chamar a IA de novo. Para retomar: corrija os documentos e remova **as duas** labels (`spec-wave:needs-human` e `spec-wave:critique-failed`).
367
+ - Uma crítica **limpa** remove a `spec-wave:critique-failed` automaticamente e zera o contador de tentativas.
368
+
369
+ ### Decomposição em duas etapas (`decomposition.md`)
370
+
371
+ O `decompose` **não cria issues direto**. São dois passos, com um artefato revisável no meio:
372
+
373
+ ```
374
+ spec-wave:decompose
375
+ ├─ decomposition.md ausente → gera via IA → abre Pull Request → critica
376
+ └─ decomposition.md presente → critica o arquivo COMO ESTÁ (preserva suas edições)
377
+ ├─ grave → +critique-failed, comentário citando Story N / Task N.M, exit 1
378
+ └─ limpo → +decompose-ready, comentário "revise e aplique"
379
+
380
+ spec-wave:decompose-apply
381
+ └─ lê decomposition.md → cria Stories/Tasks → board → +decomposed
382
+ (sem nova crítica: aplicar a label É a aprovação humana)
383
+ ```
384
+
385
+ O arquivo fica em **`docs/features/<slug>/decomposition.md`** (Feature) ou **`docs/rfcs/<slug>/decomposition.md`** (RFC). Formato:
386
+
387
+ ```markdown
388
+ # Decomposição — [FEATURE] Cadastro de Pedidos
389
+ <!-- spec-wave:decomposition v1 issue=360 kind=stories -->
390
+
391
+ ## Story 1 — visualizar meus pedidos
392
+
393
+ **User story:** Como cliente, quero visualizar meus pedidos, para acompanhar entregas
394
+ **Depende de:** —
395
+
396
+ Descrição complementar (contexto, critérios de aceite).
397
+
398
+ ### Task 1.1 — criar endpoint GET /pedidos
399
+
400
+ Corpo técnico.
401
+ ```
402
+
403
+ **Ao editar à mão:**
404
+ - a **posição** manda, não o número escrito — inserir uma Story no meio sem renumerar funciona;
405
+ - `**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;
406
+ - o corpo aceita markdown livre (`## Backend`, cercas de código) — só `## Story N` e `### Task N.M` são estrutura;
407
+ - **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`.
408
+
409
+ ### Guard de idempotência do decompose (`spec-wave:decomposed`)
410
+
411
+ O evento `labeled` pode redisparar (re-add da label, retry de runner). Para não duplicar Stories/Tasks, o `decompose` **pula** quando a issue já tem a label **`spec-wave:decomposed`** ou já tem sub-issues do tipo-alvo (`[STORY]` para Feature, `[TASK]` para RFC). O Action grava a label ao **aplicar** a decomposição. Os workflows ainda usam `concurrency` por issue para serializar runs simultâneos.
412
+
413
+ A `spec-wave:decompose-ready` **não** entra nesse guard: é estado de rascunho pendente, não de decomposição feita.
414
+
415
+ **Para forçar um re-decompose:** remova a label (`gh issue edit <n> --remove-label "spec-wave:decomposed"`), **apague/feche as sub-issues antigas** (senão a detecção por sub-issues pula de novo), apague o `decomposition.md` se quiser um rascunho novo, e re-adicione `spec-wave:decompose`.
416
+
417
+ ### Dependências entre Stories (`Depende de: #N`)
418
+
419
+ O `decompose` grava nas Stories geradas uma linha **`Depende de: #N, #M`** no corpo e cria a relação nativa *blocked by* do GitHub. Essas dependências alimentam:
420
+ - `spec-wave order <feature>` → ordem topológica de execução;
421
+ - `spec-wave implement <feature>` → Stories pendentes implementadas **nessa ordem**; **ciclo de dependências → erro** (corrija as linhas `Depende de:`); dependências **externas** abertas viram aviso no contexto;
422
+ - `spec-wave implement <n>` (Story/Task) → **aviso** no contexto quando uma dependência ainda não está concluída (confirme com o usuário antes de implementar fora de ordem).
423
+
424
+ Não apague a linha `Depende de:` ao editar o corpo de uma Story; para mudar dependências, edite a linha (e/ou a relação *blocked by*).
425
+
426
+ ### Modelo de IA por ação (`ai.models` no `.spec-wave.json`)
427
+
428
+ Cada ação de IA (`spec`, `plan`, `decompose`, `critique`) pode usar um modelo próprio, com fallback em `ai.model` e depois no default do provider:
429
+
430
+ ```json
431
+ {
432
+ "ai": {
433
+ "provider": "anthropic",
434
+ "model": "claude-sonnet-4-6",
435
+ "models": {
436
+ "plan": "claude-opus-4-1",
437
+ "critique": "claude-opus-4-1"
438
+ },
439
+ "escalationModel": "claude-opus-5",
440
+ "maxCritiqueAttempts": 3,
441
+ "modelAliases": {
442
+ "opus": "claude-opus-5",
443
+ "haiku": "claude-haiku-4-5"
444
+ }
445
+ }
446
+ }
447
+ ```
448
+
449
+ - `escalationModel` → modelo usado a partir da **segunda** tentativa da crítica.
450
+ - `maxCritiqueAttempts` → quantas reprovas seguidas antes de exigir revisão humana (`spec-wave:needs-human`).
451
+ - `modelAliases` → apelidos para a label **`spec-wave:model:<apelido>`**.
452
+
453
+ **Precedência do modelo:** `SPEC_WAVE_MODEL` (env) → label `spec-wave:model:<apelido>` → escalada automática da crítica → `ai.models[ação]` → `ai.model` → default do provider.
454
+
455
+ Edite o bloco `ai` no `.spec-wave.json` (e commite) — o `doctor` mostra o provider, o modelo, os apelidos, a escalada e os overrides resolvidos.
456
+
457
+ ### Override de modelo numa execução (`spec-wave:model:<apelido>`)
458
+
459
+ Para reprocessar **uma issue difícil** num modelo mais forte sem editar a configuração do repositório inteiro:
460
+
461
+ ```bash
462
+ # 1. Garanta o apelido em ai.modelAliases (uma vez, commitado)
463
+ # 2. Aplique a label na issue e redispare o gatilho
464
+ gh issue edit 360 --add-label "spec-wave:model:opus"
465
+ gh issue edit 360 --add-label "spec-wave:decompose"
466
+ ```
467
+
468
+ A label vale só para as execuções daquela issue e **vence a escalada automática** (é decisão humana explícita). Apelido desconhecido é ignorado com aviso; duas labels dessas na mesma issue = ambíguo, nenhuma vale.
469
+
470
+ ### Teto de saída (`ai.maxTokens`) e truncamento
471
+
472
+ O teto de tokens de saída é **32.768** por padrão, ajustável globalmente por `ai.maxTokens` e por ação em `ai.maxTokensByAction` (mesma forma de `model`/`models`; `SPEC_WAVE_MAX_TOKENS` na env tem precedência):
473
+
474
+ ```json
475
+ {
476
+ "ai": {
477
+ "maxTokens": 32768,
478
+ "maxTokensByAction": { "spec": 49152 }
479
+ }
480
+ }
481
+ ```
482
+
483
+ **Quando a saída não cabe no teto, a geração FALHA — nada é gravado.** Os dois provedores sinalizam o corte (`finish_reason: "length"` no OpenRouter, `stop_reason: "max_tokens"` na Anthropic) e a CLI transforma isso em erro: um documento cortado no meio de uma frase passaria na validação de seções e valeria menos que documento nenhum. O erro é comentado na issue e a label de gatilho é removida, então basta corrigir e re-aplicar a label.
484
+
485
+ Se acontecer, as saídas são: **aumentar o teto** (`ai.maxTokens`) ou **reduzir o tamanho da issue de origem** — corpo muito grande gera documento muito grande. Modelos com raciocínio (Opus 4.7+, deepseek-r1) gastam parte do teto "pensando" antes de escrever, então o teto precisa cobrir raciocínio + documento.
486
+
487
+ O `validate` também recusa documento com sinal objetivo de corte (bloco de código não fechado, parêntese aberto na última linha) — rede de segurança para documento editado à mão ou gerado por versão antiga da CLI.
488
+
489
+ ---
490
+
491
+ ## Sub-comandos
492
+
493
+ {{SUBCOMANDOS}}
494
+
495
+ ---
496
+
497
+ ## Tech Context (`.github/config/tech_context.yml`)
498
+
499
+ Fonte de verdade estática da stack do sistema (RFC-002 §4). O `generate-plan` lê este arquivo para embasar o plano técnico e usar **APENAS** as tecnologias/serviços nele declarados — sem ele, o plano fica genérico e pode inventar APIs inexistentes. O `npx @spec-wave/cli@latest init` gera um **scaffold de exemplo** que **deve ser adaptado** à stack real. Use este fluxo quando o arquivo estiver ausente ou desatualizado.
500
+
501
+ **Como ajudar a criar (quando não existir):**
502
+
503
+ 1. **Confirme a ausência:** tente `Read .github/config/tech_context.yml`. Se já existir, apenas confirme com o usuário se reflete a stack atual e pule para o fim.
504
+ 2. **Detecte a stack** lendo os arquivos do repositório (use Read; não invente):
505
+ - `package.json` → backend/frontend e libs (ex.: `@nestjs/core`, `next`, `react`, `@prisma/client`, `express`).
506
+ - `pom.xml` / `build.gradle` (Java), `requirements.txt` / `pyproject.toml` (Python), `go.mod` (Go).
507
+ - `prisma/schema.prisma` ou pasta `migrations/` → tabelas e colunas para `database_schemas`.
508
+ - `Dockerfile` / `docker-compose.yml` / charts Helm → `infra`.
509
+ - Procure papéis/roles (enum de RBAC) no código para `security.rbac_roles`.
510
+ 3. **Rascunhe** o YAML seguindo EXATAMENTE este schema (preencha só o que conseguir confirmar; deixe `# TODO` no que faltar — não invente):
511
+ ```yaml
512
+ system_info:
513
+ name: "<nome do sistema>"
514
+ stack:
515
+ backend: "<ex.: Node.js (NestJS v11)>"
516
+ frontend: "<ex.: Next.js 16 (React 19)>"
517
+ database: "<ex.: PostgreSQL (Prisma 5)>"
518
+ infra: "<ex.: Docker / Kubernetes>"
519
+ architecture: "<ex.: Monorepo Nx / Microservices>"
520
+ security:
521
+ auth_protocol: "<ex.: JWT>"
522
+ rbac_roles: ["ADMIN", "..."]
523
+ database_schemas:
524
+ - table: "<tabela>"
525
+ columns: "<col1, col2, ...>"
526
+ existing_services:
527
+ - name: "<serviço>"
528
+ endpoint: "<caminho>"
529
+ auth: "<ex.: JWT, mTLS>"
530
+ internal_libraries:
531
+ - "<lib interna>"
532
+ ```
533
+ 4. **Mostre o rascunho ao usuário e peça confirmação/ajustes** antes de gravar (ele conhece serviços internos e roles que o código pode não revelar).
534
+ 5. **Grave** com Write em `.github/config/tech_context.yml`.
535
+ 6. **Oriente a commitar e pushar** antes de seguir (o Action lê do repo). Sugira ao usuário rodar, via prefixo `!`:
536
+ ```bash
537
+ !git add .github/config/tech_context.yml && git commit -m "chore: tech_context.yml [spec-wave]" && git push
538
+ ```
539
+
540
+ **Desvios pontuais:** para uma Feature específica usar algo fora do padrão (ex.: "usar DynamoDB só aqui"), oriente a adicionar uma seção `## Tech Override` no corpo da issue, com um bloco YAML que será mesclado (deep-merge) sobre o `tech_context.yml`:
541
+
542
+ ````markdown
543
+ ## Tech Override
544
+ ```yaml
545
+ system_info:
546
+ stack:
547
+ database: "DynamoDB"
548
+ ```
549
+ ````
550
+
551
+ ---
552
+
553
+ ## Estrutura de arquivos gerados
554
+
555
+ ```
556
+ docs/
557
+ features/
558
+ <slug-da-feature>/
559
+ spec.md ← gerado quando spec-wave:spec é adicionado (1º)
560
+ plan.md ← gerado quando spec-wave:plan é adicionado (2º, usa a spec)
561
+ decomposition.md ← rascunho gerado quando spec-wave:decompose é adicionado (3º).
562
+ REVISÁVEL e EDITÁVEL à mão; as issues só nascem com
563
+ spec-wave:decompose-apply
564
+ qa-plan.md ← plano de QA gerado quando spec-wave:qa é adicionado (4º,
565
+ com a Feature já em 🧪 QA). Um cenário por critério de
566
+ aceite, seções "## Cenário N — Story #X"; executado
567
+ localmente por `spec-wave qa <issue>`
568
+ dependency-map.json ← grafo de dependências das Stories PRÉ-COMPUTADO,
569
+ escrito pelo decompose --apply e atualizado por
570
+ `order --sync`. É o que deixa order/implement/merge
571
+ consultarem a ordem sem pagar a API por Story
572
+ rfcs/
573
+ <slug-do-rfc>/
574
+ decomposition.md ← mesmo papel, com "## Task N" (RFC não usa spec/plan)
575
+ qa/
576
+ <slug-da-milestone>/
577
+ cycle-<n>/
578
+ report.md ← relatório do ciclo N da trilha de QA (qa-lead run)
579
+ report.json ← o mesmo ciclo, no schema protocol/qa-trail-report.v1.json
580
+ ```
581
+
582
+ O slug é gerado a partir do título da issue: `[FEATURE] Cadastro de Pedidos com PIX` → `cadastro-de-pedidos-com-pix`
583
+
584
+ > ⚠️ O slug vem do **título**. Renomear a Feature entre o rascunho e o apply muda o diretório e o `decomposition.md` antigo fica órfão — o apply reclama que não encontrou o rascunho.