@mir-code/specs-platform 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +460 -0
- package/assets/specs-usage-statusline.sh +77 -0
- package/assets/template/.agents/README.md +123 -0
- package/assets/template/.agents/RUNTIME.md +64 -0
- package/assets/template/.agents/agents/discovery-agent.md +15 -0
- package/assets/template/.agents/agents/drawing-agent.md +15 -0
- package/assets/template/.agents/agents/feature-runner.md +15 -0
- package/assets/template/.agents/agents/refinement-runner.md +15 -0
- package/assets/template/.agents/agents/refinement.md +15 -0
- package/assets/template/.agents/project.md +158 -0
- package/assets/template/.agents/scripts/check-commit.mjs +70 -0
- package/assets/template/.agents/scripts/validate-spec.mjs +345 -0
- package/assets/template/.agents/skills/discovery-agent/SKILL.md +80 -0
- package/assets/template/.agents/skills/discovery-writing/SKILL.md +76 -0
- package/assets/template/.agents/skills/drawing-agent/SKILL.md +85 -0
- package/assets/template/.agents/skills/drawing-writing/SKILL.md +100 -0
- package/assets/template/.agents/skills/execution-protocol/SKILL.md +110 -0
- package/assets/template/.agents/skills/execution-protocol/references/git.md +104 -0
- package/assets/template/.agents/skills/execution-protocol/references/relatorio-halt.md +103 -0
- package/assets/template/.agents/skills/feature-runner/SKILL.md +81 -0
- package/assets/template/.agents/skills/feature-runner/references/divergencias.md +38 -0
- package/assets/template/.agents/skills/feature-runner/references/implementar.md +80 -0
- package/assets/template/.agents/skills/feature-runner/references/localizar.md +46 -0
- package/assets/template/.agents/skills/mermaid-diagramming/SKILL.md +198 -0
- package/assets/template/.agents/skills/prototype-check/SKILL.md +90 -0
- package/assets/template/.agents/skills/refinement/SKILL.md +136 -0
- package/assets/template/.agents/skills/refinement/references/estrutura.md +27 -0
- package/assets/template/.agents/skills/refinement/references/mapear-terreno.md +46 -0
- package/assets/template/.agents/skills/refinement/references/validar-renderizacao.md +29 -0
- package/assets/template/.agents/skills/refinement-runner/SKILL.md +145 -0
- package/assets/template/.agents/skills/requirements-closure/SKILL.md +236 -0
- package/assets/template/.agents/skills/spec-writing/SKILL.md +258 -0
- package/assets/template/.agents/skills/test-strategy/SKILL.md +176 -0
- package/assets/template/.agents/skills/verification/SKILL.md +143 -0
- package/assets/template/.specs/config.json +39 -0
- package/assets/template/.specs/discoveries/meta.json +4 -0
- package/assets/template/.specs/drawings/meta.json +4 -0
- package/assets/template/.specs/specs/_templates/task-backend.md +75 -0
- package/assets/template/.specs/specs/_templates/task-frontend.md +89 -0
- package/assets/template/.specs/specs/_templates/task-integracao.md +72 -0
- package/assets/template/.specs/specs/exemplo/feat-exemplo-primeira-task.md +82 -0
- package/assets/template/.specs/specs/exemplo/meta.json +8 -0
- package/assets/template/.specs/specs/exemplo/overview.md +45 -0
- package/assets/template/.specs/specs/meta.json +4 -0
- package/assets/template/SPECS.md +213 -0
- package/dist/chunk-SOOETS3N.js +3490 -0
- package/dist/chunk-SOOETS3N.js.map +1 -0
- package/dist/cli.js +15 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +69 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/ui/assets/abnfDiagram-VCTEODGH-DYXtkHNq.js +2 -0
- package/dist/ui/assets/abnfDiagram-VCTEODGH-DYXtkHNq.js.map +1 -0
- package/dist/ui/assets/arc-CJs0gz4E.js +2 -0
- package/dist/ui/assets/arc-CJs0gz4E.js.map +1 -0
- package/dist/ui/assets/architectureDiagram-5GKGNRK7-Br7ZNRfe.js +37 -0
- package/dist/ui/assets/architectureDiagram-5GKGNRK7-Br7ZNRfe.js.map +1 -0
- package/dist/ui/assets/blockDiagram-I7D4REHJ-172V7R5o.js +130 -0
- package/dist/ui/assets/blockDiagram-I7D4REHJ-172V7R5o.js.map +1 -0
- package/dist/ui/assets/c4Diagram-7LVT6UL2-B4AYFhRs.js +39 -0
- package/dist/ui/assets/c4Diagram-7LVT6UL2-B4AYFhRs.js.map +1 -0
- package/dist/ui/assets/channel-BfWO3B41.js +2 -0
- package/dist/ui/assets/channel-BfWO3B41.js.map +1 -0
- package/dist/ui/assets/chunk-2Q5K7J3B-B-u7gtZN.js +2 -0
- package/dist/ui/assets/chunk-2Q5K7J3B-B-u7gtZN.js.map +1 -0
- package/dist/ui/assets/chunk-5VM5RSS4-CjFDq_cq.js +16 -0
- package/dist/ui/assets/chunk-5VM5RSS4-CjFDq_cq.js.map +1 -0
- package/dist/ui/assets/chunk-F27PBJKO-BDYeB7B8.js +2 -0
- package/dist/ui/assets/chunk-F27PBJKO-BDYeB7B8.js.map +1 -0
- package/dist/ui/assets/chunk-IMKFNOWR-y2kXPnac.js +232 -0
- package/dist/ui/assets/chunk-IMKFNOWR-y2kXPnac.js.map +1 -0
- package/dist/ui/assets/chunk-JWPE2WC7-DyCryvDN.js +2 -0
- package/dist/ui/assets/chunk-JWPE2WC7-DyCryvDN.js.map +1 -0
- package/dist/ui/assets/chunk-POPQ4Y6H-DeaxKHvR.js +2 -0
- package/dist/ui/assets/chunk-POPQ4Y6H-DeaxKHvR.js.map +1 -0
- package/dist/ui/assets/chunk-SVP7TREG-CmcZEncL.js +89 -0
- package/dist/ui/assets/chunk-SVP7TREG-CmcZEncL.js.map +1 -0
- package/dist/ui/assets/chunk-TICWLB2K-Df1RRXWR.js +207 -0
- package/dist/ui/assets/chunk-TICWLB2K-Df1RRXWR.js.map +1 -0
- package/dist/ui/assets/chunk-XXDRQBXY-ClTat8Q0.js +2 -0
- package/dist/ui/assets/chunk-XXDRQBXY-ClTat8Q0.js.map +1 -0
- package/dist/ui/assets/classDiagram-ZZMXUADV-YTUiu8rF.js +2 -0
- package/dist/ui/assets/classDiagram-ZZMXUADV-YTUiu8rF.js.map +1 -0
- package/dist/ui/assets/classDiagram-v2-VYDZK3BY-YTUiu8rF.js +2 -0
- package/dist/ui/assets/classDiagram-v2-VYDZK3BY-YTUiu8rF.js.map +1 -0
- package/dist/ui/assets/cose-bilkent-JH36ORCC-QvqQLoy5.js +2 -0
- package/dist/ui/assets/cose-bilkent-JH36ORCC-QvqQLoy5.js.map +1 -0
- package/dist/ui/assets/cynefin-OW5HDTMX-BY6w3pAQ.js +179 -0
- package/dist/ui/assets/cynefin-OW5HDTMX-BY6w3pAQ.js.map +1 -0
- package/dist/ui/assets/cynefinDiagram-5FMLGOSQ-luPP4ha1.js +63 -0
- package/dist/ui/assets/cynefinDiagram-5FMLGOSQ-luPP4ha1.js.map +1 -0
- package/dist/ui/assets/cytoscape.esm-Ix0LnXOy.js +332 -0
- package/dist/ui/assets/cytoscape.esm-Ix0LnXOy.js.map +1 -0
- package/dist/ui/assets/dagre-GXQ25YYZ-DhpPwKqq.js +5 -0
- package/dist/ui/assets/dagre-GXQ25YYZ-DhpPwKqq.js.map +1 -0
- package/dist/ui/assets/defaultLocale-DX6XiGOO.js +2 -0
- package/dist/ui/assets/defaultLocale-DX6XiGOO.js.map +1 -0
- package/dist/ui/assets/diagram-S7CK7UJ4-B9wvQM0w.js +31 -0
- package/dist/ui/assets/diagram-S7CK7UJ4-B9wvQM0w.js.map +1 -0
- package/dist/ui/assets/diagram-UQ7AKVKN-gm1M_iZS.js +42 -0
- package/dist/ui/assets/diagram-UQ7AKVKN-gm1M_iZS.js.map +1 -0
- package/dist/ui/assets/diagram-VSXAHHWV-DkEB6nEx.js +4 -0
- package/dist/ui/assets/diagram-VSXAHHWV-DkEB6nEx.js.map +1 -0
- package/dist/ui/assets/diagram-VX7I27RA-Ce2F1bHi.js +25 -0
- package/dist/ui/assets/diagram-VX7I27RA-Ce2F1bHi.js.map +1 -0
- package/dist/ui/assets/diagram-Z3DM3KII-B5ArCh-E.js +25 -0
- package/dist/ui/assets/diagram-Z3DM3KII-B5ArCh-E.js.map +1 -0
- package/dist/ui/assets/ebnfDiagram-PWID7BFC-DgBM80MD.js +2 -0
- package/dist/ui/assets/ebnfDiagram-PWID7BFC-DgBM80MD.js.map +1 -0
- package/dist/ui/assets/erDiagram-RLTQ6QDP-C161af8G.js +100 -0
- package/dist/ui/assets/erDiagram-RLTQ6QDP-C161af8G.js.map +1 -0
- package/dist/ui/assets/flowDiagram-HODETNUW-B8N_WyW5.js +169 -0
- package/dist/ui/assets/flowDiagram-HODETNUW-B8N_WyW5.js.map +1 -0
- package/dist/ui/assets/ganttDiagram-EL5Y4UJY-CD2RJpTb.js +293 -0
- package/dist/ui/assets/ganttDiagram-EL5Y4UJY-CD2RJpTb.js.map +1 -0
- package/dist/ui/assets/gitGraphDiagram-WWUBYQGX-BrDAzeFT.js +107 -0
- package/dist/ui/assets/gitGraphDiagram-WWUBYQGX-BrDAzeFT.js.map +1 -0
- package/dist/ui/assets/index-CVWRdirI.css +32 -0
- package/dist/ui/assets/index-DoR97Zqf.js +408 -0
- package/dist/ui/assets/index-DoR97Zqf.js.map +1 -0
- package/dist/ui/assets/infoDiagram-27XIBGKW-HYGaMzrA.js +3 -0
- package/dist/ui/assets/infoDiagram-27XIBGKW-HYGaMzrA.js.map +1 -0
- package/dist/ui/assets/init-Gi6I4Gst.js +2 -0
- package/dist/ui/assets/init-Gi6I4Gst.js.map +1 -0
- package/dist/ui/assets/ishikawaDiagram-5VMMS53U-DXTLlBiw.js +71 -0
- package/dist/ui/assets/ishikawaDiagram-5VMMS53U-DXTLlBiw.js.map +1 -0
- package/dist/ui/assets/journeyDiagram-3NMN7TZE-DSJ8QN1S.js +140 -0
- package/dist/ui/assets/journeyDiagram-3NMN7TZE-DSJ8QN1S.js.map +1 -0
- package/dist/ui/assets/kanban-definition-UXKFOSKX-Bm5iz0k3.js +90 -0
- package/dist/ui/assets/kanban-definition-UXKFOSKX-Bm5iz0k3.js.map +1 -0
- package/dist/ui/assets/katex-C5jXJg4s.js +258 -0
- package/dist/ui/assets/katex-C5jXJg4s.js.map +1 -0
- package/dist/ui/assets/layout-DfJgW6eG.js +2 -0
- package/dist/ui/assets/layout-DfJgW6eG.js.map +1 -0
- package/dist/ui/assets/linear-B_kyVotV.js +2 -0
- package/dist/ui/assets/linear-B_kyVotV.js.map +1 -0
- package/dist/ui/assets/mermaid-block-CUJSBQFx.js +2 -0
- package/dist/ui/assets/mermaid-block-CUJSBQFx.js.map +1 -0
- package/dist/ui/assets/mermaid.core-ExHG1WnM.js +313 -0
- package/dist/ui/assets/mermaid.core-ExHG1WnM.js.map +1 -0
- package/dist/ui/assets/mindmap-definition-YA3MSWOX-B1Hh9dQz.js +97 -0
- package/dist/ui/assets/mindmap-definition-YA3MSWOX-B1Hh9dQz.js.map +1 -0
- package/dist/ui/assets/ordinal-Cboi1Yqb.js +2 -0
- package/dist/ui/assets/ordinal-Cboi1Yqb.js.map +1 -0
- package/dist/ui/assets/pegDiagram-XKGWAZYB-x242yOd7.js +2 -0
- package/dist/ui/assets/pegDiagram-XKGWAZYB-x242yOd7.js.map +1 -0
- package/dist/ui/assets/pieDiagram-E7YTZNPT-Dl-YP7Xs.js +40 -0
- package/dist/ui/assets/pieDiagram-E7YTZNPT-Dl-YP7Xs.js.map +1 -0
- package/dist/ui/assets/quadrantDiagram-AXDQQJYC-CMJ920V9.js +8 -0
- package/dist/ui/assets/quadrantDiagram-AXDQQJYC-CMJ920V9.js.map +1 -0
- package/dist/ui/assets/railroadDiagram-O6MQD6OU-1kV83y5t.js +2 -0
- package/dist/ui/assets/railroadDiagram-O6MQD6OU-1kV83y5t.js.map +1 -0
- package/dist/ui/assets/requirementDiagram-BXWQKSXE-BFd8ZZD3.js +85 -0
- package/dist/ui/assets/requirementDiagram-BXWQKSXE-BFd8ZZD3.js.map +1 -0
- package/dist/ui/assets/sankeyDiagram-P5KCCOFB-C0LZevnf.js +41 -0
- package/dist/ui/assets/sankeyDiagram-P5KCCOFB-C0LZevnf.js.map +1 -0
- package/dist/ui/assets/sequenceDiagram-WJ2MYXX4-BasIXLJ0.js +163 -0
- package/dist/ui/assets/sequenceDiagram-WJ2MYXX4-BasIXLJ0.js.map +1 -0
- package/dist/ui/assets/sizeCapture-INFHLROL-qAtnqB7N.js +2 -0
- package/dist/ui/assets/sizeCapture-INFHLROL-qAtnqB7N.js.map +1 -0
- package/dist/ui/assets/stateDiagram-D77RDMKH-CllWDWZP.js +2 -0
- package/dist/ui/assets/stateDiagram-D77RDMKH-CllWDWZP.js.map +1 -0
- package/dist/ui/assets/stateDiagram-v2-MP3YSRHH-Dwntf8Tk.js +2 -0
- package/dist/ui/assets/stateDiagram-v2-MP3YSRHH-Dwntf8Tk.js.map +1 -0
- package/dist/ui/assets/swimlanes-42K2YHIH-Bgt0KslH.js +2 -0
- package/dist/ui/assets/swimlanes-42K2YHIH-Bgt0KslH.js.map +1 -0
- package/dist/ui/assets/swimlanesDiagram-VR7AAH4N-C9abicdw.js +9 -0
- package/dist/ui/assets/swimlanesDiagram-VR7AAH4N-C9abicdw.js.map +1 -0
- package/dist/ui/assets/timeline-definition-24CTP7MA-BYO2h9Qr.js +121 -0
- package/dist/ui/assets/timeline-definition-24CTP7MA-BYO2h9Qr.js.map +1 -0
- package/dist/ui/assets/vennDiagram-4TSXK5OY-ZzyiwIUi.js +35 -0
- package/dist/ui/assets/vennDiagram-4TSXK5OY-ZzyiwIUi.js.map +1 -0
- package/dist/ui/assets/wardleyDiagram-VM6X3IG4-DfjKCK0N.js +79 -0
- package/dist/ui/assets/wardleyDiagram-VM6X3IG4-DfjKCK0N.js.map +1 -0
- package/dist/ui/assets/xychartDiagram-S5SC5T6Z-Z7daOfmM.js +8 -0
- package/dist/ui/assets/xychartDiagram-S5SC5T6Z-Z7daOfmM.js.map +1 -0
- package/dist/ui/favicon.svg +6 -0
- package/dist/ui/index.html +21 -0
- package/package.json +70 -0
- package/scripts/copy-ui.mjs +21 -0
- package/scripts/fix-node-pty-perms.cjs +73 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: refinement-runner
|
|
3
|
+
description: Refinamento com execução imediata — entende a atividade, mapeia o terreno, esgota todas as dúvidas antes de tocar em código, implementa e PARA antes de commitar para code review humano, sem criar nem alterar documento em `.specs/specs/`. Carregue ao pedir "refinar e executar", "fazer direto", ou ao descrever uma atividade para ver implementada sem passar por spec.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# refinement-runner
|
|
7
|
+
|
|
8
|
+
Existe para o caso em que **documentar a task custa mais do que fazê-la**: você faz o trabalho de
|
|
9
|
+
refinamento — entender, mapear o terreno, fechar o escopo, **tirar todas as dúvidas** — e em
|
|
10
|
+
seguida executa, sem produzir nenhum documento em `.specs/specs/`.
|
|
11
|
+
|
|
12
|
+
É a fusão do `refinement` (entender + mapear + fechar requisitos) com o `feature-runner`
|
|
13
|
+
(implementar + verificar + halt). Quando a atividade for grande o bastante para merecer spec
|
|
14
|
+
versionada, **pare e recomende** o `refinement`.
|
|
15
|
+
|
|
16
|
+
Equivalências de tools Claude Code ↔ Cursor: `.agents/RUNTIME.md`.
|
|
17
|
+
|
|
18
|
+
## Ponto de partida obrigatório
|
|
19
|
+
|
|
20
|
+
**Carregue a skill `execution-protocol` antes de qualquer coisa** — princípios invioláveis,
|
|
21
|
+
verificação do repositório, convenções de código, ciclo halt → ajustar → complete.
|
|
22
|
+
|
|
23
|
+
Além dela: **nunca crie nem edite arquivos em `.specs/specs/`.** Nem task, nem `overview.md`, nem
|
|
24
|
+
`meta.json`. Seu entregável é código no working tree. Precisa de documentação? é sinal de que a
|
|
25
|
+
atividade deveria ter ido para o `refinement` — diga isso.
|
|
26
|
+
|
|
27
|
+
## Skills por camada
|
|
28
|
+
|
|
29
|
+
| Carregue | Quando |
|
|
30
|
+
|---|---|
|
|
31
|
+
| `execution-protocol` | **sempre**, antes de tudo |
|
|
32
|
+
| `requirements-closure` | **sempre** — é ela que define quando o escopo está fechado, e aqui não há spec para conferir depois |
|
|
33
|
+
| `test-strategy` | a atividade produz código testável |
|
|
34
|
+
| `verification` | a atividade produz código com teste automatizado |
|
|
35
|
+
| `input-security` | a atividade toca input do usuário (opcional — só se o projeto adotar essa skill) |
|
|
36
|
+
| `ui-standards` | a atividade cria ou altera tela/componente (opcional — só se o projeto adotar essa skill) |
|
|
37
|
+
| `prototype-check` | a atividade tem entregável visual |
|
|
38
|
+
|
|
39
|
+
`spec-writing` **não** é carregada: você não escreve spec. O que a substitui é a skill
|
|
40
|
+
`requirements-closure` como régua do escopo consolidado da Fase 3.
|
|
41
|
+
|
|
42
|
+
## Fluxo
|
|
43
|
+
|
|
44
|
+
Ponto de entrada pelo contexto: pedido novo ⇒ **0**; "Ajustar: ..." e "Complete" ⇒ ciclos do
|
|
45
|
+
`execution-protocol`. Aqui a entrega é única, então não há halt intermediário nem "Prosseguir":
|
|
46
|
+
o halt da Fase 7 já é o final, e é ele que oferece "Complete".
|
|
47
|
+
|
|
48
|
+
### 0. Protótipo (quando a atividade for visual)
|
|
49
|
+
|
|
50
|
+
Antes de ler código, **descubra qual ferramenta de protótipo o projeto usa** — o bloco `prototype`
|
|
51
|
+
do `.specs/config.json`, sobrescrito pelo `meta.json` da feature quando ele declarar o seu:
|
|
52
|
+
|
|
53
|
+
- `tool: "claude-design"` ⇒ canvas do Claude Design, endereçado pela `url`; as decisões versionadas
|
|
54
|
+
estão em `<designDir>/README.md`. Não há node ID nem MCP — referencie artboards pelo nome.
|
|
55
|
+
- `tool: "pencil"` ⇒ arquivo `.pen` (encriptado, nunca `Read`/`Grep`); a consulta é pelo Pencil MCP,
|
|
56
|
+
e é ali que você **obtém os node IDs** dos nós alvo.
|
|
57
|
+
- sem bloco ⇒ o projeto não tem protótipo: siga sem fase visual e registre isso no relatório.
|
|
58
|
+
|
|
59
|
+
Carregue `prototype-check` para o fluxo de consulta. Sem acesso ao protótipo para uma tela que
|
|
60
|
+
deveria existir, **pare e informe o usuário**.
|
|
61
|
+
|
|
62
|
+
### 1. Entender a atividade
|
|
63
|
+
|
|
64
|
+
Identifique **o quê**, **por quê** e **onde** (frontend, backend, ambos, infra, docs).
|
|
65
|
+
|
|
66
|
+
**Teste de tamanho — faça já.** Se a atividade toca mais de uma camada com contratos novos entre
|
|
67
|
+
elas, ou se você já enxerga que ela se quebraria em três ou mais tasks independentes, **pare** e
|
|
68
|
+
recomende o `refinement` (com o `feature-runner` depois). Explique o porquê em uma linha e deixe a
|
|
69
|
+
decisão com o usuário via `AskUserQuestion` / `AskQuestion`: "Refinar e documentar primeiro" vs.
|
|
70
|
+
"Seguir direto mesmo assim".
|
|
71
|
+
|
|
72
|
+
### 2. Mapear o terreno
|
|
73
|
+
|
|
74
|
+
Siga [mapear-terreno.md](../refinement/references/mapear-terreno.md) — inclusive a leitura
|
|
75
|
+
**obrigatória** de `.specs/STATE.md` `## Decisions` antes de qualquer decisão arquitetural.
|
|
76
|
+
|
|
77
|
+
Duas paradas específicas desta skill:
|
|
78
|
+
|
|
79
|
+
- **Reuso antes de criação.** Procure utilitários, tipos compartilhados, componentes e hooks que já
|
|
80
|
+
existem antes de planejar código novo.
|
|
81
|
+
- **Task já documentada.** Encontrou em `.specs/specs/` uma task que cobre o que foi pedido?
|
|
82
|
+
**pare e avise**: o caminho certo ali é o `feature-runner`, não você.
|
|
83
|
+
|
|
84
|
+
### 3. Esgotar as dúvidas — o portão
|
|
85
|
+
|
|
86
|
+
Esta é a fase que justifica sua existência. **Você não passa daqui com pergunta em aberto.** Sem
|
|
87
|
+
spec escrita, não há segunda chance de pegar a ambiguidade: ela vira código errado direto.
|
|
88
|
+
|
|
89
|
+
1. **Rode o sweep das 9 dimensões implícitas** da skill `requirements-closure`. Cada dimensão
|
|
90
|
+
resolve para um requisito **ou** um `N/A porque <motivo>`. Nunca em branco. É o que impede a
|
|
91
|
+
pergunta que ninguém lembrou de fazer — falha de dependência externa, idempotência, ciclo de
|
|
92
|
+
vida do dado.
|
|
93
|
+
2. **Classifique cada decisão** que a implementação vai exigir:
|
|
94
|
+
- **Decidível pelo código** — o projeto já tem convenção, padrão análogo ou tipo pronto. Decida
|
|
95
|
+
sozinho e registre como decisão no relatório. Não pergunte o óbvio.
|
|
96
|
+
- **Ambígua de verdade** — escopo, comportamento esperado, contrato de API, biblioteca, UX,
|
|
97
|
+
tratamento de erro, regra de negócio, caminho triste. **Pergunte.**
|
|
98
|
+
3. **Dispare as perguntas agrupadas** (`AskUserQuestion` / `AskQuestion`, até 4 por chamada), cada
|
|
99
|
+
uma com 2–4 opções concretas e uma recomendação quando você tiver opinião informada.
|
|
100
|
+
|
|
101
|
+
Nunca pergunte "posso prosseguir?". Só saia daqui quando a próxima pergunta que você consegue
|
|
102
|
+
formular for sobre algo fora do escopo.
|
|
103
|
+
|
|
104
|
+
### 4. Fechar o escopo
|
|
105
|
+
|
|
106
|
+
Consolide **para si mesmo** (ainda sem escrever arquivo nenhum), aplicando o portão de fechamento
|
|
107
|
+
da skill `requirements-closure`:
|
|
108
|
+
|
|
109
|
+
- o que entra e o que **não** entra;
|
|
110
|
+
- os critérios de aceite em EARS, objetivos e ancorados em código que existe de verdade;
|
|
111
|
+
- a tabela de premissas — o que você decidiu sozinho, com default e racional;
|
|
112
|
+
- os arquivos que você espera tocar;
|
|
113
|
+
- o gate que vai fechar a entrega (skill `test-strategy`);
|
|
114
|
+
- a checklist de code review que vai para o relatório de halt.
|
|
115
|
+
|
|
116
|
+
**Esse consolidado é o que substitui o documento de spec** e é o que você reporta no halt.
|
|
117
|
+
|
|
118
|
+
### 5. Verificar o repositório
|
|
119
|
+
|
|
120
|
+
Skill `execution-protocol`.
|
|
121
|
+
|
|
122
|
+
### 6. Implementar
|
|
123
|
+
|
|
124
|
+
Siga [implementar.md](../feature-runner/references/implementar.md), pulando o passo de marcar
|
|
125
|
+
`in-progress` (não há arquivo de task). Os critérios de aceite são os da Fase 4.
|
|
126
|
+
|
|
127
|
+
Descobriu na implementação que uma decisão da Fase 3 não se sustenta? **volte e pergunte** — não
|
|
128
|
+
improvise uma saída.
|
|
129
|
+
|
|
130
|
+
### 7. Verificação e halt
|
|
131
|
+
|
|
132
|
+
Skill `verification`, depois
|
|
133
|
+
[relatorio-halt.md](../execution-protocol/references/relatorio-halt.md). Deixe explícito no
|
|
134
|
+
relatório que **nenhum arquivo em `.specs/specs/` foi criado ou alterado**, e inclua o escopo
|
|
135
|
+
consolidado da Fase 4 junto com a tabela de premissas.
|
|
136
|
+
|
|
137
|
+
### 8. Ajustar / Complete
|
|
138
|
+
|
|
139
|
+
Ciclos do `execution-protocol`. Sem arquivo de task, o commit não carrega `Refs:` nem atualização
|
|
140
|
+
de status — a mensagem descreve o que foi feito.
|
|
141
|
+
|
|
142
|
+
## Specs Platform
|
|
143
|
+
|
|
144
|
+
O botão "+" da sidebar pergunta entre **Refinamento** (`refinement`) e **Refinamento + execução**
|
|
145
|
+
(você). A UI envia `POST /api/jobs` com `kind: refinement-runner` e a CLI escolhida.
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: requirements-closure
|
|
3
|
+
description: Como fechar requisitos sem deixar ambiguidade em silêncio — notação EARS para critérios de aceite, IDs de requisito rastreáveis, o sweep das 9 dimensões implícitas (validação, falha parcial, idempotência, auth/rate-limit, concorrência, ciclo de vida do dado, observabilidade, falha de dependência externa, transição de estado), o portão de fechamento e a tabela de premissas. Carregue antes de redigir critérios de aceite em qualquer refinamento, com ou sem spec escrita.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Fechamento de requisitos
|
|
7
|
+
|
|
8
|
+
Esta skill responde a uma pergunta só: **este requisito pode ser lido de duas formas?** Enquanto
|
|
9
|
+
puder, ele não está pronto — nem para virar spec, nem para virar código.
|
|
10
|
+
|
|
11
|
+
Vale para quem escreve spec (`refinement`) e para quem fecha escopo de cabeça (`refinement-runner`).
|
|
12
|
+
O `spec-writing` diz *onde* o critério mora no arquivo; esta skill diz *como ele é escrito e quando
|
|
13
|
+
está completo*.
|
|
14
|
+
|
|
15
|
+
## Fatos você descobre, decisões você pergunta
|
|
16
|
+
|
|
17
|
+
Antes de perguntar qualquer coisa ao usuário, resolva sozinho tudo que é descobrível lendo o
|
|
18
|
+
ambiente. Pergunta que o código já responde queima a atenção dele e um turno.
|
|
19
|
+
|
|
20
|
+
**Cadeia de verificação de conhecimento** — em ordem estrita, nunca pule para o passo 5:
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
1. Código → o que já existe, convenções e padrões em uso no monorepo
|
|
24
|
+
2. Docs → CLAUDE.md (raiz e apps), .specs/specs/, .specs/discoveries/, .specs/STATE.md
|
|
25
|
+
3. Context7 → doc atual da lib (subagente com MCP context7) quando a decisão depende de versão
|
|
26
|
+
4. Busca web → doc oficial, fonte reputada
|
|
27
|
+
5. Declarar incerteza → "não tenho certeza sobre X — meu raciocínio é Y, confirme"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**Nunca invente.** API, comportamento de lib, nome de campo, formato de payload: não achou? diga
|
|
31
|
+
"não sei" ou "não encontrei documentação". Requisito fabricado se propaga para o critério de
|
|
32
|
+
aceite, para o teste e para o código — e o teste passa provando a coisa errada.
|
|
33
|
+
|
|
34
|
+
Reserve as perguntas para o que é genuinamente decisão do usuário: escopo, prioridade,
|
|
35
|
+
comportamento de produto, trade-off, o que fazer no caminho triste.
|
|
36
|
+
|
|
37
|
+
## O que é critério de aceite, e o que não é
|
|
38
|
+
|
|
39
|
+
Antes de escrever, decida **se aquilo é critério**. EARS não protege contra isso: dá para escrever
|
|
40
|
+
"QUANDO o body é validado ENTÃO o schema DEVE usar `.strict()`" — está em EARS e continua sendo
|
|
41
|
+
decisão de estrutura interna, não entrega.
|
|
42
|
+
|
|
43
|
+
**Critério de aceite é comportamento observável na fronteira da entrega:** resposta de API, o que
|
|
44
|
+
aparece na tela, o que fica persistido, invariante que precisa valer. Ele descreve **o que a
|
|
45
|
+
entrega faz**, não como ela é por dentro.
|
|
46
|
+
|
|
47
|
+
### O teste do refactor
|
|
48
|
+
|
|
49
|
+
> **Se eu refatorar sem mudar comportamento, esse item quebra?**
|
|
50
|
+
> Sim ⇒ **não é critério de aceite.** É nota de implementação ou item de code review.
|
|
51
|
+
|
|
52
|
+
Um segundo teste, equivalente: *um teste que desconhece a implementação consegue provar isso?* Se
|
|
53
|
+
a única forma de "verificar" é abrir o arquivo e olhar, é inspeção — e inspeção mora na
|
|
54
|
+
`## Code Review Checklist`.
|
|
55
|
+
|
|
56
|
+
| Não é critério (vai para a Code Review Checklist) | É critério (fica no bloco `<details>`) |
|
|
57
|
+
|---|---|
|
|
58
|
+
| `CreateQueryRequestDTO` ganha `objective?: QueryObjective` | QUANDO `POST /queries` recebe body sem `objective` ENTÃO o sistema DEVE persistir `BUY` |
|
|
59
|
+
| O schema do controller segue `.strict()` | SE o body traz campo desconhecido ENTÃO o sistema DEVE responder 400 sem processar a requisição |
|
|
60
|
+
| A entidade não expõe setter para o campo | QUANDO uma query `COMPLETED` é reprocessada ENTÃO o sistema DEVE manter o `objective` original |
|
|
61
|
+
| Teste mora em `__tests__/unit/useCases/...` | O sistema DEVE cobrar o mesmo preço para a mesma placa e SKU, qualquer que seja o `objective` |
|
|
62
|
+
| Nenhum índice novo na tabela | O sistema DEVE manter o parâmetro fora da chave de cache e de dedupe |
|
|
63
|
+
|
|
64
|
+
Repare no padrão: a coluna da direita sobrevive a renomear DTO, mover arquivo e trocar ORM. A da
|
|
65
|
+
esquerda não.
|
|
66
|
+
|
|
67
|
+
### A exceção: quando a estrutura é a entrega
|
|
68
|
+
|
|
69
|
+
A regra não é "nunca cite arquivo". É *a estrutura é o produto, ou o caminho até ele?*
|
|
70
|
+
|
|
71
|
+
Numa task cuja entrega **é** a migration, `coluna objective com default BUY, sem backfill` é o
|
|
72
|
+
desfecho — é o que o usuário da task está pedindo, e um teste de schema prova. Numa task de caso de
|
|
73
|
+
uso, a mesma frase é detalhe de como você escolheu persistir.
|
|
74
|
+
|
|
75
|
+
Na dúvida, pergunte: **se isso mudar, o consumidor da entrega percebe?** Sim ⇒ critério.
|
|
76
|
+
|
|
77
|
+
### Por que isso importa aqui
|
|
78
|
+
|
|
79
|
+
1. **O Verifier exige evidência.** A skill `verification` cobra `file:line` + a expressão da
|
|
80
|
+
asserção para cada critério. Nota de implementação não tem asserção que prove valor — ela
|
|
81
|
+
entope a tabela de cobertura com linhas que nunca fecham.
|
|
82
|
+
2. **Critério estrutural envelhece rápido.** Ele quebra no primeiro refactor e a spec passa a
|
|
83
|
+
mentir, o que é pior do que não ter dito nada.
|
|
84
|
+
3. **Hoje isso está escrito duas vezes.** Nas specs atuais, os itens de padrão aparecem no bloco
|
|
85
|
+
`<details>` **e** repetidos, condensados, na `## Code Review Checklist`. Escrevendo cada coisa
|
|
86
|
+
no lugar dela, a duplicação some.
|
|
87
|
+
|
|
88
|
+
## Critérios de aceite em EARS
|
|
89
|
+
|
|
90
|
+
Todo critério de aceite resolve para **exatamente um** destes padrões. O verbo **DEVE** é
|
|
91
|
+
obrigatório em todos — é ele que marca a linha como requisito verificável.
|
|
92
|
+
|
|
93
|
+
| Padrão | Palavra-chave | Forma | Para |
|
|
94
|
+
|---|---|---|---|
|
|
95
|
+
| Ubíquo | (nenhuma) | O sistema DEVE `<resposta>` | Invariante sempre válida |
|
|
96
|
+
| Dirigido a evento | QUANDO | QUANDO `<gatilho>` ENTÃO o sistema DEVE `<resposta>` | Reação a um evento discreto |
|
|
97
|
+
| Dirigido a estado | ENQUANTO | ENQUANTO `<estado>` o sistema DEVE `<resposta>` | Comportamento durante um estado |
|
|
98
|
+
| Opcional | ONDE | ONDE `<capacidade presente>` o sistema DEVE `<resposta>` | Atrás de flag ou capacidade opcional |
|
|
99
|
+
| Indesejado | SE / ENTÃO | SE `<condição indesejada>` ENTÃO o sistema DEVE `<resposta>` | Erro, falha, input inválido, timeout |
|
|
100
|
+
| Composto | combinação | ENQUANTO `<estado>`, QUANDO `<gatilho>` o sistema DEVE `<resposta>` | Comportamento mais rico |
|
|
101
|
+
|
|
102
|
+
**Por que seis padrões e não um.** Com só `QUANDO/ENTÃO`, falha e transição de estado viram nota
|
|
103
|
+
de rodapé em prosa. Com `SE/ENTÃO` e `ENQUANTO` de primeira classe, elas viram critério — e
|
|
104
|
+
critério vira teste.
|
|
105
|
+
|
|
106
|
+
Regras:
|
|
107
|
+
|
|
108
|
+
- **Um comportamento por critério.** Nunca junte dois com "e também".
|
|
109
|
+
- **Valor concreto, nunca advérbio.** `DEVE responder 409 com `errorCode: EMAIL_ALREADY_REGISTERED``,
|
|
110
|
+
não "DEVE tratar graciosamente". "Rápido", "amigável" e "corretamente" não são verificáveis.
|
|
111
|
+
- **Desfecho preciso.** O critério define o valor esperado: status, campo, mensagem, estado
|
|
112
|
+
persistido. Sem desfecho preciso o teste vira asserção vaga que passa com implementação errada.
|
|
113
|
+
- **Ancorado em código real.** Cite rota, componente, tipo e tabela que existem — salvo quando a
|
|
114
|
+
task é justamente criá-los, e aí seja explícito ("Criar `POST /api/v1/vehicles`").
|
|
115
|
+
- **Sem token visual fixo** (hex, px, peso de fonte): vive no protótipo, não na spec.
|
|
116
|
+
|
|
117
|
+
Exemplos:
|
|
118
|
+
|
|
119
|
+
```markdown
|
|
120
|
+
- [ ] QUANDO o usuário submete CPF já cadastrado ENTÃO o sistema DEVE responder 409 com
|
|
121
|
+
`errorCode: CPF_ALREADY_REGISTERED` e não criar registro em `users`
|
|
122
|
+
- [ ] SE o provedor veicular exceder 5s ENTÃO o sistema DEVE abortar a chamada, registrar
|
|
123
|
+
`provider_timeout` no log e responder 504 com mensagem genérica
|
|
124
|
+
- [ ] ENQUANTO a consulta estiver em `processing` o sistema DEVE exibir o skeleton do relatório
|
|
125
|
+
em vez do conteúdo parcial
|
|
126
|
+
- [ ] O sistema DEVE persistir o identificador sensível como hash truncado, nunca em claro
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## IDs de requisito
|
|
130
|
+
|
|
131
|
+
Todo critério de aceite de task **Large** (5+ critérios ou 2+ camadas) carrega um ID rastreável.
|
|
132
|
+
|
|
133
|
+
- Formato: `<CATEGORIA>-<NN>` em maiúsculas — `CADASTRO-01`, `CONSULTA-07`, `CMS-03`.
|
|
134
|
+
- A categoria é derivada do slug da feature, não da task.
|
|
135
|
+
- Numeração sequencial por feature, **permanente**: não reaproveite número de requisito removido.
|
|
136
|
+
- No arquivo da task o ID prefixa o critério: `- [ ] **CADASTRO-03** — QUANDO ... ENTÃO ...`.
|
|
137
|
+
|
|
138
|
+
O ID é o que permite ao `verification` dizer "CADASTRO-03 coberto em
|
|
139
|
+
`tests/unit/auth-use-cases.test.ts:88`" em vez de "os testes parecem cobrir o cadastro".
|
|
140
|
+
|
|
141
|
+
Task pequena e coesa (≤4 critérios, uma camada) pode dispensar IDs. Declare isso no relatório.
|
|
142
|
+
|
|
143
|
+
## Sweep das 9 dimensões implícitas
|
|
144
|
+
|
|
145
|
+
O que mais falta em spec não é o que foi escrito errado — é o que ninguém lembrou de perguntar.
|
|
146
|
+
Antes de fechar o escopo, passe por **cada** dimensão abaixo. Cada uma resolve para um requisito
|
|
147
|
+
**ou** para um `N/A porque <motivo>` explícito. **Campo em branco é proibido.**
|
|
148
|
+
|
|
149
|
+
| Dimensão | O que cobrir |
|
|
150
|
+
|---|---|
|
|
151
|
+
| Validação e limites de input | formato, tamanho máximo, alfabeto permitido, sanitização |
|
|
152
|
+
| Falha e falha parcial | timeout, gravação parcial, rollback, o que o usuário vê quando quebra no meio |
|
|
153
|
+
| Idempotência / retry / duplicata | reenvio seguro, chave de deduplicação, clique duplo no submit |
|
|
154
|
+
| Fronteira de auth e rate limit | quem pode chamar, o que acontece sem token, throttle |
|
|
155
|
+
| Concorrência e ordenação | corrida entre requisições, garantia de ordem, lock |
|
|
156
|
+
| Ciclo de vida do dado | TTL, expiração, arquivamento, deleção, o que acontece com dado órfão |
|
|
157
|
+
| Observabilidade | o que é logado, com que nível, qual métrica, correlação de request |
|
|
158
|
+
| Falha de dependência externa | provedor veicular fora do ar, gateway de pagamento recusando, fallback, circuit breaker |
|
|
159
|
+
| Integridade de transição de estado | transições válidas, guarda contra transição ilegal, estado terminal |
|
|
160
|
+
|
|
161
|
+
Profundidade pelo tamanho da atividade:
|
|
162
|
+
|
|
163
|
+
- **Grande / complexa** (2+ camadas, contrato novo, ou 3+ tasks): **todas** as 9 dimensões,
|
|
164
|
+
cada uma com requisito ou `N/A porque`.
|
|
165
|
+
- **Média** (uma camada, escopo claro): só as dimensões obviamente presentes no domínio da task;
|
|
166
|
+
colapse o resto em uma linha `demais dimensões N/A para este escopo`.
|
|
167
|
+
- **Pequena** (ajuste pontual, ≤3 arquivos): pule o sweep.
|
|
168
|
+
|
|
169
|
+
O `N/A porque` é **obrigatório** e não é burocracia: é ele que impede inventar requisito só para
|
|
170
|
+
preencher a tabela. `Concorrência: N/A porque a operação é um GET sem efeito colateral` é uma
|
|
171
|
+
resposta completa.
|
|
172
|
+
|
|
173
|
+
Bound: o sweep é limitado ao escopo **desta** atividade. Ele esclarece requisito existente, nunca
|
|
174
|
+
inventa capacidade nova — "Fora de escopo" continua sendo o contrapeso.
|
|
175
|
+
|
|
176
|
+
> Em produto que depende de integração externa, as dimensões que mais mordem são **falha de
|
|
177
|
+
> dependência externa** (provedor
|
|
178
|
+
> veicular, gateway de pagamento), **idempotência** (webhook de pagamento reentregue) e **ciclo de
|
|
179
|
+
> vida do dado** (resultado em cache, identificador sensível, expiração de artefato gerado). Não
|
|
180
|
+
> passe batido nelas.
|
|
181
|
+
|
|
182
|
+
## Portão de fechamento (antes de apresentar o escopo)
|
|
183
|
+
|
|
184
|
+
Três checagens. Enquanto qualquer item ficar aberto e não registrado, o escopo **não** vai para
|
|
185
|
+
aprovação nem para implementação.
|
|
186
|
+
|
|
187
|
+
1. **Ambiguidade e precisão.** Todo critério tem uma leitura só **e** um desfecho preciso. Falhou
|
|
188
|
+
em qualquer das duas: resolva com o usuário, quebre em dois critérios, ou registre como
|
|
189
|
+
premissa com o default escolhido e o racional.
|
|
190
|
+
2. **Fechamento de questões em aberto.** Enumere toda decisão que surgiu durante o refinamento.
|
|
191
|
+
Cada uma foi **resolvida com o usuário** ou virou **premissa registrada**. Nada segue sem marca.
|
|
192
|
+
3. **Gray area recusada vira premissa.** O que o usuário não quis discutir, ou que nem chegou a
|
|
193
|
+
ser discutido, é escrito na tabela de premissas com o default do agente e o motivo — nunca
|
|
194
|
+
descartado em silêncio.
|
|
195
|
+
|
|
196
|
+
Escala pelo tamanho: **grande/complexa** = portão completo; **média** = resolva as ambiguidades
|
|
197
|
+
óbvias e registre o resto como premissa; **pequena** = pule.
|
|
198
|
+
|
|
199
|
+
## Tabela de premissas e questões em aberto
|
|
200
|
+
|
|
201
|
+
Vive num bloco `<details>` chamado **Premissas e questões em aberto**, logo antes do bloco de
|
|
202
|
+
Testes (ver `spec-writing`). No `refinement-runner`, que não escreve spec, ela vai no relatório
|
|
203
|
+
de halt.
|
|
204
|
+
|
|
205
|
+
```markdown
|
|
206
|
+
<details>
|
|
207
|
+
<summary>Premissas e questões em aberto</summary>
|
|
208
|
+
|
|
209
|
+
| Premissa / decisão | Default escolhido | Racional | Confirmado? |
|
|
210
|
+
|---|---|---|---|
|
|
211
|
+
| Webhook reentregue pelo gateway | dedup por `providerEventId` único | o gateway não garante entrega única | não |
|
|
212
|
+
|
|
213
|
+
**Questões em aberto:** nenhuma — todas resolvidas ou registradas acima.
|
|
214
|
+
|
|
215
|
+
</details>
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
A linha `**Questões em aberto:**` é obrigatória. Se houver questão viva de verdade, liste-a e diga
|
|
219
|
+
a quem ela é endereçada — mas então o escopo não está fechado, e isso precisa aparecer no relatório
|
|
220
|
+
como bloqueio, não como nota de rodapé.
|
|
221
|
+
|
|
222
|
+
## Verificação determinística
|
|
223
|
+
|
|
224
|
+
Antes de apresentar a spec, rode:
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
node .agents/scripts/validate-spec.mjs .specs/specs/<slug>/feat-<slug>-<task>.md
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
Ele checa a metade estrutural deste portão — frontmatter válido, ordem das seções, ausência de H1
|
|
231
|
+
no corpo, linha em branco nos `<details>`, `classDef` do Mermaid, critério sem `DEVE`, premissa com
|
|
232
|
+
célula vazia, formato de ID de requisito. Saída ≠ 0 significa **pare e corrija** antes de
|
|
233
|
+
apresentar.
|
|
234
|
+
|
|
235
|
+
O script confere estrutura; o julgamento continua seu — se a interpretação está certa e se o
|
|
236
|
+
desfecho é preciso, só você sabe.
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: spec-writing
|
|
3
|
+
description: Como escrever e manter as specs de `.specs/specs/` — estrutura fixa da página de tarefa (contexto, visão técnica com diagrama Mermaid e blocos expansíveis, escopo, code review checklist), o `overview.md` de cada feature, o frontmatter, o `meta.json`, o registro de Execuções e as heurísticas de quebra em tasks. Carregue antes de criar, refinar ou atualizar qualquer arquivo em `.specs/specs/`.
|
|
4
|
+
related-skills: requirements-closure, test-strategy
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Escrita de specs
|
|
8
|
+
|
|
9
|
+
As specs vivem em `.specs/specs/<slug-da-feature>/` e são renderizadas pela Specs Platform
|
|
10
|
+
(`specs start`). A estrutura de diretório, a nomenclatura de arquivos e o `meta.json` estão em
|
|
11
|
+
`.specs/specs/CLAUDE.md` — esta skill cobre **o que escrever dentro dos arquivos**.
|
|
12
|
+
|
|
13
|
+
## Estrutura fixa da página de tarefa
|
|
14
|
+
|
|
15
|
+
Toda tarefa segue esta ordem de seções, sem exceção:
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
## Contexto da alteração (termina com a lista "**Depende de:**")
|
|
19
|
+
## Visão Técnica
|
|
20
|
+
diagrama Mermaid + legenda
|
|
21
|
+
### O que muda, em resumo (tabela curta)
|
|
22
|
+
### Detalhamento técnico (blocos <details>)
|
|
23
|
+
## Escopo
|
|
24
|
+
### Fora de escopo
|
|
25
|
+
## Code Review Checklist
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**Não existem** as seções `Critérios de Aceite`, `Detalhes Técnicos`, `Testes` e `Dependências`
|
|
29
|
+
como seções de primeiro nível. Os critérios e os detalhes vivem dentro dos blocos expansíveis,
|
|
30
|
+
testes são um bloco expansível, e as dependências são a lista `**Depende de:**` no fim do
|
|
31
|
+
Contexto.
|
|
32
|
+
|
|
33
|
+
**Nunca escreva `# Título` no corpo.** O `title` do frontmatter já vira o `<h1>` da página; um H1
|
|
34
|
+
no corpo duplica o título (o renderer descarta o duplicado, mas o arquivo fica sujo).
|
|
35
|
+
|
|
36
|
+
### Contexto da alteração
|
|
37
|
+
|
|
38
|
+
Dois a quatro parágrafos curtos respondendo: como funciona hoje, o que passa a funcionar
|
|
39
|
+
diferente, e o que o usuário percebe (ou explicitamente não percebe). Sem detalhe de
|
|
40
|
+
implementação — isso é o detalhamento técnico.
|
|
41
|
+
|
|
42
|
+
Termina com:
|
|
43
|
+
|
|
44
|
+
```markdown
|
|
45
|
+
**Depende de:**
|
|
46
|
+
|
|
47
|
+
- [Título da task](./feat-<slug>-<task>.md) — o que ela entrega para esta
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Quando não há dependência, diga isso explicitamente ("Nenhuma task. É a primeira da feature.").
|
|
51
|
+
|
|
52
|
+
### Diagrama da Visão Técnica (obrigatório)
|
|
53
|
+
|
|
54
|
+
Um `flowchart` Mermaid com a visão geral do que será feito. Sempre com estes `classDef`:
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
classDef changed fill:#3b2f00,stroke:#eab308,color:#fde68a
|
|
58
|
+
classDef added fill:#052e1a,stroke:#22c55e,color:#bbf7d0
|
|
59
|
+
classDef removed fill:#3b0d0d,stroke:#ef4444,color:#fecaca
|
|
60
|
+
classDef untouched fill:#151515,stroke:#2a2a2a,color:#9ca3af
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Regras:
|
|
64
|
+
|
|
65
|
+
- **Um nó por recurso/componente real tocado** — use case, entidade, tabela, endpoint, job, fila,
|
|
66
|
+
tela, componente, DAL, integração externa. Nada genérico como "o backend".
|
|
67
|
+
- **Cor pela natureza da mudança:** `:::changed` (amarelo) alterado, `:::added` (verde)
|
|
68
|
+
adicionado, `:::removed` (vermelho) removido, `:::untouched` (cinza) só o contexto mínimo que
|
|
69
|
+
faz o fluxo ter sentido.
|
|
70
|
+
- Cole a legenda logo abaixo do bloco:
|
|
71
|
+
`> 🟡 alterado · 🟢 adicionado · 🔴 removido · ⚪ inalterado (contexto)`
|
|
72
|
+
- Agrupe em `subgraph` por etapa ou camada. Prefira `flowchart TB` com `direction LR` **dentro**
|
|
73
|
+
de cada subgraph: faixas horizontais empilhadas rendem um diagrama equilibrado, enquanto `LR`
|
|
74
|
+
puro produz diagramas larguíssimos e ilegíveis.
|
|
75
|
+
- Ligue arestas a **nós específicos**, nunca ao subgraph inteiro — aresta apontando para um
|
|
76
|
+
subgraph faz o Mermaid ignorar o `direction` interno dele.
|
|
77
|
+
- Máximo ~15 nós. O que não couber vira texto no detalhamento.
|
|
78
|
+
- Sem aspas duplas dentro do rótulo; `<br/>` para quebrar linha.
|
|
79
|
+
- Um card `:::removed` pode marcar **acoplamento proibido** em vez de código deletado (ex.: "o que
|
|
80
|
+
não pode passar a depender deste campo") — quando fizer isso, explique na linha da legenda.
|
|
81
|
+
|
|
82
|
+
### Blocos expansíveis do detalhamento técnico
|
|
83
|
+
|
|
84
|
+
A linha em branco depois do `</summary>` e antes do `</details>` é obrigatória — sem ela o
|
|
85
|
+
markdown interno não é interpretado:
|
|
86
|
+
|
|
87
|
+
```markdown
|
|
88
|
+
<details>
|
|
89
|
+
<summary>Título do recorte</summary>
|
|
90
|
+
|
|
91
|
+
Explicação curta do recorte.
|
|
92
|
+
|
|
93
|
+
- [ ] critério de aceite verificável
|
|
94
|
+
|
|
95
|
+
</details>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Regras:
|
|
99
|
+
|
|
100
|
+
- Um bloco por **recorte coeso**: etapa do fluxo, endpoint, seção de tela, política de erro.
|
|
101
|
+
- **Os critérios de aceite moram dentro do bloco do recorte a que pertencem**, logo abaixo da
|
|
102
|
+
explicação.
|
|
103
|
+
- Blocos temáticos obrigatórios quando se aplicarem: `Segurança e sanitização de inputs`,
|
|
104
|
+
`Premissas e questões em aberto`, `Testes` e, em frontend, `Responsividade`,
|
|
105
|
+
`Estados de UI — loading, erro, vazio`, `Acessibilidade e animações`.
|
|
106
|
+
- **`Premissas e questões em aberto` é obrigatório em toda task média ou grande** — é onde a
|
|
107
|
+
ambiguidade que não foi resolvida com o usuário fica registrada com default e racional, em vez
|
|
108
|
+
de sumir. Formato e regra na skill `requirements-closure`.
|
|
109
|
+
- **`Testes` declara `**Tipo:**` e `**Gate:**`** com o comando real do pacote tocado. Formato e
|
|
110
|
+
matriz de cobertura na skill `test-strategy`.
|
|
111
|
+
- **Nada de headings markdown (`###`) dentro de `<details>`** — eles aparecem no índice lateral
|
|
112
|
+
apontando para conteúdo fechado. Use **negrito** para subtítulos internos.
|
|
113
|
+
- O conteúdo fora dos blocos precisa ser lido de ponta a ponta em menos de um minuto: contexto,
|
|
114
|
+
diagrama, tabela-resumo, escopo e checklist. Todo o resto fica colapsado.
|
|
115
|
+
|
|
116
|
+
### Tabela "O que muda, em resumo"
|
|
117
|
+
|
|
118
|
+
Três colunas — `#`, `Mudança`, `Efeito`. Uma linha por mudança relevante, tipicamente 4 a 8.
|
|
119
|
+
O efeito é a consequência prática ("o worker deixa de ficar bloqueado"), não a repetição da
|
|
120
|
+
mudança.
|
|
121
|
+
|
|
122
|
+
## A `## Code Review Checklist`
|
|
123
|
+
|
|
124
|
+
É **a casa dos itens de estrutura interna** — não um resumo dos critérios de aceite.
|
|
125
|
+
|
|
126
|
+
A divisão, cuja regra completa está na skill `requirements-closure`:
|
|
127
|
+
|
|
128
|
+
- **Bloco `<details>`** → comportamento observável na fronteira. Vira teste, e o Verifier cobra
|
|
129
|
+
`file:line` + asserção para cada um.
|
|
130
|
+
- **Code Review Checklist** → o que só se verifica abrindo o arquivo: path e nomenclatura, nome de
|
|
131
|
+
DTO/tipo, padrão aplicado (`.strict()`, `private readonly`, allowlist de enum), ausência
|
|
132
|
+
deliberada (sem índice novo, sem setter, sem backfill), acoplamento que não pode nascer.
|
|
133
|
+
|
|
134
|
+
O teste para saber onde cada item mora: **se eu refatorar sem mudar comportamento, isso quebra?**
|
|
135
|
+
Sim ⇒ Code Review Checklist.
|
|
136
|
+
|
|
137
|
+
**Não repita.** Se um item já é critério de aceite num bloco, ele não volta aqui condensado — é
|
|
138
|
+
duplicação que envelhece em dois lugares ao mesmo tempo. A checklist cobre o que os critérios
|
|
139
|
+
deliberadamente **não** cobrem.
|
|
140
|
+
|
|
141
|
+
Escreva cada item como algo que o revisor consegue marcar olhando o diff, e específico:
|
|
142
|
+
`Enum validado por allowlist no schema .strict() do controller`, não `Validação OK`.
|
|
143
|
+
|
|
144
|
+
## O `overview.md` da feature
|
|
145
|
+
|
|
146
|
+
Toda feature tem `.specs/specs/<slug>/overview.md` — a página exibida ao clicar na feature na
|
|
147
|
+
sidebar. Sem ele, a plataforma redireciona para a primeira task.
|
|
148
|
+
|
|
149
|
+
```
|
|
150
|
+
---
|
|
151
|
+
title: "<Título da feature, igual ao meta.json>"
|
|
152
|
+
description: "<mesma descrição do meta.json>"
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## O que será feito (problema, decisão e desenho geral — 3 a 5 parágrafos curtos)
|
|
156
|
+
## Visão Técnica
|
|
157
|
+
diagrama Mermaid MACRO + legenda
|
|
158
|
+
### Frentes de trabalho (tabela: frente · o que entrega · nº de tasks)
|
|
159
|
+
### Ordem de execução (cadeia crítica e o que roda em paralelo)
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
- Sem `status` no frontmatter e **fora** de `pages` no `meta.json` — não é uma task.
|
|
163
|
+
- A lista de tasks com status é renderizada automaticamente abaixo do conteúdo. **Não escreva
|
|
164
|
+
essa lista à mão.**
|
|
165
|
+
- O diagrama do overview é **macro** (granularidade de frente/entrega); o de cada task é **micro**
|
|
166
|
+
(granularidade de arquivo/componente). Mesmas cores nos dois.
|
|
167
|
+
- Obrigatório ao criar feature nova. Ao adicionar uma task a uma feature existente, atualize o
|
|
168
|
+
overview se a task mudar o desenho macro.
|
|
169
|
+
|
|
170
|
+
## Frontmatter da tarefa
|
|
171
|
+
|
|
172
|
+
```yaml
|
|
173
|
+
---
|
|
174
|
+
title: "<Camada/Descrição da tarefa>"
|
|
175
|
+
description: "<Frase curta descrevendo o escopo>"
|
|
176
|
+
status: pending # pending | in-progress | completed | blocked
|
|
177
|
+
---
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**O `title` descreve só a tarefa, sem repetir o nome da feature.** A plataforma já exibe a feature
|
|
181
|
+
como sobretítulo acima do H1 e agrupa as tarefas por feature na sidebar — repetir o prefixo
|
|
182
|
+
("Login — Frontend" dentro da feature "Login") gasta a linha inteira com informação redundante.
|
|
183
|
+
Escreva `"Frontend (tela de login)"`, não `"Login — Frontend (tela de login)"`. Em specs antigas
|
|
184
|
+
que ainda carregam o prefixo, o renderer o remove na exibição.
|
|
185
|
+
|
|
186
|
+
O `status` é responsabilidade de quem executa (`feature-runner`), não de quem refina.
|
|
187
|
+
|
|
188
|
+
## Critérios de aceite — como redigir
|
|
189
|
+
|
|
190
|
+
**A notação é EARS e a fonte de verdade é a skill `requirements-closure`** — carregue-a antes de
|
|
191
|
+
redigir. Em resumo: todo critério resolve para um dos seis padrões (ubíquo, `QUANDO`, `ENQUANTO`,
|
|
192
|
+
`ONDE`, `SE`, composto) e carrega o verbo **DEVE**.
|
|
193
|
+
|
|
194
|
+
```markdown
|
|
195
|
+
- [ ] **CADASTRO-03** — QUANDO o usuário submete CPF já cadastrado ENTÃO o sistema DEVE responder
|
|
196
|
+
409 com `errorCode: CPF_ALREADY_REGISTERED` e não criar registro em `users`
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
O prefixo `**CATEGORIA-NN**` é o **ID de requisito**, obrigatório em task com 5+ critérios ou 2+
|
|
200
|
+
camadas — é ele que permite ao Verifier dizer "CADASTRO-03 coberto em `auth-use-cases.test.ts:88`".
|
|
201
|
+
|
|
202
|
+
E ainda:
|
|
203
|
+
|
|
204
|
+
- **Objetivos:** não "funcionar bem", mas "retorna 200 com payload `{ id, name }` para input
|
|
205
|
+
válido".
|
|
206
|
+
- **Testáveis:** um humano ou um E2E verifica sem ambiguidade.
|
|
207
|
+
- **Ancorados no código real:** cite rotas, componentes, arquivos e tipos que existem. Não invente
|
|
208
|
+
— a menos que a task seja justamente criá-los, e aí seja explícito ("Criar endpoint `POST
|
|
209
|
+
/api/v1/vehicles`").
|
|
210
|
+
- **Sem tokens visuais fixos** (cores hex, px, pesos de fonte): eles mudam no protótipo e a doc
|
|
211
|
+
fica mentindo. Descreva estrutura e intenção; quem implementa extrai os valores do protótipo.
|
|
212
|
+
|
|
213
|
+
## Validação determinística antes de apresentar
|
|
214
|
+
|
|
215
|
+
Depois de escrever ou editar qualquer arquivo de task, rode:
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
node .agents/scripts/validate-spec.mjs .specs/specs/<slug>/feat-<slug>-<task>.md
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Ele checa por código o que esta skill exige de memória: frontmatter, ordem das seções, ausência de
|
|
222
|
+
H1 no corpo, `**Depende de:**`, `### Fora de escopo`, os quatro `classDef` do Mermaid, linha em
|
|
223
|
+
branco nos `<details>`, heading proibido dentro de `<details>`, critério fora de EARS, ID de
|
|
224
|
+
requisito malformado, premissa com célula vazia e presença do arquivo em `pages` do `meta.json`.
|
|
225
|
+
|
|
226
|
+
**Saída ≠ 0 = pare e corrija** antes de apresentar a spec. Rode no arquivo que você tocou — `--all`
|
|
227
|
+
existe para inventário e hoje acusa as 225 specs no formato antigo, que não são escopo desta rodada.
|
|
228
|
+
|
|
229
|
+
## Registro de Execuções
|
|
230
|
+
|
|
231
|
+
Quem executa acrescenta, ao fim do arquivo, depois de um `---`. **Cada execução é um bloco
|
|
232
|
+
expansível** — o histórico cresce sem empurrar o conteúdo da spec para longe:
|
|
233
|
+
|
|
234
|
+
```markdown
|
|
235
|
+
## Execuções
|
|
236
|
+
|
|
237
|
+
<details>
|
|
238
|
+
<summary>dd/mm/aaaa HH:mm — TIPO</summary>
|
|
239
|
+
|
|
240
|
+
- <o que foi criado/alterado, citando arquivos e decisões não óbvias>
|
|
241
|
+
|
|
242
|
+
</details>
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Entradas novas vão **no topo** da seção, logo abaixo do `## Execuções`. O `<summary>` carrega data,
|
|
246
|
+
hora e tipo (`FEAT`, `FIX`, `REFACTOR`, `CHORE`…) — nada de heading `###`. Máximo 8 bullets por
|
|
247
|
+
execução; específico sempre ("Criado `.../health-routes.ts` com rota `GET /health`", não
|
|
248
|
+
"adicionada rota").
|
|
249
|
+
|
|
250
|
+
## Heurísticas de quebra em tasks
|
|
251
|
+
|
|
252
|
+
Quebre quando: a atividade toca frontend **e** backend; passaria de ~15 critérios de aceite;
|
|
253
|
+
partes podem ser paralelizadas; uma parte está bloqueada e a outra não.
|
|
254
|
+
|
|
255
|
+
Não quebre quando: o escopo é pequeno e coeso; as tasks resultantes teriam menos de 3 critérios.
|
|
256
|
+
|
|
257
|
+
Posição no array `pages`: dependente depois da dependência; backend antes de frontend;
|
|
258
|
+
integração/E2E por último.
|