nexus-core-v3 3.0.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 (232) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +134 -0
  3. package/agents/README.md +133 -0
  4. package/agents/_protocol.md +107 -0
  5. package/agents/analyst.md +138 -0
  6. package/agents/architect.md +146 -0
  7. package/agents/data-engineer.md +170 -0
  8. package/agents/dev.md +134 -0
  9. package/agents/devops.md +141 -0
  10. package/agents/nexus-master.md +147 -0
  11. package/agents/pm.md +133 -0
  12. package/agents/po.md +138 -0
  13. package/agents/qa.md +192 -0
  14. package/agents/sm.md +122 -0
  15. package/agents/squad-creator.md +121 -0
  16. package/agents/ux-design-expert.md +165 -0
  17. package/artifact-manifest.json +903 -0
  18. package/bin/nexus.mjs +37 -0
  19. package/checklists/README.md +49 -0
  20. package/checklists/architect-checklist.md +47 -0
  21. package/checklists/change-checklist.md +61 -0
  22. package/checklists/db-predeploy-checklist.md +57 -0
  23. package/checklists/design-quality-checklist.md +57 -0
  24. package/checklists/discovery-checklist.md +36 -0
  25. package/checklists/foundation-checklist.md +39 -0
  26. package/checklists/launch-checklist.md +39 -0
  27. package/checklists/pm-checklist.md +48 -0
  28. package/checklists/po-master-checklist.md +64 -0
  29. package/checklists/reality-check-checklist.md +49 -0
  30. package/checklists/story-dod-checklist.md +52 -0
  31. package/checklists/story-draft-checklist.md +36 -0
  32. package/dist/bin/dashboard.html +279 -0
  33. package/dist/bin/nexus.mjs +20008 -0
  34. package/dist/constitution.yaml +76 -0
  35. package/knowledge/README.md +57 -0
  36. package/knowledge/architecture/architectural-styles-map.md +182 -0
  37. package/knowledge/architecture/design-patterns-gof.md +192 -0
  38. package/knowledge/architecture/distributed-patterns-cheatsheet.md +201 -0
  39. package/knowledge/architecture/saas-subscription-blueprint.md +355 -0
  40. package/knowledge/architecture/system-design-tradeoffs.md +231 -0
  41. package/knowledge/architecture/t3-fullstack-typesafe-stack.md +273 -0
  42. package/knowledge/copy/landing-copy-that-converts.md +168 -0
  43. package/knowledge/data/postgres-indexing-and-tuning.md +263 -0
  44. package/knowledge/data/schema-modeling-decisions.md +273 -0
  45. package/knowledge/data/supabase-rls-patterns.md +316 -0
  46. package/knowledge/data/zero-downtime-migrations.md +308 -0
  47. package/knowledge/devops/cicd-pipeline-best-practices.md +318 -0
  48. package/knowledge/devops/production-dockerfile.md +283 -0
  49. package/knowledge/devops/twelve-factor-app.md +398 -0
  50. package/knowledge/engineering/clean-code-principles.md +429 -0
  51. package/knowledge/engineering/effective-code-review.md +204 -0
  52. package/knowledge/engineering/testing-strategy-beyond-unit.md +307 -0
  53. package/knowledge/governance/risk-matrix.md +56 -0
  54. package/knowledge/integration/mcp-server-selection-matrix.md +235 -0
  55. package/knowledge/marketing/copy-que-converte.md +43 -0
  56. package/knowledge/marketing/funil-e-jornada.md +36 -0
  57. package/knowledge/negocios/proposta-vencedora.md +38 -0
  58. package/knowledge/negocios/roi-e-unit-economics.md +46 -0
  59. package/knowledge/pipeline/1-descobrir.md +26 -0
  60. package/knowledge/pipeline/2-estrategizar.md +26 -0
  61. package/knowledge/pipeline/3-estruturar.md +27 -0
  62. package/knowledge/pipeline/4-construir.md +27 -0
  63. package/knowledge/pipeline/5-endurecer.md +28 -0
  64. package/knowledge/pipeline/6-lancar.md +27 -0
  65. package/knowledge/pipeline/7-operar.md +27 -0
  66. package/knowledge/security/lgpd-conformidade-basica.md +35 -0
  67. package/knowledge/security/owasp-secure-coding-gates.md +220 -0
  68. package/knowledge/security/owasp-top10-threat-assessment.md +287 -0
  69. package/knowledge/security/threat-modeling-stride.md +34 -0
  70. package/knowledge/web-craft/a11y-audit-checklist.md +251 -0
  71. package/knowledge/web-craft/accessible-component-patterns.md +383 -0
  72. package/knowledge/web-craft/anti-ai-look.md +114 -0
  73. package/knowledge/web-craft/design-system-from-code.md +195 -0
  74. package/knowledge/web-craft/intrinsic-css-layout.md +420 -0
  75. package/knowledge/web-craft/style-cloning.md +185 -0
  76. package/knowledge/web-craft/visual-polish-review.md +183 -0
  77. package/package.json +55 -0
  78. package/runbooks/campanha-de-conteudo.md +36 -0
  79. package/runbooks/feature-em-projeto-existente.md +37 -0
  80. package/runbooks/mvp-startup.md +38 -0
  81. package/runbooks/resposta-a-incidente.md +37 -0
  82. package/squads/exemplo-conteudo/agents/editor-chefe.md +48 -0
  83. package/squads/exemplo-conteudo/agents/pesquisador.md +44 -0
  84. package/squads/exemplo-conteudo/agents/redator.md +45 -0
  85. package/squads/exemplo-conteudo/knowledge/estilo-editorial.md +21 -0
  86. package/squads/exemplo-conteudo/squad.yaml +19 -0
  87. package/squads/exemplo-conteudo/tasks/pesquisar-fontes.md +26 -0
  88. package/squads/exemplo-conteudo/tasks/planejar-pauta.md +27 -0
  89. package/squads/exemplo-conteudo/tasks/redigir-artigo.md +26 -0
  90. package/squads/exemplo-conteudo/tasks/revisar-artigo.md +27 -0
  91. package/squads/marketing/agents/analista.md +56 -0
  92. package/squads/marketing/agents/chefe-marketing.md +65 -0
  93. package/squads/marketing/agents/conteudo.md +55 -0
  94. package/squads/marketing/agents/copy.md +55 -0
  95. package/squads/marketing/agents/growth.md +56 -0
  96. package/squads/marketing/agents/social.md +55 -0
  97. package/squads/marketing/squad.yaml +17 -0
  98. package/squads/marketing/tasks/aprovar-campanha.md +43 -0
  99. package/squads/negocios/agents/chefe-negocios.md +65 -0
  100. package/squads/negocios/agents/financas-roi.md +55 -0
  101. package/squads/negocios/agents/suporte.md +55 -0
  102. package/squads/negocios/agents/vendas-proposta.md +56 -0
  103. package/squads/negocios/squad.yaml +17 -0
  104. package/squads/negocios/tasks/aprovar-proposta.md +40 -0
  105. package/squads/security/agents/appsec-reviewer.md +59 -0
  106. package/squads/security/agents/chefe-seguranca.md +65 -0
  107. package/squads/security/agents/compliance-auditor.md +60 -0
  108. package/squads/security/agents/threat-modeler.md +60 -0
  109. package/squads/security/squad.yaml +20 -0
  110. package/squads/security/tasks/aprovar-gate-seguranca.md +42 -0
  111. package/squads/security/tasks/emitir-parecer-conformidade.md +42 -0
  112. package/tasks/README.md +72 -0
  113. package/tasks/accessibility-wcag-checklist.md +69 -0
  114. package/tasks/advanced-elicitation.md +42 -0
  115. package/tasks/analyze-performance.md +54 -0
  116. package/tasks/analyze-project-structure.md +59 -0
  117. package/tasks/apply-qa-fixes.md +57 -0
  118. package/tasks/architect-analyze-impact.md +62 -0
  119. package/tasks/archive-squad.md +52 -0
  120. package/tasks/audit-codebase.md +53 -0
  121. package/tasks/build-component.md +61 -0
  122. package/tasks/calculate-roi.md +63 -0
  123. package/tasks/ci-cd-configuration.md +51 -0
  124. package/tasks/collect-visual-evidence.md +62 -0
  125. package/tasks/compose-molecule.md +57 -0
  126. package/tasks/consolidate-patterns.md +54 -0
  127. package/tasks/create-brownfield-prd.md +54 -0
  128. package/tasks/create-competitor-analysis.md +42 -0
  129. package/tasks/create-deep-research-prompt.md +62 -0
  130. package/tasks/create-doc.md +62 -0
  131. package/tasks/create-epic.md +49 -0
  132. package/tasks/create-front-end-spec.md +56 -0
  133. package/tasks/create-migration-plan.md +57 -0
  134. package/tasks/create-next-story.md +66 -0
  135. package/tasks/create-prd.md +53 -0
  136. package/tasks/create-project-brief.md +47 -0
  137. package/tasks/create-rls-policies.md +59 -0
  138. package/tasks/create-schema.md +57 -0
  139. package/tasks/create-service.md +55 -0
  140. package/tasks/create-squad.md +100 -0
  141. package/tasks/create-suite.md +62 -0
  142. package/tasks/db-apply-migration.md +56 -0
  143. package/tasks/db-domain-modeling.md +57 -0
  144. package/tasks/db-dry-run.md +50 -0
  145. package/tasks/db-env-check.md +57 -0
  146. package/tasks/db-load-csv.md +54 -0
  147. package/tasks/db-policy-apply.md +58 -0
  148. package/tasks/db-rollback.md +51 -0
  149. package/tasks/db-run-sql.md +61 -0
  150. package/tasks/db-seed.md +52 -0
  151. package/tasks/db-smoke-test.md +51 -0
  152. package/tasks/db-snapshot.md +48 -0
  153. package/tasks/db-verify-order.md +49 -0
  154. package/tasks/deliberate.md +46 -0
  155. package/tasks/design-indexes.md +59 -0
  156. package/tasks/dev-develop-story.md +61 -0
  157. package/tasks/document-project.md +59 -0
  158. package/tasks/execute-checklist.md +57 -0
  159. package/tasks/execute-epic-plan.md +52 -0
  160. package/tasks/execute-subtask.md +51 -0
  161. package/tasks/extend-pattern.md +63 -0
  162. package/tasks/extend-squad.md +60 -0
  163. package/tasks/extract-patterns.md +64 -0
  164. package/tasks/extract-tokens.md +59 -0
  165. package/tasks/facilitate-brainstorming-session.md +42 -0
  166. package/tasks/generate-ai-frontend-prompt.md +57 -0
  167. package/tasks/generate-documentation.md +60 -0
  168. package/tasks/generate-migration-strategy.md +57 -0
  169. package/tasks/generate-shock-report.md +56 -0
  170. package/tasks/mcp-management.md +66 -0
  171. package/tasks/orchestrate.md +50 -0
  172. package/tasks/perform-market-research.md +42 -0
  173. package/tasks/plan-create-context.md +57 -0
  174. package/tasks/plan-create-implementation.md +58 -0
  175. package/tasks/po-close-story.md +60 -0
  176. package/tasks/po-manage-story-backlog.md +59 -0
  177. package/tasks/po-pull-story.md +60 -0
  178. package/tasks/po-sync-story.md +59 -0
  179. package/tasks/pr-automation.md +50 -0
  180. package/tasks/pre-push-quality-gate.md +54 -0
  181. package/tasks/push.md +53 -0
  182. package/tasks/qa-browser-console-check.md +52 -0
  183. package/tasks/qa-create-fix-request.md +58 -0
  184. package/tasks/qa-evidence-requirements.md +55 -0
  185. package/tasks/qa-false-positive-detection.md +55 -0
  186. package/tasks/qa-fix-issues.md +55 -0
  187. package/tasks/qa-gate.md +53 -0
  188. package/tasks/qa-migration-validation.md +58 -0
  189. package/tasks/qa-nfr-assess.md +45 -0
  190. package/tasks/qa-review-story.md +56 -0
  191. package/tasks/qa-risk-profile.md +45 -0
  192. package/tasks/qa-security-checklist.md +64 -0
  193. package/tasks/qa-test-design.md +47 -0
  194. package/tasks/qa-trace-requirements.md +48 -0
  195. package/tasks/release-management.md +53 -0
  196. package/tasks/repository-cleanup.md +61 -0
  197. package/tasks/route.md +44 -0
  198. package/tasks/run-tests.md +50 -0
  199. package/tasks/security-audit.md +54 -0
  200. package/tasks/setup-database.md +60 -0
  201. package/tasks/setup-design-system.md +60 -0
  202. package/tasks/shard-doc.md +60 -0
  203. package/tasks/spec-assess-complexity.md +55 -0
  204. package/tasks/spec-critique.md +64 -0
  205. package/tasks/spec-gather-requirements.md +48 -0
  206. package/tasks/spec-research-dependencies.md +42 -0
  207. package/tasks/spec-write-spec.md +50 -0
  208. package/tasks/test-as-user.md +52 -0
  209. package/tasks/ux-create-wireframe.md +54 -0
  210. package/tasks/ux-user-research.md +55 -0
  211. package/tasks/validate-next-story.md +61 -0
  212. package/tasks/validate-squad.md +55 -0
  213. package/tasks/verify-subtask.md +52 -0
  214. package/tasks/version-management.md +45 -0
  215. package/templates/README.md +47 -0
  216. package/templates/architecture-tmpl.md +115 -0
  217. package/templates/competitor-analysis-tmpl.md +87 -0
  218. package/templates/epic-tmpl.md +83 -0
  219. package/templates/front-end-spec-tmpl.md +110 -0
  220. package/templates/market-research-tmpl.md +98 -0
  221. package/templates/migration-plan-tmpl.md +92 -0
  222. package/templates/prd-tmpl.md +95 -0
  223. package/templates/project-brief-tmpl.md +100 -0
  224. package/templates/qa-verdict-tmpl.md +73 -0
  225. package/templates/rls-policies-tmpl.md +93 -0
  226. package/templates/schema-design-tmpl.md +107 -0
  227. package/templates/spec-tmpl.md +88 -0
  228. package/templates/squad/agent-dna-tmpl.md +72 -0
  229. package/templates/squad/chief-dna-tmpl.md +98 -0
  230. package/templates/squad/squad-task-tmpl.md +50 -0
  231. package/templates/squad/squad-yaml-tmpl.md +47 -0
  232. package/templates/story-tmpl.md +63 -0
@@ -0,0 +1,307 @@
1
+ ---
2
+ id: testing-strategy-beyond-unit
3
+ domain: engineering
4
+ agents: [qa, dev]
5
+ when: "ao desenhar a estratégia de testes de uma feature ou avaliar a cobertura de uma story"
6
+ ---
7
+
8
+ # Testing strategy beyond unit — testes que pegam bug, não que decoram cobertura
9
+
10
+ Suíte de teste medíocre tem uma "cara": ela é verde, tem 85% de cobertura, e mesmo assim
11
+ bugs escapam pra produção. O motivo é quase sempre o mesmo — os testes visitam o código
12
+ sem testar nada, ou estão tão acoplados aos internos que quebram a cada refactor e ninguém
13
+ mais confia neles. Este pack ensina a **escolher o tipo de teste certo, escrevê-lo pra pegar
14
+ bug de verdade, e medir se ele presta** — destilado do
15
+ [goldbergyoni/javascript-testing-best-practices](https://github.com/goldbergyoni/javascript-testing-best-practices)
16
+ (Yoni Goldberg). A regra-mãe (o "Golden Rule" do repo): **código de teste não é código de
17
+ produção — projete-o pra ser curto, raso e óbvio. Olhe um teste e entenda a intenção na hora.**
18
+ Tudo abaixo deriva disso.
19
+
20
+ ## O problema / os tells
21
+
22
+ Se a suíte tem 3+ destes, ela é teatro de cobertura, não rede de segurança:
23
+
24
+ 1. **Nome de teste que não diz nada** — `it("Add product")`, `it("Test addNewOrder")`. Falhou no
25
+ CI: você não faz ideia do que quebrou sem abrir o código.
26
+ 2. **Sem separação AAA** — arrange, act e assert grudados num bloco só; o leitor gasta CPU mental
27
+ só pra achar onde o teste age e onde verifica.
28
+ 3. **Asserção imperativa** — `forEach` + `if` + flags booleanas + `throw` manual em vez de um
29
+ `expect` declarativo. A "história" do teste some no meio do controle de fluxo.
30
+ 4. **Testa método privado / internals** — o teste chama `calculateVATAdd()` (interno) e quebra
31
+ quando você renomeia o método, embora o resultado final esteja certo. O teste vira o menino
32
+ que gritou lobo: dá falso-positivo até alguém ignorar o CI e um bug real passar.
33
+ 5. **Mock que verifica "foi chamado com esses args"** — `mock.expects("deleteProduct").withArgs(...)`.
34
+ Acoplado ao como, não ao quê. Qualquer refactor obriga a caçar e reescrever todos os mocks.
35
+ 6. **Input `"Foo"` / `123`** — input sintético nunca dispara o regex de validação, o path de erro,
36
+ o caso de borda. Verde no dev, vermelho quando um usuário manda `"@3e2ddsf . ##' 1 fdsfds"`.
37
+ 7. **`setTimeout(2000)` esperando algo async** — o teste é lento (espera demais) ou flaky (espera
38
+ de menos). Trade-off entre lentidão e flakiness, perde nos dois.
39
+ 8. **Seed global de DB** (`before(() => DB.seed('seed.json'))`) — testes acoplados a dados que
40
+ vivem fora deles; dois testes mutam a mesma linha e o deploy aborta sem causa óbvia.
41
+ 9. **Selector por classe CSS** — `wrapper.find("[className='thin-border']")`. O designer troca a
42
+ classe e o teste de *lógica* de login quebra.
43
+ 10. **Snapshot gigante externo** — `toMatchSnapshot()` de 2000 linhas que ninguém leu; quebra a
44
+ cada espaço, comentário ou mudança de CSS, e o autor aprova cegamente o "novo correto".
45
+ 11. **100% de cobertura, 0% de teste** — o teste chama a função e não tem **nenhum** `expect`.
46
+ Visitou todas as linhas, não verificou nada.
47
+ 12. **Só pirâmide de unit** — 50% do budget em unit tests pra uma app que é integração-cêntrica
48
+ (ingest Kafka → data warehouse → UI), quase sem lógica. Muito esforço, 20% de cobertura real.
49
+
50
+ ## Os princípios do craft (com pares bad→good reais do repo)
51
+
52
+ ### 1. Nome do teste em 3 partes: o quê / cenário / esperado
53
+ O relatório do CI tem que dizer o que está quebrado pra quem **não** conhece o código (o ops que
54
+ faz deploy, você daqui a dois anos). Três partes: (1) unidade sob teste, (2) cenário/circunstância,
55
+ (3) resultado esperado.
56
+
57
+ ```javascript
58
+ // ❌ "Add product" — falhou no deploy. Isso te diz o que está com defeito?
59
+
60
+ // ✅ describe aninhado carrega a parte (1); o it() carrega (2) e (3)
61
+ describe('Products Service', () => {
62
+ describe('Add new product', () => {
63
+ it('When no price is specified, then the product status is pending approval', () => {
64
+ const newProduct = new ProductService().add(/* ... */);
65
+ expect(newProduct.status).to.equal('pendingApproval');
66
+ });
67
+ });
68
+ });
69
+ ```
70
+
71
+ ### 2. Estruture com AAA — Arrange, Act, Assert, separados
72
+ Três seções marcadas. Garante que o leitor não gasta "brain-CPU" decifrando o plano do teste.
73
+ Act e Assert costumam ser 1 linha cada.
74
+
75
+ ```javascript
76
+ // ❌ tudo num bloco só, mais difícil de interpretar
77
+ test("Should be classified as premium", () => {
78
+ const customerToClassify = { spent: 505, joined: new Date(), id: 1 };
79
+ const DBStub = sinon.stub(dataAccess, "getCustomer").reply({ id: 1, classification: "regular" });
80
+ const received = customerClassifier.classifyCustomer(customerToClassify);
81
+ expect(received).toMatch("premium");
82
+ });
83
+
84
+ // ✅ Arrange / Act / Assert separados
85
+ test("When customer spent more than 500$, should be classified as premium", () => {
86
+ // Arrange
87
+ const customerToClassify = { spent: 505, joined: new Date(), id: 1 };
88
+ sinon.stub(dataAccess, "getCustomer").reply({ id: 1, classification: "regular" });
89
+ // Act
90
+ const receivedClassification = customerClassifier.classifyCustomer(customerToClassify);
91
+ // Assert
92
+ expect(receivedClassification).toMatch("premium");
93
+ });
94
+ ```
95
+
96
+ ### 3. Asserção declarativa (BDD), não fluxo imperativo
97
+ Código imperativo com `if`/`forEach`/flags força o leitor a executar o teste na cabeça. Use
98
+ `expect`/`should` declarativo. Se a asserção que você precisa não existe e é repetível, estenda o
99
+ matcher — não escreva lógica de verificação inline.
100
+
101
+ ```javascript
102
+ // ❌ o leitor tem que percorrer o loop pra entender a história do teste
103
+ allAdmins.forEach(u => {
104
+ if (u === "user1") assert.notEqual(u, "user1", "A user was found and not admin");
105
+ if (u === "admin1") admin1Found = true;
106
+ if (u === "admin2") admin2Found = true;
107
+ });
108
+ if (!admin1Found || !admin2Found) throw new Error("Not all admins were returned");
109
+
110
+ // ✅ uma linha declarativa
111
+ expect(allAdmins)
112
+ .to.include.ordered.members(["admin1", "admin2"])
113
+ .but.not.include.ordered.members(["user1"]);
114
+ ```
115
+
116
+ Corolário — **não capture erro, espere-o.** Nada de `try/catch` + flag pra provar que lançou.
117
+
118
+ ```javascript
119
+ // ❌ se a asserção final falhar, o relatório só diz "valor null" — nada sobre exceção faltando
120
+ let caught = null;
121
+ try { await addNewProduct({}); } catch (e) { expect(e.code).to.equal("InvalidInput"); caught = e; }
122
+ expect(caught).not.to.be.null;
123
+
124
+ // ✅ legível até pro QA/PM, e o tipo do erro é verificado
125
+ await expect(addNewProduct({}))
126
+ .to.eventually.throw(AppError)
127
+ .with.property("code", "InvalidInput");
128
+ ```
129
+
130
+ ### 4. Teste comportamento via API pública (black-box), nunca internals
131
+ Verificar o comportamento público testa a implementação privada **implicitamente**. Testar o
132
+ interno (white-box) desloca o foco pro detalhe e quebra o teste em refactors inofensivos.
133
+
134
+ ```javascript
135
+ // ❌ white-box: testa um método interno que nem é requisito
136
+ class ProductService {
137
+ calculateVATAdd(price) { return { finalPrice: price * 1.2 }; } // renomear → testes quebram
138
+ getPrice(id) { return this.calculateVATAdd(DB.getProduct(id).price).finalPrice; }
139
+ }
140
+ expect(new ProductService().calculateVATAdd(0).finalPrice).to.equal(0);
141
+
142
+ // ✅ teste o que é requisito (preço final via método público); o VAT é coberto de tabela
143
+ ```
144
+
145
+ No frontend, a mesma regra vira "renderize de verdade e aja como o usuário", não shallow render +
146
+ invocar método interno:
147
+
148
+ ```javascript
149
+ // ✅ realista: monta o componente, clica, verifica o que o usuário vê
150
+ const wrapper = mount(<Calendar showFilters={false} />);
151
+ wrapper.find("button").simulate("click");
152
+ expect(wrapper.text().includes("Choose Filter"));
153
+
154
+ // ❌ shallow + .instance().showFilters() — tapeia a UI e chama método privado (white-box)
155
+ ```
156
+
157
+ ### 5. Escolha o test double certo: stub/spy (comportamento), não mock (internals)
158
+ Antes de qualquer double, pergunte: **isto aparece (ou poderia aparecer) no documento de requisitos?**
159
+ Se não, é cheiro de white-box. Stub pra simular um cenário ("pagamento fora do ar"), spy pra
160
+ verificar um efeito que **é** requisito ("envie e-mail se o pagamento falhar"). Mock que checa
161
+ "foi chamado com esses tipos/args" testa o interno — vai mudar toda hora.
162
+
163
+ ```javascript
164
+ // ❌ mock: o objetivo virou verificar a chamada interna ao DAL, não o requisito
165
+ const dataAccessMock = sinon.mock(DAL);
166
+ dataAccessMock.expects("deleteProduct").once().withArgs(DBConfig, product, true, false);
167
+ new ProductService().deletePrice(product);
168
+ dataAccessMock.verify();
169
+
170
+ // ✅ spy: verifica o requisito (e-mail enviado); tocar no interno é só efeito colateral
171
+ const spy = sinon.spy(Emailer.prototype, "sendEmail");
172
+ new ProductService().deletePrice(product);
173
+ expect(spy.calledOnce).to.be.true;
174
+ ```
175
+
176
+ ### 6. Input realista, não `"Foo"`
177
+ Bug de produção aparece em input específico e surpreendente. Use Faker/Chance pra gerar dado que
178
+ se parece com produção; suba pra property-based testing quando quiser cobrir permutações.
179
+
180
+ ```javascript
181
+ // ❌ "Foo" nunca dispara o regex (sem espaço) — falso verde
182
+ const r = addProduct("Foo", 5);
183
+ expect(r).toBe(true);
184
+
185
+ // ✅ input pseudo-real cobre paths que você não planejou
186
+ const r = addProduct(faker.commerce.productName(), faker.random.number());
187
+ expect(r).to.be.true;
188
+
189
+ // ✅✅ property-based (fast-check): roda 100 permutações automáticas
190
+ fc.assert(fc.property(fc.integer(), fc.string(), (id, name) => {
191
+ expect(addNewProduct(id, name).status).toEqual("approved");
192
+ }));
193
+ ```
194
+
195
+ ### 7. Anti-flakiness: determinismo, sem sleep, dados por-teste
196
+ - **Não durma.** Em vez de `setTimeout`, use a espera determinística do framework (`cy.wait('@route')`,
197
+ `waitFor`/`findBy` do testing-library, fake timers). Sleep é trade-off entre lento e flaky.
198
+
199
+ ```javascript
200
+ // ❌ sleep/polling caseiro, sem timeout
201
+ const interval = setInterval(() => { if (getByText("the lion king")) clearInterval(interval); }, 100);
202
+
203
+ // ✅ espera determinística do framework
204
+ await waitFor(() => expect(getByText("the lion king")).toBeInTheDocument());
205
+ ```
206
+
207
+ - **Dados isolados por teste.** Cada caso adiciona e age só nas próprias linhas de DB. Seed global é
208
+ acoplamento: dois testes mutam o mesmo registro e o deploy aborta sem causa óbvia.
209
+
210
+ ```javascript
211
+ // ❌ before(() => DB.AddSeedDataFromJson('seed.json')); // o dado vive fora do teste
212
+ // ✅ cada teste cria o que precisa: const site = await SiteService.addSite({ name: faker.... });
213
+ ```
214
+
215
+ - **Stub recurso flaky/lento** (API de backend) nos testes que não são E2E — staging cai sozinho e
216
+ reprova seu componente que está correto; e chamada de rede deixa o teste ~20x mais lento.
217
+ - **Selector estável**: `data-test-id`, não classe CSS. Classe muda com o visual e derruba teste de lógica.
218
+
219
+ ```javascript
220
+ // ❌ expect(wrapper.find("[className='d-flex-column']").text()).toBe("0");
221
+ // ✅ <span data-test-id="errorsLabel">{value}</span> → getByTestId("errorsLabel")
222
+ ```
223
+
224
+ ### 8. Pirâmide vs. troféu: enriqueça o portfólio, não empilhe só unit
225
+ A pirâmide de testes (muito unit, pouco E2E) ainda vale pra muita app — mas "todo modelo está
226
+ errado às vezes". App integração-cêntrica com pouca lógica não merece 50% do budget em unit. Combine
227
+ o **tipo de teste ao risco real** da feature, como um investidor diversifica por análise de risco.
228
+ O nível mais valioso e subestimado costuma ser o **component test** (o "troféu"): bate na API do
229
+ microsserviço, usa DB real (ou in-memory), e faz stub só do que é externo (outros serviços). Testa
230
+ o que você faz deploy, de fora pra dentro, com cobertura realista a custo razoável.
231
+
232
+ ### 9. Meça a *qualidade* do teste, não só a cobertura — mutation testing
233
+ Cobertura tradicional mente: pode mostrar 100% e nenhuma função retornar o certo, porque ela mede
234
+ linha **visitada**, não **testada** (asserção certa). É como provar trabalho mostrando carimbos no
235
+ passaporte. Mutation testing (Stryker) **planta bugs** no código (`price === 0` vira `price != 0`)
236
+ e roda a suíte: se os testes passam mesmo assim, o mutante "sobreviveu" — seu teste não pega aquele
237
+ bug. Mutante morto = teste de verdade.
238
+
239
+ ```javascript
240
+ // ❌ 100% de cobertura, 0% de teste — visita tudo, não verifica nada
241
+ function addNewOrder(o) { logger.log(o); DB.save(o); Mailer.sendMail(o.assignee, "..."); return { approved: true }; }
242
+ it("Test addNewOrder", () => { addNewOrder({ assignee: "j@x.com", price: 120 }); }); // sem expect
243
+ ```
244
+
245
+ Complemente com **lint de teste** (`eslint-plugin-jest`/`-mocha`): pega teste sem asserção, teste
246
+ skipado, título duplicado — coisas que viram "90% verde" enganoso.
247
+
248
+ ### 10. Garanta o contrato entre serviços — contract tests
249
+ Microsserviço com múltiplos clientes: você muda um campo e quebra um cliente importante. O provider
250
+ publica o typing da API (JSDoc/TypeScript) como pacote npm, e os consumidores ganham validação em
251
+ tempo de build. Abordagem mais rica: **PACT** — o cliente define as expectativas, grava num "broker",
252
+ e o servidor roda contra elas em todo build, pegando o mismatch cedo no CI.
253
+
254
+ ### 11. Cubra os 5 resultados possíveis de um fluxo (foco no de fora, não no como)
255
+ Ao planejar o que verificar numa ação (ex.: chamada de API), cubra os cinco resultados observáveis
256
+ de fora: **(1) Response** (dados, schema, status HTTP) · **(2) Novo estado** (dado publicamente
257
+ acessível mudou) · **(3) Chamadas externas** (SMS, e-mail, cobrança) · **(4) Filas de mensagem**
258
+ (mensagem publicada) · **(5) Observabilidade** (erro tratado, log/métrica certos — o "usuário ops"
259
+ também é usuário).
260
+
261
+ ## Checklist (qualquer "sim" é um tell a corrigir)
262
+
263
+ - [ ] Algum nome de teste não tem as 3 partes (o quê / cenário / esperado)?
264
+ - [ ] Tem teste sem separação AAA, ou com asserção imperativa (`if`/`forEach`/flag) em vez de `expect`?
265
+ - [ ] Algum teste verifica método privado / internal que não é requisito?
266
+ - [ ] Tem mock checando "foi chamado com esses args" em vez de stub/spy de comportamento?
267
+ - [ ] Input é `"Foo"`/`123` em vez de dado realista (Faker) ou property-based onde compensa?
268
+ - [ ] Tem `setTimeout`/sleep esperando async em vez de espera determinística do framework?
269
+ - [ ] Tem seed global de DB em vez de dado criado por-teste?
270
+ - [ ] Selector de teste de lógica depende de classe CSS em vez de `data-test-id`?
271
+ - [ ] Tem snapshot externo gigante em vez de inline curto (3–7 linhas) e focado?
272
+ - [ ] Existe teste sem nenhuma asserção (cobre linha, não testa nada)?
273
+ - [ ] A confiança vem só de "% de cobertura", sem mutation testing nos caminhos críticos?
274
+ - [ ] A estratégia é "só unit" mesmo numa feature integração-cêntrica?
275
+
276
+ ## Tabela de decisão (use X quando Y)
277
+
278
+ | Quando Y | Use X | O que pega / o que custa |
279
+ |---|---|---|
280
+ | Lógica pura, sem IO (cálculo, classificação, validação) | **Unit test** (black-box, API pública) | Pega bug de lógica; barato e rápido, mas cobre pouca área por teste |
281
+ | Feature que cruza camadas de **um** serviço (rota → lógica → DB) | **Component test** (API real, DB real/in-memory, stub do externo) | Pega bug de integração interna com cobertura realista; melhor ROI no backend |
282
+ | Risco de mismatch de schema **entre** serviços/clientes | **Contract test** (typing publicado ou PACT) | Pega quebra de contrato no CI, antes do deploy; setup extra no provider+consumer |
283
+ | Validar fluxo ponta-a-ponta (front + backend real) | **E2E**, mas só **1–10** sobre staging production-like | Pega falha de deploy e de integração front↔back; caro, frágil, lento — use com parcimônia |
284
+ | Sanidade de produção / dev | **1 smoke E2E** que percorre o site map | ROI altíssimo, pega falha funcional/rede/empacotamento; não substitui teste funcional |
285
+ | Input com muitas permutações possíveis | **Property-based** (fast-check) sobre o unit | Acha o caso de borda que você não imaginou; roda N vezes, um pouco mais lento |
286
+ | Você quer saber se os testes **prestam** (não só cobrem) | **Mutation testing** (Stryker) nos caminhos críticos | Mede teste real (mutante morto); setup ~igual ao de cobertura, execução mais cara |
287
+ | Componente UI (lógica + alguns filhos, tamanho razoável) | **Render realista** (`mount`) + query por `data-test-id` | Pega bug que dado certo não chega na UI; evite shallow + chamar método interno |
288
+ | Recurso externo lento/instável num teste não-E2E (API backend) | **Stub** (nock/Sinon) | Mata flakiness e ~20x de lentidão; nunca stube o que você está justamente testando |
289
+ | Async com tempo desconhecido (animação, fetch) | Espera **determinística** do framework (`waitFor`, `cy.wait`, fake timers) | Determinismo sem sleep; sleep troca lentidão por flakiness |
290
+ | Asserção em markup que muda muito | **Inline snapshot** curto (3–7 linhas) sobre o trecho que importa | Self-explanatory e estável; snapshot externo gigante quebra por espaço/CSS |
291
+
292
+ ## O que NÃO testar
293
+
294
+ - **Métodos privados / internals** — cobertos implicitamente pela API pública; testá-los só cria
295
+ testes frágeis e custo de manutenção.
296
+ - **Como (interação interna)** quando o que importa é o **resultado observável** — não verifique
297
+ "chamou o DAL com esses args"; verifique o efeito que é requisito.
298
+ - **100% de tudo** — 100% desloca o foco dos caminhos críticos pros cantos exóticos; ~80% é o número
299
+ de bolso (Fowler: "nos 80s ou 90s altos"), e o limiar é contextual (A380 ≠ site de cartoon).
300
+ - **Detalhe gráfico (HTML/CSS) em teste de lógica** — separe UI de funcionalidade; asserte dado contra
301
+ dado.
302
+ - **Documento gigante via snapshot externo** que ninguém leu — 1000 motivos pra falhar, zero sinal útil.
303
+ - Às vezes vale **dropar um teste** e trocar confiabilidade por agilidade — o Golden Rule manda manter
304
+ a suíte enxuta e deliciosa de manter, não exaustiva por exaustão.
305
+
306
+ ---
307
+ *Fonte: [goldbergyoni/javascript-testing-best-practices](https://github.com/goldbergyoni/javascript-testing-best-practices) — Yoni Goldberg. Exemplos de código extraídos do repositório real.*
@@ -0,0 +1,56 @@
1
+ ---
2
+ sla:
3
+ P0: imediato
4
+ P1: menos de 4h
5
+ P2: menos de 24h
6
+ P3: menos de 1 semana
7
+ categorias:
8
+ - { categoria: Dívida técnica, dono: architect, mitigador: dev, escalacao: nexus-master, severidade: P2 }
9
+ - { categoria: Regressão de qualidade, dono: qa, mitigador: dev, escalacao: nexus-master, severidade: P1 }
10
+ - { categoria: Vulnerabilidade de segurança, dono: qa, mitigador: devops, escalacao: nexus-master, severidade: P0 }
11
+ - { categoria: Estouro de custo, dono: pm, mitigador: nexus-master, escalacao: nexus-master, severidade: P1 }
12
+ - { categoria: Perda ou corrupção de dados, dono: data-engineer, mitigador: devops, escalacao: nexus-master, severidade: P0 }
13
+ - { categoria: Escopo furado (invenção), dono: po, mitigador: pm, escalacao: nexus-master, severidade: P2 }
14
+ - { categoria: Dependência externa instável, dono: devops, mitigador: architect, escalacao: nexus-master, severidade: P2 }
15
+ - { categoria: Acessibilidade/UX quebrada, dono: ux-design-expert, mitigador: dev, escalacao: nexus-master, severidade: P2 }
16
+ - { categoria: Falha de release, dono: devops, mitigador: dev, escalacao: nexus-master, severidade: P0 }
17
+ - { categoria: Requisito ambíguo, dono: analyst, mitigador: pm, escalacao: nexus-master, severidade: P3 }
18
+ ---
19
+
20
+ # Matriz de risco — donos, mitigadores e SLA
21
+
22
+ > A FONTE ÚNICA é o frontmatter YAML acima; a tabela abaixo é derivada dele. Um risco sem dono é um
23
+ > risco órfão — o validator `risk-ownership` confere que todo dono, mitigador e escalação existe no
24
+ > roster. O SLA amarra a severidade ao tempo de resposta esperado.
25
+
26
+ ## SLA por severidade
27
+
28
+ | Severidade | Resposta esperada |
29
+ |---|---|
30
+ | P0 | imediato |
31
+ | P1 | menos de 4h |
32
+ | P2 | menos de 24h |
33
+ | P3 | menos de 1 semana |
34
+
35
+ ## Categorias (10)
36
+
37
+ | Categoria | Dono (detecta) | Mitigador (corrige) | Escalação | Severidade |
38
+ |---|---|---|---|---|
39
+ | Dívida técnica | architect | dev | nexus-master | P2 |
40
+ | Regressão de qualidade | qa | dev | nexus-master | P1 |
41
+ | Vulnerabilidade de segurança | qa | devops | nexus-master | P0 |
42
+ | Estouro de custo | pm | nexus-master | nexus-master | P1 |
43
+ | Perda ou corrupção de dados | data-engineer | devops | nexus-master | P0 |
44
+ | Escopo furado (invenção) | po | pm | nexus-master | P2 |
45
+ | Dependência externa instável | devops | architect | nexus-master | P2 |
46
+ | Acessibilidade/UX quebrada | ux-design-expert | dev | nexus-master | P2 |
47
+ | Falha de release | devops | dev | nexus-master | P0 |
48
+ | Requisito ambíguo | analyst | pm | nexus-master | P3 |
49
+
50
+ ## Como usar
51
+
52
+ - **Dono** monitora a categoria e levanta a bandeira quando o risco aparece (ele detecta, não
53
+ necessariamente conserta).
54
+ - **Mitigador** executa a correção sob o SLA da severidade.
55
+ - **Escalação** entra quando o SLA estoura ou o mitigador não converge — o `nexus-master` medeia.
56
+ - Um risco P0 (segurança, dados, release) para a linha: imediato, sem exceção.
@@ -0,0 +1,235 @@
1
+ ---
2
+ id: mcp-server-selection-matrix
3
+ domain: integration
4
+ agents: [devops]
5
+ when: "ao escolher e adicionar um servidor MCP ao roster do projeto"
6
+ ---
7
+
8
+ # Matriz de seleção de servidor MCP — o melhor por categoria do NEXUS
9
+
10
+ Adicionar um MCP ao roster é decisão de DevOps (@devops detém a authority exclusiva de add/remove/configure de
11
+ MCP). O erro comum é tratar isso como "instala o primeiro que aparece na busca": pega-se um fork community não
12
+ mantido, com token de admin, write habilitado, sem nunca ter rodado o servidor uma vez fora do agente. Este pack dá
13
+ a **matriz canônica** (melhor servidor por categoria), o critério de escolha e o passo **obrigatório** de validar
14
+ com o **MCP Inspector** antes de qualquer `mcp add`.
15
+
16
+ ## O problema
17
+
18
+ Os tells de um roster de MCP mal montado:
19
+
20
+ 1. **Fork community no lugar do oficial** — pega `asifdotpy/github-mcp-server` em vez de `github/github-mcp-server`;
21
+ `bkeys73/mcp-supabase` em vez de `supabase-community/supabase-mcp`. O awesome-mcp-servers lista 142 servidores de
22
+ database e 188 de busca — a maioria é redundante. Sem marcar o oficial, escolhe-se ruído.
23
+ 2. **Servidor arquivado tratado como vivo** — `@modelcontextprotocol/server-github`, `server-postgres`,
24
+ `server-brave-search`, `server-puppeteer`, `server-gitlab` etc. **foram arquivados** para `servers-archived`. Quem
25
+ copia config de tutorial velho instala um servidor morto.
26
+ 3. **Write por padrão** — adiciona supabase ou github sem `--read-only`. O agente ganha poder de `DROP TABLE` ou
27
+ `git push --force` num servidor que devia só ler.
28
+ 4. **Credencial com escopo total** — um Personal Access Token `repo` + `admin:org` colado no env quando o agente só
29
+ precisava ler issues. Token vaza no log, no handoff, no histórico do shell.
30
+ 5. **Nunca validou** — adiciona o MCP direto no roster e descobre no meio de uma story que o servidor não sobe, pede
31
+ prompt em vez de expor tools, ou expõe 60 tools quando precisava de 5.
32
+ 6. **Transport errado** — usa stdio (local, processo filho) onde queria HTTP remoto gerenciado, ou vice-versa, e
33
+ depois briga com Docker/credencial que nem precisava existir.
34
+
35
+ ## O conhecimento
36
+
37
+ ### Critério de escolha (a ordem importa)
38
+
39
+ ```text
40
+ 1. Oficial > community # mantido pelo vendor/steering group, não por um fork
41
+ 2. Manutenção ativa # commits recentes, releases, issues respondidas
42
+ 3. Read-only por padrão # write só quando a categoria exige e a story justifica
43
+ 4. Credencial de escopo mínimo # o menor token/role que faz a tool funcionar
44
+ 5. Transport adequado # stdio p/ local-dev, HTTP/SSE p/ remoto gerenciado
45
+ 6. Validado no MCP Inspector # GATE — nunca entra no roster sem passar por aqui
46
+ ```
47
+
48
+ "Oficial" tem um significado concreto: os **reference servers** vivem em `modelcontextprotocol/servers` e são
49
+ mantidos pelo steering group; os servidores de vendor (`github/`, `supabase-community/`, `microsoft/`, `exa-labs/`,
50
+ `brave/`) são o canônico de cada produto. Tudo o mais é community — útil, mas só depois de descartar o oficial.
51
+
52
+ ### Transport: stdio vs HTTP/SSE
53
+
54
+ | Transport | Como roda | Quando usar | Custo |
55
+ |---|---|---|---|
56
+ | **stdio** | processo filho local (`npx`/`uvx`/binário) | dev local, filesystem/git, controle total da credencial | você gerencia processo + token |
57
+ | **HTTP/SSE (remoto)** | endpoint hospedado pelo vendor, OAuth | quando o vendor oferece remoto gerenciado (GitHub, Exa, Supabase) | sem Docker/atualização manual, mas depende do vendor |
58
+
59
+ Regra prática: **filesystem, git e qualquer coisa que toque o disco do dev → stdio sempre.** Serviço de nuvem com
60
+ remoto oficial (GitHub `https://api.githubcopilot.com/mcp/`, Exa `https://mcp.exa.ai/mcp`, Supabase
61
+ `https://mcp.supabase.com/mcp`) → prefira o **HTTP remoto** e evite manter Docker/binário/atualização à mão.
62
+
63
+ ### A matriz — melhor MCP por categoria do NEXUS
64
+
65
+ | Categoria NEXUS | Servidor canônico | Origem | Transport | Escopo de tools | Agente consumidor |
66
+ |---|---|---|---|---|---|
67
+ | Dados / DB | `supabase-community/supabase-mcp` | oficial (vendor) | stdio (npx) **ou** HTTP remoto | `execute_sql`, `apply_migration`, branches, projetos | @data-engineer, @dev |
68
+ | Browser / QA | `microsoft/playwright-mcp` (`@playwright/mcp`) | oficial (Microsoft) | stdio (npx) | navegar, snapshot a11y, click/type, screenshot | @qa, @ux-design-expert |
69
+ | DevOps / Git remoto | `github/github-mcp-server` | oficial (GitHub) | HTTP remoto **ou** stdio/Docker | issues, PRs, repos, actions (por toolset) | **@devops apenas** |
70
+ | Filesystem | `@modelcontextprotocol/server-filesystem` | reference (steering group) | stdio (npx) | leitura/escrita de arquivo com paths permitidos | @dev |
71
+ | Git local | `mcp-server-git` | reference (steering group) | stdio (uvx) | ler/buscar/manipular repo Git local | @dev |
72
+ | Fetch / web → markdown | `mcp-server-fetch` | reference (steering group) | stdio (uvx) | buscar URL e converter p/ LLM | @analyst, @dev |
73
+ | Memória / knowledge graph | `@modelcontextprotocol/server-memory` | reference (steering group) | stdio (npx) | grafo de conhecimento persistente | @analyst |
74
+ | Busca web | `exa-labs/exa-mcp-server` **ou** `brave/brave-search-mcp-server` | oficial (vendor) | HTTP remoto (Exa) / stdio (Brave) | `web_search`, research, crawling | @analyst |
75
+
76
+ > **Authority:** adicionar/remover/configurar QUALQUER linha desta matriz é operação **exclusiva do @devops**. O
77
+ > servidor `github-mcp-server` em particular só é consumido pelo @devops — push, PR e gerência de repo remoto não
78
+ > saem de outro agente.
79
+
80
+ ### Config: ruim → bom
81
+
82
+ #### Filesystem — escopo de paths
83
+
84
+ ```jsonc
85
+ // RUIM — sem restrição: o agente lê/escreve qualquer lugar do disco
86
+ { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/"] }
87
+
88
+ // BOM — paths permitidos explícitos; o servidor recusa fora deles
89
+ { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem",
90
+ "/Users/me/projeto/docs", "/Users/me/projeto/packages"] }
91
+ ```
92
+
93
+ #### Git local — repo escopado
94
+
95
+ ```jsonc
96
+ // RUIM — server arquivado + sem repo definido
97
+ { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-git"] } // não existe mais
98
+
99
+ // BOM — reference server oficial via uvx, repo explícito
100
+ { "command": "uvx", "args": ["mcp-server-git", "--repository", "/Users/me/projeto"] }
101
+ ```
102
+
103
+ #### Supabase — read-only e projeto escopado
104
+
105
+ ```jsonc
106
+ // RUIM — write habilitado, sem escopo de projeto, token inline com todos os escopos
107
+ { "command": "npx", "args": ["-y", "@supabase/mcp-server-supabase"],
108
+ "env": { "SUPABASE_ACCESS_TOKEN": "sbp_live_admin_total_no_codigo" } }
109
+
110
+ // BOM — --read-only (queries rodam como Postgres read-only user),
111
+ // --project-ref escopa só o projeto, token vem do ambiente
112
+ { "command": "npx",
113
+ "args": ["-y", "@supabase/mcp-server-supabase", "--read-only", "--project-ref=abcdef123456"],
114
+ "env": { "SUPABASE_ACCESS_TOKEN": "${SUPABASE_ACCESS_TOKEN}" } }
115
+ ```
116
+
117
+ `--read-only` faz `execute_sql`/`apply_migration` rodarem como usuário Postgres read-only; `--project-ref` remove as
118
+ tools de nível de conta (`list_projects`, `list_organizations`). Em CI, prefira o remoto:
119
+ `https://mcp.supabase.com/mcp?project_ref=abc123&read_only=true`.
120
+
121
+ #### GitHub — read-only, toolsets e remoto
122
+
123
+ ```jsonc
124
+ // RUIM — server arquivado, token com escopo total no código
125
+ { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"], // arquivado
126
+ "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_token_repo_admin_org_workflow" } }
127
+
128
+ // BOM (stdio/binário) — oficial, read-only, só os toolsets necessários, token do ambiente
129
+ { "command": "github-mcp-server", "args": ["stdio", "--read-only", "--toolsets=repos,issues,pull_requests"],
130
+ "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_PAT}" } }
131
+ ```
132
+
133
+ ```http
134
+ # BOM (remoto HTTP) — sem Docker, OAuth, headers de hardening
135
+ # endpoint:
136
+ https://api.githubcopilot.com/mcp/
137
+ X-MCP-Readonly: true
138
+ X-MCP-Toolsets: repos,issues,pull_requests
139
+ ```
140
+
141
+ #### Playwright — perfil isolado e capabilities mínimas
142
+
143
+ ```jsonc
144
+ // RUIM — perfil persistente (estado vaza entre sessões), todas as caps
145
+ { "command": "npx", "args": ["@playwright/mcp@latest", "--caps=vision,pdf,devtools"] }
146
+
147
+ // BOM — --isolated (sessão descartável, sem storage state vazando), só a cap que a story pede
148
+ { "command": "npx", "args": ["@playwright/mcp@latest", "--isolated", "--caps=vision"] }
149
+ ```
150
+
151
+ #### Busca — chave de escopo mínimo
152
+
153
+ ```jsonc
154
+ // RUIM — server de busca arquivado
155
+ { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-brave-search"], // arquivado
156
+ "env": { "BRAVE_API_KEY": "chave_colada" } }
157
+
158
+ // BOM (Brave) — server oficial do vendor, chave do ambiente
159
+ { "command": "npx", "args": ["-y", "@brave/brave-search-mcp-server"],
160
+ "env": { "BRAVE_API_KEY": "${BRAVE_API_KEY}" } }
161
+
162
+ // BOM (Exa) — remoto, sem setup local; ou local com --tools restrito
163
+ { "url": "https://mcp.exa.ai/mcp" }
164
+ // local, só as tools que a story usa:
165
+ { "command": "npx", "args": ["-y", "exa-mcp-server", "--tools=web_search_exa,crawling"],
166
+ "env": { "EXA_API_KEY": "${EXA_API_KEY}" } }
167
+ ```
168
+
169
+ ### O GATE obrigatório: validar no MCP Inspector ANTES do roster
170
+
171
+ **Nenhum servidor entra no roster sem passar pelo Inspector.** O Inspector (`@modelcontextprotocol/inspector`) sobe o
172
+ servidor isolado, mostra as tools/resources reais e prova que a credencial funciona — antes de você confiar nele
173
+ dentro de um agente.
174
+
175
+ ```bash
176
+ # 1. CLI mode — lista as tools que o servidor REALMENTE expõe (não as que o README promete)
177
+ npx @modelcontextprotocol/inspector --cli node build/index.js --method tools/list
178
+
179
+ # 2. Passa a credencial via -e e roda o binário/comando real do servidor
180
+ npx @modelcontextprotocol/inspector -e SUPABASE_ACCESS_TOKEN=$SUPABASE_ACCESS_TOKEN \
181
+ npx -y @supabase/mcp-server-supabase --read-only --project-ref=abcdef123456
182
+
183
+ # 3. UI mode — abre o cliente em :6274 (proxy em :6277) p/ inspeção interativa
184
+ npx @modelcontextprotocol/inspector node build/index.js
185
+ ```
186
+
187
+ Sinais de **reprovação** no Inspector (não adicione ao roster):
188
+ - Mostra **"(N prompts)" em vez de "(N tools)"** — o servidor subiu mas **falhou autenticação** (credencial não
189
+ chegou). Corrija o env antes de prosseguir.
190
+ - A lista de tools não bate com o esperado, ou expõe write quando você passou `--read-only`.
191
+ - O servidor não sobe, trava ou exige um runtime que o projeto não tem.
192
+
193
+ Só depois de uma `tools/list` limpa, com a credencial certa e o escopo correto, o @devops roda o `mcp add`.
194
+
195
+ ### Hardening — não-negociável
196
+
197
+ - **Read-only por padrão.** DB, git remoto e qualquer servidor com poder de escrita entram com `--read-only` (ou
198
+ `X-MCP-Readonly: true`). Write só quando a story exige e o @devops aprova.
199
+ - **Escopo de credencial mínimo.** O menor PAT/role que faz a tool funcionar. GitHub: só os escopos que você se
200
+ sente confortável em dar ao agente; nunca `admin:org` "por garantia". Supabase: `--project-ref` para tirar as
201
+ tools de conta.
202
+ - **Credencial via ambiente, nunca inline.** Token vai em `${VAR}`/env, não colado no JSON que vira commit/handoff.
203
+ - **Tools/toolsets enxutos.** `--toolsets` (GitHub), `--tools` (Exa), `--caps` (Playwright) reduzem a superfície:
204
+ menos tools expostas = menos vetor de erro/abuso.
205
+ - **Sessão descartável onde fizer sentido.** Playwright `--isolated` evita vazar storage state entre stories.
206
+
207
+ ## Checklist
208
+
209
+ Antes de o @devops rodar `mcp add`, todo "não" é um bloqueio:
210
+
211
+ - [ ] É o servidor **oficial** da categoria (reference do steering group ou do vendor), não um fork community?
212
+ - [ ] O servidor **não está arquivado** (não é `@modelcontextprotocol/server-{github,postgres,brave-search,...}`)?
213
+ - [ ] Tem **manutenção ativa** (commits/releases recentes)?
214
+ - [ ] O **transport** é o certo (stdio p/ local; HTTP remoto quando o vendor oferece gerenciado)?
215
+ - [ ] Está em **read-only** por padrão (ou a escrita é justificada pela story)?
216
+ - [ ] A **credencial é de escopo mínimo** e vem do **ambiente** (`${VAR}`), nunca inline?
217
+ - [ ] O conjunto de **tools/toolsets/caps** está enxuto p/ o que a story precisa?
218
+ - [ ] Foi **validado no MCP Inspector** — `tools/list` limpa, mostra "(N tools)" e não "(N prompts)"?
219
+ - [ ] É consumido pelo **agente certo** (ex.: `github-mcp-server` só @devops)?
220
+
221
+ ## Tabela de decisão
222
+
223
+ | Situação | Decisão |
224
+ |---|---|
225
+ | Preciso ler/escrever arquivos do projeto | `@modelcontextprotocol/server-filesystem` (stdio) com paths permitidos explícitos |
226
+ | Preciso operar um repo Git **local** | `mcp-server-git` (uvx, stdio) com `--repository` escopado |
227
+ | Preciso de issues/PRs/repo **remoto** no GitHub | `github/github-mcp-server` — remoto HTTP ou stdio, **read-only + toolsets**, **só @devops** |
228
+ | Preciso consultar/migrar banco Supabase | `supabase-community/supabase-mcp` com `--read-only` + `--project-ref` |
229
+ | Preciso de QA de browser / screenshot | `microsoft/playwright-mcp` (`--isolated`, `--caps` mínimo) |
230
+ | Preciso de busca web p/ pesquisa | Exa (`https://mcp.exa.ai/mcp`, remoto) ou Brave (oficial, stdio) com `--tools` restrito |
231
+ | Preciso buscar URL e virar markdown | `mcp-server-fetch` (uvx, stdio) |
232
+ | Preciso de memória persistente entre sessões | `@modelcontextprotocol/server-memory` (stdio) |
233
+ | Encontrei só um fork community da categoria | Procure o oficial primeiro; se não existir, **só** após Inspector + hardening + aprovação @devops |
234
+ | O tutorial manda usar `@modelcontextprotocol/server-{github,postgres,...}` | **Recuse** — está arquivado; use o servidor do vendor |
235
+ | O Inspector mostra "(N prompts)" | **Não adicione** — credencial falhou; corrija o env e revalide |
@@ -0,0 +1,43 @@
1
+ # Copy que converte — clareza antes de esperteza
2
+
3
+ Copy de conversão não é escrever bonito. É fazer a pessoa parar, entender a oferta em três segundos e
4
+ ter uma razão para agir agora. O adjetivo empilhado ("inovador, revolucionário, único") é o que se
5
+ escreve quando não se tem uma promessa de verdade.
6
+
7
+ ## A anatomia que converte
8
+
9
+ 1. **Headline com promessa específica.** O que a pessoa ganha, em número quando possível. "Economize 6
10
+ horas por semana" vence "produtividade revolucionária". Especificidade é credibilidade.
11
+ 2. **Subheadline / abertura.** A razão de continuar lendo — o custo de não resolver ou a facilidade de resolver.
12
+ 3. **Corpo que antecipa objeções.** Cada "sim, mas..." do leitor (é caro? é difícil? funciona pra mim?)
13
+ respondido antes de ele fechar a página.
14
+ 4. **Prova.** Número, caso, garantia, redução de risco — o que torna o "sim" seguro.
15
+ 5. **Um call-to-action, sem atrito.** Uma ação clara, com o menor esforço possível.
16
+
17
+ ## Clareza vence esperteza
18
+
19
+ A pessoa tem de entender na primeira leitura. Trocadilho que precisa ser explicado já falhou. A copy
20
+ esperta premia o ego do autor; a copy clara converte. Na dúvida, corte a piada e diga a coisa.
21
+
22
+ ## Específico vence superlativo
23
+
24
+ | Fraco (superlativo) | Forte (específico) |
25
+ |---|---|
26
+ | "resultados incríveis" | "3 leads a mais por dia" |
27
+ | "solução revolucionária" | "configura em 5 minutos, sem código" |
28
+ | "atendimento de excelência" | "resposta em menos de 2 horas, sempre" |
29
+
30
+ ## Objeções: a venda mora nos "sim, mas..."
31
+
32
+ Liste o que o leitor pensa antes de fechar e responda cada um NA copy:
33
+ - "é caro" → mostre o retorno / o custo de não ter.
34
+ - "é complicado" → mostre a facilidade / o tempo de setup.
35
+ - "não funciona pra mim" → mostre o caso parecido com o dele.
36
+ - "e se eu me arrepender" → garantia / risco reduzido.
37
+
38
+ ## Anti-padrões
39
+
40
+ - Adjetivo empilhado sem promessa concreta.
41
+ - Dois CTAs — dividem a decisão; nenhum — não vende.
42
+ - Prometer o que o produto não entrega — copy é contrato; overpromise é churn.
43
+ - Esconder o preço/oferta atrás de esperteza — clareza fecha, mistério cansa.