<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>Blog Nextside</title><link>https://blog.nextside.tech/</link><description>Posts da Nextside — tecnologia, gestão e entregas rápidas, sem hype.</description><generator>Hugo</generator><language>pt-BR</language><lastBuildDate>Fri, 26 Jun 2026 11:37:21 -0300</lastBuildDate><atom:link href="https://blog.nextside.tech/index.xml" rel="self" type="application/rss+xml"/><item><title>Quanto cobrar por uma ferramenta: margem não é dev barato</title><link>https://blog.nextside.tech/posts/2026/06/22/quanto-cobrar-por-uma-ferramenta/</link><pubDate>Mon, 22 Jun 2026 09:00:00 -0300</pubDate><guid>https://blog.nextside.tech/posts/2026/06/22/quanto-cobrar-por-uma-ferramenta/</guid><dc:creator>Pablo Winter</dc:creator><category>agencias</category><category>precificacao</category><category>white-label</category><category>ferramentas-web</category><category>margem</category><description>A margem de revender uma ferramenta não vem de achar o dev mais barato. Vem de uma entrega previsível que não volta com bug na frente do seu cliente.</description><content:encoded><![CDATA[<h2>TL;DR<span class="hx:absolute hx:-mt-20" id="tldr"></span>
    <a href="#tldr" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Toda semana eu vejo a mesma cena. A agência fechou a estratégia, o cliente confiou, e aí ele pede uma ferramenta de verdade no site: uma calculadora de orçamento, um configurador, um assistente que responde sozinho. A agência topa, manda um preço, e seis semanas depois está pagando do próprio bolso pra terminar. O erro não foi cobrar caro. Foi cobrar no escuro.</p>
<p>Vou ser seco: a margem de uma ferramenta que você revende não vem de achar o dev mais barato. Vem de revender uma entrega previsível que não volta. O barato cobra a diferença depois, em retrabalho e na confiança do seu cliente.</p>
<p>Os números ancoram isso. 78% das agências raramente ou nunca cobram quando o escopo cresce no meio do caminho (<a href="https://www.ignitionapp.com/blog/preventing-agency-scope-creep"target="_blank" rel="noopener">Ignition, 2025</a>). O dinheiro vaza antes mesmo de o fornecedor sumir. E quando ele some, sobra pra você explicar pro cliente.</p>
<h2>O desconto que você arranca hoje volta como retrabalho amanhã<span class="hx:absolute hx:-mt-20" id="o-desconto-que-você-arranca-hoje-volta-como-retrabalho-amanhã"></span>
    <a href="#o-desconto-que-voc%c3%aa-arranca-hoje-volta-como-retrabalho-amanh%c3%a3" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O reflexo é sempre o mesmo: pra ter margem, a agência caça o dev mais barato. Faz sentido na planilha e quebra na entrega. Porque o preço do dev é só uma parte da conta. O resto, o que não está na proposta, é o que decide se sobrou margem.</p>
<p>(Se o seu time travou antes mesmo de chegar no preço, eu escrevi sobre <a href="/posts/2026/06/17/cliente-pediu-ferramenta-time-nao-da-conta/">esse momento exato aqui</a>.)</p>
<p>Pensa no que o barato não inclui. O retrabalho quando a primeira versão volta torta. As três semanas a mais que atrasam a sua entrega e fazem o cliente ligar perguntando. A ferramenta que cai numa segunda-feira de campanha grande, e quem leva a bronca é a SUA marca, não a do freela. O freela cobrou metade. Você pagou o dobro, só que parcelado em dor.</p>
<p>Barato não é preço. É prazo de validade.</p>
<blockquote>
  <p>&ldquo;Mas se eu pago mais caro no dev, minha margem some.&rdquo;</p>

</blockquote>
<p>Não. Sua margem some quando a entrega volta. Se você paga 30% a mais por alguém que entrega no prazo, com escopo fechado, e que não te deixa na mão na frente do cliente, você não gastou mais. Você comprou previsibilidade. E previsibilidade é a única coisa que dá pra revender com tranquilidade.</p>
<p>O caro de verdade nunca é a hora do dev. É o custo de oportunidade do projeto atrasado, o custo de refazer o que saiu errado, e o custo de um cliente que parou de confiar. Esses três não aparecem em nenhum orçamento. Mas saem todos do seu bolso.</p>
<h2>A conta que ninguém abre: o que faz o preço de uma ferramenta<span class="hx:absolute hx:-mt-20" id="a-conta-que-ninguém-abre-o-que-faz-o-preço-de-uma-ferramenta"></span>
    <a href="#a-conta-que-ningu%c3%a9m-abre-o-que-faz-o-pre%c3%a7o-de-uma-ferramenta" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Aqui está o erro estrutural que vejo direto: a agência precifica ferramenta com a régua de site. Por página, por hora de design, por tela. Só que ferramenta não é site com botão. O que custa numa ferramenta é o que acontece depois que o usuário clica.</p>
<p>Um site mostra. Uma ferramenta faz. E &ldquo;fazer&rdquo; é onde mora o custo:</p>
<ul>
<li><strong>A lógica de negócio.</strong> A regra que calcula, decide, valida. É invisível pro cliente e é a maior parte do trabalho.</li>
<li><strong>A integração.</strong> A ferramenta que conversa com o estoque, o CRM ou o pagamento do cliente custa muito mais que a que vive sozinha.</li>
<li><strong>O que sustenta depois.</strong> Login, dados de usuário, segurança. No dia que a ferramenta guarda informação de gente, o jogo muda de patamar.</li>
<li><strong>A escala.</strong> Aguentar dez pessoas é fácil. Aguentar a ferramenta no ar quando a campanha viraliza é outra história.</li>
</ul>
<p>Pra dar ordem de grandeza, sem fingir uma precisão que não existe. São faixas de mercado e variam muito por escopo:</p>
<table>
  <thead>
      <tr>
          <th>Tipo de ferramenta</th>
          <th>O que mais pesa no preço</th>
          <th>Ordem de grandeza (mercado)</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Calculadora ou quiz de lead</td>
          <td>lógica simples, quase sem integração</td>
          <td>a mais baixa: poucos milhares</td>
      </tr>
      <tr>
          <td>Configurador de produto</td>
          <td>regras de negócio + catálogo + visual</td>
          <td>média</td>
      </tr>
      <tr>
          <td>Assistente ou automação no site</td>
          <td>integração com os sistemas do cliente</td>
          <td>média-alta</td>
      </tr>
      <tr>
          <td>Ferramenta com login e dados de usuário</td>
          <td>conta, segurança, escala</td>
          <td>a mais alta</td>
      </tr>
  </tbody>
</table>
<p>O ponto não é decorar a tabela. É entender que duas coisas chamadas &ldquo;ferramenta&rdquo; podem ter dez vezes de diferença de custo. Quem precifica as duas igual perde dinheiro numa e perde o cliente na outra.</p>
<h3>Como precificar uma ferramenta sem saber quanto vai custar o dev?<span class="hx:absolute hx:-mt-20" id="como-precificar-uma-ferramenta-sem-saber-quanto-vai-custar-o-dev"></span>
    <a href="#como-precificar-uma-ferramenta-sem-saber-quanto-vai-custar-o-dev" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Você não chuta. Pede uma faixa fechada antes de fechar com o cliente. Um bom parceiro técnico te entrega o escopo e o preço fixo antes de começar, não uma estimativa que dobra no meio. Com a faixa na mão, você remarca com a sua margem e fecha sabendo exatamente quanto sobra.</p>
<p>É a diferença entre orçamento aberto e escopo fechado. Orçamento aberto é o convite pra surpresa: começa em X, vira 2X, e quem absorve é você. Escopo fechado é o contrário. Você sabe a conta antes de assinar, o seu cliente sabe <a href="/posts/2026/06/16/mvp-o-que-cortar-e-o-que-manter/">o que entra e o que fica de fora</a> antes de pagar. Os dois lados dormem tranquilos.</p>
<aside class="ns-cta ns-cta-mid" data-servico="discovery">
  <p class="eyebrow">● Nextside</p>

  <h3 class="ns-cta-title">Quer dar uma faixa fechada pro seu cliente antes de fechar o projeto, sem orçamento que estoura no meio? A gente faz isso num Discovery.</h3>

  <p class="ns-cta-meta">Validação técnica · 2-3 semanas · Entrega: roadmap &#43; protótipo.</p>

  <div class="ns-cta-actions">
    <a href="https://www.nextside.tech/?utm_source=blog&amp;utm_medium=cta&amp;utm_campaign=discovery&amp;utm_content=quanto-cobrar-por-uma-ferramenta-mid#discovery" class="btn btn-primary">Fale com a Nextside →</a></div>
</aside>

<h2>A margem real: você revende previsibilidade, não horas de dev<span class="hx:absolute hx:-mt-20" id="a-margem-real-você-revende-previsibilidade-não-horas-de-dev"></span>
    <a href="#a-margem-real-voc%c3%aa-revende-previsibilidade-n%c3%a3o-horas-de-dev" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Agora a virada. Você não está revendendo desenvolvimento. Está revendendo o resultado, com a sua marca na frente, sem o seu cliente nunca saber quem codou. Esse é o modelo <dfn>white-label</dfn>, em que o fornecedor entrega na sua marca e fica invisível. E a margem dele não nasce do desconto. Nasce da previsibilidade.</p>
<p>O markup de revenda no white-label costuma ficar entre 40% e 70% sobre o custo da entrega (<a href="https://www.cloudcampaign.com/blog/how-to-price-white-label-software"target="_blank" rel="noopener">CloudCampaign</a>). Parece muito até você perceber a condição que quase ninguém diz em voz alta: esse markup só sobrevive se a entrega não voltar. Cada projeto que volta com bug, cada prazo estourado, cada fornecedor que some come essa margem inteira. O markup não é lucro garantido. É lucro condicionado a uma entrega que funciona.</p>
<p>Faz a conta de um caso desses que eu vejo repetir. A agência fecha um configurador pro cliente por R$ 30 mil.</p>
<ul>
<li><strong>Caminho A.</strong> Acha um freela por R$ 8 mil e comemora a margem gorda. O freela atrasa, a primeira versão não bate com o catálogo, entra retrabalho, e o lançamento que era pra abril vai pra junho. A margem de R$ 22 mil virou prejuízo de reputação.</li>
<li><strong>Caminho B.</strong> Fecha com um parceiro previsível por R$ 15 mil, escopo travado, entrega no prazo. A margem no papel é menor, R$ 15 mil, mas é a margem que de fato ENTRA. E o cliente, satisfeito, volta com o próximo projeto.</li>
</ul>
<p>Uma agência feliz traz N projetos. Um cliente queimado não traz nenhum.</p>
<p>Desconto é margem que você ainda vai devolver. Previsibilidade é margem que fica.</p>
<h3>Qual margem dá pra cobrar revendendo desenvolvimento como agência?<span class="hx:absolute hx:-mt-20" id="qual-margem-dá-pra-cobrar-revendendo-desenvolvimento-como-agência"></span>
    <a href="#qual-margem-d%c3%a1-pra-cobrar-revendendo-desenvolvimento-como-ag%c3%aancia" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>A faixa praticada no white-label vai de 40% a 70% de markup sobre o custo da entrega. Mas o número que importa não é o teto, é o que sobra depois do retrabalho. Markup alto numa entrega que volta dá zero. Markup honesto numa entrega previsível é o que constrói a agência ao longo do tempo.</p>
<h2>Previsibilidade é o produto. O resto é sorte.<span class="hx:absolute hx:-mt-20" id="previsibilidade-é-o-produto-o-resto-é-sorte"></span>
    <a href="#previsibilidade-%c3%a9-o-produto-o-resto-%c3%a9-sorte" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>No fim, o seu cliente não está comprando uma ferramenta de você. Está comprando a tranquilidade de que aquilo vai funcionar quando ele mais precisar. É isso que você revende. A ferramenta é o objeto. A previsibilidade é o produto.</p>
<p>Quando você caça o dev mais barato, não está economizando. Está apostando que dessa vez vai dar certo. Às vezes dá. Mas você não montou uma agência pra viver de aposta.</p>
<p>O barato sempre cobra a diferença. A única pergunta é quando, e na frente de quem.</p>
]]></content:encoded></item><item><title>Recebi um MVP vibe-coded pra escalar: o diagnóstico honesto</title><link>https://blog.nextside.tech/posts/2026/06/19/recebi-mvp-vibe-coded-pra-escalar/</link><pubDate>Fri, 19 Jun 2026 10:00:00 -0300</pubDate><guid>https://blog.nextside.tech/posts/2026/06/19/recebi-mvp-vibe-coded-pra-escalar/</guid><dc:creator>Pablo Winter</dc:creator><category>vibe-coding</category><category>divida-tecnica</category><category>refatoracao</category><category>mvp</category><category>arquitetura</category><category>testes</category><description>Recebeu um MVP vibe-coded travado pra escalar? Reescrever do zero é o erro mais caro. O diagnóstico honesto: o que salvar, o que reescrever, como estabilizar.</description><content:encoded><![CDATA[<h2>TL;DR<span class="hx:absolute hx:-mt-20" id="tldr"></span>
    <a href="#tldr" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>De uns meses pra cá mudou o perfil de quem me procura. Antes era &ldquo;tenho uma ideia, faz pra mim&rdquo;. Agora é &ldquo;já tenho o app, ele até funciona, mas trava na hora de crescer, e eu não sei se conserto ou jogo fora&rdquo;. O produto foi <dfn>vibe coding: gerar software pedindo pra IA e aceitando o resultado sem ler nem entender o código que saiu</dfn>. Funciona o suficiente pra ter cliente pagando. E o suficiente pra dar medo.</p>
<p>A primeira decisão diante de um desses não é técnica. É de triagem. E a tentação mais cara, a que quase todo mundo tem no primeiro dia, é mandar reescrever tudo do zero. Quase sempre é erro. Na maioria dos casos não é transplante: é suíte de testes primeiro, depois bisturi no que de fato apodreceu. Salva-se muito mais do que o desespero sugere.</p>
<p>Os números explicam o susto e por que ele engana. 45% do código gerado por IA carrega <a href="https://www.veracode.com/blog/genai-code-security-report/"target="_blank" rel="noopener">uma falha do OWASP Top 10</a> (Veracode), e só <a href="https://arxiv.org/html/2508.14727v1"target="_blank" rel="noopener">10,5% do código vibe-coded passa num review de segurança decente</a> contra 61% que simplesmente &ldquo;funciona&rdquo; (Carnegie Mellon). Parece sentença de demolição. Não é. É a medida da distância entre funcionar e aguentar, e distância a gente mede ANTES de demolir, não depois.</p>
<p>Funciona não é o mesmo que pronto. Mas também não é o mesmo que lixo.</p>
<h2>Reescrever do zero é o erro mais caro que existe<span class="hx:absolute hx:-mt-20" id="reescrever-do-zero-é-o-erro-mais-caro-que-existe"></span>
    <a href="#reescrever-do-zero-%c3%a9-o-erro-mais-caro-que-existe" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Todo mundo que me liga com um app travado chega com a mesma sentença na ponta da língua:</p>
<blockquote>
  <p>&ldquo;Esse código é uma zona. É mais rápido refazer do zero do que entender essa bagunça.&rdquo;</p>

</blockquote>
<p>Calma lá. Essa frase é o canto da sereia mais caro da engenharia de software, e não fui eu que descobri isso. Joel Spolsky chamou reescrever do zero de <a href="https://www.joelonsoftware.com/2000/04/06/things-you-should-never-do-part-i/"target="_blank" rel="noopener">&ldquo;o pior erro estratégico que uma empresa de software pode cometer&rdquo;</a>, e isso foi em 2000, muito antes de a IA deixar a reescrita ainda mais tentadora e ainda mais cara.</p>
<p>Por que é erro? Porque você está prestes a jogar fora justamente a única coisa que esse MVP provou: que tem gente querendo. O código é feio, mas ele carrega meses de aprendizado embutido. Cada gambiarra esquisita é, na metade das vezes, um caso de borda real que algum cliente encontrou e que a versão &ldquo;limpa&rdquo; do zero vai redescobrir do jeito difícil, em produção, de novo.</p>
<p>Pensa no Twitter. Nasceu num monólito Rails porque era o que dois caras conseguiam tocar rápido o bastante pra achar product-market fit. Os problemas de escala vieram depois. Porque deu certo. Se tivessem começado &ldquo;do jeito certo&rdquo;, parrudo e distribuído, provavelmente não existiria Twitter pra ter problema de escala. A velocidade do vibe coding é real e é valiosa pra validar. O erro não é ter validado assim. É não trocar de marcha quando a validação acabou.</p>
<p>Reescrita do zero é a vaidade de quem acabou de chegar no projeto.</p>
<h2>Antes de tocar em qualquer linha, a suíte de testes<span class="hx:absolute hx:-mt-20" id="antes-de-tocar-em-qualquer-linha-a-suíte-de-testes"></span>
    <a href="#antes-de-tocar-em-qualquer-linha-a-su%c3%adte-de-testes" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Aqui está o passo que quase todo mundo pula, e é o que separa um resgate de um segundo desastre: você não conserta o que não consegue testar, nem refatora com segurança o que não cobriu antes. Teste não é o último passo do resgate. É o primeiro.</p>
<p>E é exatamente o que o código vibe-coded não tem. A IA gera com um viés brutal de caminho feliz: cobre o fluxo que você descreveu e ignora o resto do universo. Erro de rede, input inválido, dois cliques no mesmo botão, o usuário que faz na ordem errada. Nada disso existe no código, então nada disso quebra de forma visível. Até quebrar na frente do cliente.</p>
<blockquote>
  <p>&ldquo;Escrever teste antes de entregar feature nova? Vou ficar duas semanas sem mostrar nada pro board.&rdquo;</p>

</blockquote>
<p>Entendo a ansiedade, e ela está invertida. A suíte de testes não é tempo perdido antes de entregar valor. É o que te dá permissão pra mexer no código sem rezar. Sem ela, cada refactor é uma aposta cega: você arruma um bug e descobre, três dias depois, que quebrou dois outros que ninguém via. Com ela, você refatora de olhos abertos. É a diferença entre operar com luz acesa e operar no escuro.</p>
<p>Na prática, eu nem peço cobertura total de cara. Peço teste nos fluxos que dão dinheiro e nos que perdem dinheiro: o checkout, o login, o que mexe em saldo. É a rede de segurança mínima pra tudo que vem depois ser cirurgia, e não roleta. Essa mesma disciplina de validar antes de confiar a gente já destrinchou em <a href="/posts/2026/05/16/mcp-playwright-validacao-local-com-qualidade/">validação local com qualidade real</a>, só que ali aplicada ao fluxo de quem está construindo, não resgatando.</p>
<h2>O diagnóstico: lendo o extrato da dívida<span class="hx:absolute hx:-mt-20" id="o-diagnóstico-lendo-o-extrato-da-dívida"></span>
    <a href="#o-diagn%c3%b3stico-lendo-o-extrato-da-d%c3%advida" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Com rede de segurança no lugar, dá pra abrir o capô sem medo. O diagnóstico de um MVP vibe-coded quase sempre encontra os mesmos quatro buracos. Eu chamo de ler o extrato da dívida, porque é literalmente isso: descobrir quanto você deve e pra quem.</p>
<ul>
<li><strong>Arquitetura acoplada.</strong> A regra de negócio está grudada na infraestrutura, a API foi desenhada sem pensar em carga, o schema não aguenta crescer de lado. Funciona com cinquenta usuários porque tudo funciona com cinquenta usuários. O paper que formalizou isso chama de <a href="https://arxiv.org/abs/2512.11922"target="_blank" rel="noopener">flow-debt trade-off</a>: a fluidez de gerar código mascara a dívida que cresce em paralelo.</li>
<li><strong>Observabilidade ausente.</strong> Logging, trace e métrica entraram como pensamento tardio, ou não entraram. Quando cai às 3 da manhã, você não tem onde olhar. A frase da OneUptime fica na parede: <a href="https://oneuptime.com/blog/post/2026-02-15-vibe-coding-and-the-observability-gap/view"target="_blank" rel="noopener">&ldquo;observabilidade não é um nice to have, é a sua única rede de segurança&rdquo;</a>. No código vibe-coded ela é a substituta da revisão humana que nunca aconteceu.</li>
<li><strong>Segurança de enfeite.</strong> Chave de API hardcoded no repositório, autenticação com a lógica invertida, banco exposto sem regra de acesso. Não é exceção: a Apiiro mediu código gerado por IA somando <a href="https://apiiro.com/blog/4x-velocity-10x-vulnerabilities-ai-coding-assistants-are-shipping-more-risks/"target="_blank" rel="noopener">10x mais achados de segurança em seis meses</a>, com caminhos de escalonamento de privilégio subindo 322%.</li>
<li><strong>Deploy e CI frágeis.</strong> O caso clássico é preview, teste e produção dividindo o mesmo banco. Foi assim que a IA da Replit <a href="https://www.theregister.com/2025/07/21/replit_saastr_vibe_coding_incident/"target="_blank" rel="noopener">apagou o banco de produção</a> durante um congelamento de código explícito, em CAIXA ALTA no prompt, e depois mentiu dizendo que o rollback era impossível. A separação de ambientes é a lição mais barata e mais ignorada da lista.</li>
</ul>
<p>O extrato assusta de propósito. Mas extrato não é despejo. Ele te diz onde está a dívida cara e onde está a dívida que dá pra rolar, e essa distinção é o resgate inteiro.</p>
<h3>Como sei se a arquitetura dá pra salvar ou não?<span class="hx:absolute hx:-mt-20" id="como-sei-se-a-arquitetura-dá-pra-salvar-ou-não"></span>
    <a href="#como-sei-se-a-arquitetura-d%c3%a1-pra-salvar-ou-n%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>O critério prático é um só: o nível de acoplamento entre a regra de negócio e a infraestrutura, somado a se o modelo de dados aguenta crescer. Se a lógica que importa está enfiada no meio do controller, dependente de um detalhe do banco que não escala de lado, aquele pedaço é reescrita localizada: não tem como salvar a fundação sem refazê-la. Se a regra de negócio está minimamente isolada, mesmo que feia, é remediação: você melhora por dentro sem demolir. A maior parte de um MVP cai no segundo caso. É por isso que reescrita total quase nunca é a resposta certa: você condena o prédio inteiro por causa de dois cômodos.</p>
<h2>O que salvar e o que reescrever sem dó<span class="hx:absolute hx:-mt-20" id="o-que-salvar-e-o-que-reescrever-sem-dó"></span>
    <a href="#o-que-salvar-e-o-que-reescrever-sem-d%c3%b3" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Triagem é decidir o que entra no centro cirúrgico e o que recebe alta. Depois de fazer isso em vários apps, o padrão é bem estável.</p>
<p><strong>Salvar quase sempre:</strong> o modelo de domínio que reflete o negócio de verdade (os nomes das coisas e como se ligam), os fluxos que o usuário já validou na prática, e boa parte da interface. Esse é o conhecimento que custou meses e que uma reescrita joga no lixo de graça. A versão dessa disciplina no nível da estrutura do código a gente abriu em <a href="/posts/2026/06/15/codebase-novo-prompt-mvp-que-escala/">seu codebase é o novo prompt</a>: o que decide se escala não é a stack, é o repositório continuar navegável.</p>
<p><strong>Reescrever sem dó:</strong> a camada de autenticação e permissão (é onde mais dói deixar errado, porque toca toda requisição), a lógica de negócio que a IA duplicou em oito, dez, doze lugares, o schema que não aguenta tração, e as integrações sem nenhum fallback. A duplicação não é detalhe: em 2024, pela primeira vez na história, <a href="https://www.gitclear.com/ai_assistant_code_quality_2025_research"target="_blank" rel="noopener">código copiado e colado superou código refatorado</a>, com blocos duplicados crescendo 8x (GitClear). Cada cópia é um lugar a mais pra um bug se esconder e nunca ser corrigido em todos.</p>
<p>O que guia o corte é entender por que o app empaca onde empaca. Addy Osmani batizou de <a href="https://addyo.substack.com/p/the-70-problem-hard-truths-about"target="_blank" rel="noopener">70% problem</a>: a IA leva você rápido a 70%, só que é 70% do <em>volume</em> de código, não 70% do <em>caminho</em> até um produto pronto. Os 30% que faltam são exatamente o que não dá pra gerar no susto: caso de borda, manutenibilidade, performance, segurança. É a parte cara. É a parte que a triagem isola.</p>
<h3>Vibe coding serve pra produção?<span class="hx:absolute hx:-mt-20" id="vibe-coding-serve-pra-produção"></span>
    <a href="#vibe-coding-serve-pra-produ%c3%a7%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Serve pra chegar até a porta dela, não pra entrar. Vibe coding é um acelerador de validação espetacular: prova a hipótese, conquista os primeiros clientes, mostra que existe negócio. O erro não é usar. É confundir o protótipo que validou com o produto que escala, e seguir empilhando feature por cima de uma fundação que nunca foi feita pra carregar peso. A própria mecânica disso, de por que o &ldquo;pede, aceita, deploya&rdquo; empaca na hora de crescer, a gente discutiu em <a href="/posts/2026/06/13/spec-driven-development-sair-do-vibe-coding/">sair do vibe coding</a>. Vibe coding leva ao MVP. Método leva o MVP a produto.</p>
<aside class="ns-cta ns-cta-mid" data-servico="auditoria">
  <p class="eyebrow">● Nextside</p>

  <h3 class="ns-cta-title">Herdou um MVP vibe-coded travado? A Auditoria entrega o diagnóstico sem amarra comercial: o que salvar, o que reescrever e em que ordem, antes de você fechar o Sprint.</h3>

  <p class="ns-cta-meta">Auditoria independente · 1-2 semanas · Sem amarras comerciais.</p>

  <div class="ns-cta-actions">
    <a href="https://www.nextside.tech/?utm_source=blog&amp;utm_medium=cta&amp;utm_campaign=auditoria&amp;utm_content=recebi-mvp-vibe-coded-pra-escalar-mid#auditoria" class="btn btn-primary">Fale com a Nextside →</a></div>
</aside>

<h2>Estabilizar sem parar o negócio: a cirurgia com o paciente acordado<span class="hx:absolute hx:-mt-20" id="estabilizar-sem-parar-o-negócio-a-cirurgia-com-o-paciente-acordado"></span>
    <a href="#estabilizar-sem-parar-o-neg%c3%b3cio-a-cirurgia-com-o-paciente-acordado" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>A última peça, e a que mais diferencia um resgate competente, é o &ldquo;sem parar o negócio&rdquo;. Porque o app está no ar, tem cliente usando, tem fatura entrando. Você não pode desligar tudo por dois meses pra arrumar a casa. Tem que operar com o paciente acordado.</p>
<p>O jeito de fazer isso tem nome: <dfn>padrão Strangler: substituir o sistema velho por fora, módulo a módulo, enquanto ele continua rodando, até o novo estrangular o antigo</dfn>. Em vez do big bang (&ldquo;vira a chave do novo num domingo e reza&rdquo;), você escolhe um pedaço (a autenticação, digamos), constrói a versão nova ao lado, manda uma fração do tráfego pra ela com feature flag, confirma que aguenta, e só então aposenta a velha. Errou? Rollback num clique, ninguém percebe. Repete pro próximo módulo. O risco fica fatiado em pedaços que cabem no bolso, em vez de uma aposta única que pode derrubar a empresa.</p>
<p>E a primeira fatia, quase sempre, é a mais barata e a mais esquecida: separar os ambientes. Banco de produção é sagrado, tem backup automático testado, e ninguém, humano ou IA, encosta nele sem rede. É a correção que teria evitado o desastre da Replit inteiro, e custa um dia.</p>
<p>Tem trade-off, e eu não vendo milagre. No papel, o Strangler é mais lento que reescrever do zero: você mantém dois sistemas vivos ao mesmo tempo por um período, paga o custo de manter os dois falando. É chato. Mas é o preço de não parar de faturar enquanto opera, e é incomparavelmente mais barato que a reescrita que congela o produto por um trimestre e ainda chega atrasada. É o tipo de diagnóstico independente, sem amarra comercial, que a gente entrega numa Auditoria antes de qualquer linha ser tocada: o mapa do que salvar, do que reescrever e em que ordem mexer. O que cortar e o que manter quando se decide o escopo dessa reconstrução a gente abriu em <a href="/posts/2026/06/16/mvp-o-que-cortar-e-o-que-manter/">o que cortar e o que manter num MVP</a>.</p>
<h2>Funciona não é pronto. Mas também não é lixo.<span class="hx:absolute hx:-mt-20" id="funciona-não-é-pronto-mas-também-não-é-lixo"></span>
    <a href="#funciona-n%c3%a3o-%c3%a9-pronto-mas-tamb%c3%a9m-n%c3%a3o-%c3%a9-lixo" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O instinto diante de um MVP vibe-coded travado é binário: ou ele é maravilhoso porque está no ar, ou é lixo porque o código é feio. Os dois estão errados. Ele é exatamente o que parece: um protótipo que validou um negócio e agora precisa virar produto, com uma dívida que dá pra ler, item por item, e pagar na ordem certa.</p>
<p>A distância entre a demo que encantou e o sistema que aguenta tração é mensurável. Não é fé, é diagnóstico: testes pra acender a luz, o extrato pra saber o que se deve, a triagem pra separar o que salva do que reescreve, e o Strangler pra operar sem desligar o paciente. Quase sempre dá pra fazer sem demolir a casa.</p>
<p>Pronto é um estado que se prova, não que se sente.</p>
]]></content:encoded></item><item><title>Cliente pediu uma ferramenta e seu time não dá conta</title><link>https://blog.nextside.tech/posts/2026/06/17/cliente-pediu-ferramenta-time-nao-da-conta/</link><pubDate>Wed, 17 Jun 2026 09:00:00 -0300</pubDate><guid>https://blog.nextside.tech/posts/2026/06/17/cliente-pediu-ferramenta-time-nao-da-conta/</guid><dc:creator>Lucas Israel</dc:creator><category>agencias</category><category>ferramentas-web</category><category>terceirizacao</category><category>white-label</category><category>escopo-fechado</category><description>A demanda chegou, é dinheiro novo, e seu time travou. Por que software house sai caro, time interno sai mais caro ainda, e qual é a terceira saída.</description><content:encoded><![CDATA[<h2>TL;DR<span class="hx:absolute hx:-mt-20" id="tldr"></span>
    <a href="#tldr" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>A demanda por uma ferramenta de verdade no site do cliente é a melhor receita que uma agência pode ganhar: alta margem, recorrência, mais difícil de você ser trocado. Mas ela esbarra num problema real: você não tem dev, software house pede caro e some, e montar time interno é o jeito mais caro e arriscado de descobrir que dar não daria. A saída é entregar com um parceiro técnico sob a sua marca, sem virar empresa de software. <strong>O risco não está em aceitar o projeto. Está em aceitar do jeito errado.</strong></p>
<h2>Por que isso é uma oportunidade, não um problema<span class="hx:absolute hx:-mt-20" id="por-que-isso-é-uma-oportunidade-não-um-problema"></span>
    <a href="#por-que-isso-%c3%a9-uma-oportunidade-n%c3%a3o-um-problema" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Quando o cliente pede uma ferramenta (não um site, uma ferramenta que faz algo), ele está dizendo que confia em você para resolver um problema de negócio, não só de imagem. Esse é o tipo de trabalho que paga mais, dura mais e te tira da guerra de preço de landing page. É exatamente onde a agência deixa de ser fornecedora de design e vira parceira de operação.</p>
<p>O problema é que a oportunidade vem embrulhada num medo legítimo: &ldquo;e se eu aceitar e não conseguir entregar?&rdquo;. Esse medo é saudável. Ele só não pode virar o motivo de você devolver dinheiro pra concorrência.</p>
<h2>As três saídas que parecem óbvias (e onde cada uma quebra)<span class="hx:absolute hx:-mt-20" id="as-três-saídas-que-parecem-óbvias-e-onde-cada-uma-quebra"></span>
    <a href="#as-tr%c3%aas-sa%c3%addas-que-parecem-%c3%b3bvias-e-onde-cada-uma-quebra" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Recusar, contratar uma software house ou montar time interno são as reações naturais. Todas têm um custo escondido: a primeira te faz perder a conta, a segunda te faz perder margem e controle, a terceira te faz perder dinheiro por meses antes de você saber se valeu. Vale destrinchar.</p>
<h3>Recusar a demanda<span class="hx:absolute hx:-mt-20" id="recusar-a-demanda"></span>
    <a href="#recusar-a-demanda" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Parece prudente. Na prática, você ensina o cliente a procurar quem faz &ldquo;a parte de tecnologia&rdquo;, e essa pessoa, uma hora, também faz a parte de marketing. Você não só perde o projeto: abre a porta pra perder a conta.</p>
<h3>Chamar uma software house<span class="hx:absolute hx:-mt-20" id="chamar-uma-software-house"></span>
    <a href="#chamar-uma-software-house" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>O orçamento volta alto, o prazo volta longo, e o controle sai da sua mão. Pior: na frente do cliente, quem responde pela ferramenta é a sua marca, mas quem decide o ritmo é um fornecedor que você não controla. Quando trava, você está no meio, sem time pra resolver e sem o fornecedor por perto.</p>
<h3>Contratar um dev (ou um time)<span class="hx:absolute hx:-mt-20" id="contratar-um-dev-ou-um-time"></span>
    <a href="#contratar-um-dev-ou-um-time" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Essa é a que parece mais &ldquo;definitiva&rdquo; e é a mais cara de todas. Um desenvolvedor sênior no Brasil custa entre <strong>R$ 12 mil e R$ 20 mil por mês</strong> (<a href="https://www.glassdoor.com.br/Sal%C3%A1rios/desenvolvedor-s-nior-sal%C3%A1rio-SRCH_KO0,20.htm"target="_blank" rel="noopener">Glassdoor Brasil</a>), e isso é o salário, sem encargos, sem o tempo até ele produzir, sem o risco de ele sair em seis meses. Você está assumindo um custo fixo alto e recorrente por uma demanda que ainda é pontual. E aí vem a parte que ninguém da agência fala em voz alta: <strong>você não sabe contratar dev, não sabe avaliar se ele é bom, e não sabe segurar ele depois.</strong> Avaliar um profissional de uma área que não é a sua é uma aposta às cegas com seu próprio dinheiro.</p>
<aside class="ns-cta ns-cta-mid" data-servico="discovery">
  <p class="eyebrow">● Nextside</p>

  <h3 class="ns-cta-title">Quer entender se o seu próximo projeto cabe num parceiro ou pede time? Comece por um Discovery: escopo e custo na mesa antes de você decidir.</h3>

  <p class="ns-cta-meta">Validação técnica · 2-3 semanas · Entrega: roadmap &#43; protótipo.</p>

  <div class="ns-cta-actions">
    <a href="https://www.nextside.tech/?utm_source=blog&amp;utm_medium=cta&amp;utm_campaign=discovery&amp;utm_content=cliente-pediu-ferramenta-time-nao-da-conta-mid#discovery" class="btn btn-primary">Fale com a Nextside →</a></div>
</aside>

<h2>A quarta saída: entregar sob a sua marca, sem virar empresa de software<span class="hx:absolute hx:-mt-20" id="a-quarta-saída-entregar-sob-a-sua-marca-sem-virar-empresa-de-software"></span>
    <a href="#a-quarta-sa%c3%adda-entregar-sob-a-sua-marca-sem-virar-empresa-de-software" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Existe um meio-termo entre recusar e montar uma área de tecnologia: terceirizar a entrega para um parceiro técnico que trabalha sob a sua marca, com escopo e prazo fechados. Você mantém o cliente, a margem e o relacionamento; o parceiro entrega a ferramenta funcionando, e some do mapa do cliente. É o modelo que o mercado chama de <dfn>white-label: o parceiro técnico entrega sob a sua marca e não aparece para o seu cliente</dfn>, e existe justamente porque dev sênior interno é caro demais para a maioria das agências (<a href="https://xovakstudio.com/pages/white-label-web-development-for-agencies"target="_blank" rel="noopener">Xovak</a>).</p>
<p>A diferença entre isso e a software house tradicional não é só preço. É como o trabalho é feito: escopo definido na frente, prazo curto, entrega por fases com você aprovando cada passo. Você não compra &ldquo;horas de desenvolvimento&rdquo; sem fim. Você compra um resultado, com data e valor combinados antes de começar.</p>
<h2>Onde isso também quebra (porque tudo tem trade-off)<span class="hx:absolute hx:-mt-20" id="onde-isso-também-quebra-porque-tudo-tem-trade-off"></span>
    <a href="#onde-isso-tamb%c3%a9m-quebra-porque-tudo-tem-trade-off" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Parceiro errado é tão ruim quanto não ter parceiro. O modelo só funciona se três coisas estiverem claras: o escopo é fechado (sem &ldquo;depois a gente vê&rdquo;), o código fica com o cliente (ou com você, nunca refém do fornecedor), e a ferramenta nasce bem-feita, não uma gambiarra barata que trava na frente do cliente final e vira sua dor de cabeça. Ferramenta barata e mal feita é mais cara que software house: você paga duas vezes, e a segunda na frente do seu cliente. Se o parceiro não topa fechar escopo e prazo antes de começar, é o sinal de que você vai virar a software house, só que sem o time.</p>
<h2>Como decidir, na prática<span class="hx:absolute hx:-mt-20" id="como-decidir-na-prática"></span>
    <a href="#como-decidir-na-pr%c3%a1tica" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Se a demanda é pontual e você quer testar o apetite do cliente sem assumir custo fixo: parceiro, escopo fechado. Se a demanda virou recorrente e previsível a ponto de pagar um salário todo mês com folga: aí, talvez, faça sentido pensar em time, mas só depois de já ter entregue algumas vezes com parceiro e entendido o que esse trabalho exige. Começar pelo time é apostar antes de ter a informação.</p>
<p>A regra simples: não monte estrutura para uma demanda que você ainda não validou. Entregue primeiro, aprenda o custo real, e só então decida se vira operação interna.</p>
<h2>FAQ<span class="hx:absolute hx:-mt-20" id="faq"></span>
    <a href="#faq" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><h3>Quanto custa entregar uma ferramenta dessas via parceiro?<span class="hx:absolute hx:-mt-20" id="quanto-custa-entregar-uma-ferramenta-dessas-via-parceiro"></span>
    <a href="#quanto-custa-entregar-uma-ferramenta-dessas-via-parceiro" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Depende do escopo, mas o ponto do modelo é justamente ter o valor fechado antes de começar, não horas abertas. Uma ferramenta simples (calculadora, formulário inteligente, configurador) costuma sair por uma fração do que uma software house cobra por um projeto &ldquo;do zero&rdquo;, porque o escopo é enxuto e o método é padronizado.</p>
<h3>O cliente vai saber que terceirizei?<span class="hx:absolute hx:-mt-20" id="o-cliente-vai-saber-que-terceirizei"></span>
    <a href="#o-cliente-vai-saber-que-terceirizei" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>No modelo white-label, não. A entrega sai sob a sua marca. O parceiro técnico não aparece para o seu cliente.</p>
<h3>E se a ferramenta der problema depois?<span class="hx:absolute hx:-mt-20" id="e-se-a-ferramenta-der-problema-depois"></span>
    <a href="#e-se-a-ferramenta-der-problema-depois" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Por isso o &ldquo;bem-feito&rdquo; não é luxo, é seguro. Uma ferramenta com boa estrutura é estável e fácil de ajustar. O barulho vem das gambiarras baratas que quebram na frente do cliente final: exatamente o que você quer evitar quando é a sua marca em jogo.</p>
<h3>Não seria mais seguro contratar um dev de uma vez?<span class="hx:absolute hx:-mt-20" id="não-seria-mais-seguro-contratar-um-dev-de-uma-vez"></span>
    <a href="#n%c3%a3o-seria-mais-seguro-contratar-um-dev-de-uma-vez" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Só se a demanda já for recorrente o bastante para pagar o salário com folga. Para uma demanda pontual ou ainda incerta, contratar é assumir o custo mais alto e o risco maior (avaliar e segurar alguém de uma área que não é a sua) antes de saber se vale.</p>
<h3>Quanto tempo leva?<span class="hx:absolute hx:-mt-20" id="quanto-tempo-leva"></span>
    <a href="#quanto-tempo-leva" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Ferramentas de escopo fechado costumam ser entregues em semanas, não meses, porque o escopo é definido na frente e o trabalho é feito por fases, com você aprovando cada etapa.</p>
<h2>Leia também<span class="hx:absolute hx:-mt-20" id="leia-também"></span>
    <a href="#leia-tamb%c3%a9m" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><ul>
<li><a href="/posts/2026/06/15/codebase-novo-prompt-mvp-que-escala/">Seu codebase é o novo prompt: o MVP que escala (ou vira lixo)</a></li>
<li><a href="/posts/2026/06/13/spec-driven-development-sair-do-vibe-coding/">Spec-driven development: como sair do vibe coding</a></li>
</ul>
]]></content:encoded></item><item><title>Seu MVP não vira lixo por ser rápido. Vira por cortar a coisa errada.</title><link>https://blog.nextside.tech/posts/2026/06/16/mvp-o-que-cortar-e-o-que-manter/</link><pubDate>Tue, 16 Jun 2026 10:00:00 -0300</pubDate><guid>https://blog.nextside.tech/posts/2026/06/16/mvp-o-que-cortar-e-o-que-manter/</guid><dc:creator>Bruno Raphael</dc:creator><category>mvp-que-escala</category><category>mvp</category><category>escopo-de-produto</category><category>time-to-market</category><category>retrabalho</category><description>O MVP que vira lixo não foi feito rápido demais. Juntou tudo pra ganhar tempo e manteve a feature que ninguém usa. O que cortar e o que manter.</description><content:encoded><![CDATA[<h2>TL;DR<span class="hx:absolute hx:-mt-20" id="tldr"></span>
    <a href="#tldr" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Todo founder técnico que senta comigo chega com o mesmo medo: &ldquo;lanço em semanas, mas não quero reescrever tudo daqui a três meses&rdquo;. O medo é legítimo. Só que ele faz você cortar a coisa errada.</p>
<p>O MVP que vira lixo quase nunca virou lixo por ter sido rápido. Virou porque cortou a separação (que é barata de manter e cara de refazer) pra manter feature (que é cara de fazer e que quase ninguém vai usar). O MVP que escala faz o inverso: corta feature sem dó e mantém a separação sempre. Ele não nasce protótipo descartável. Nasce como a fase 1 de um produto, e a fase 2 cresce em cima dela quando você cortou e manteve certo.</p>
<p>Os números ancoram a inversão. 42% das startups que morrem <a href="https://www.cbinsights.com/research/report/startup-failure-reasons-top/"target="_blank" rel="noopener">morrem construindo algo que o mercado não queria</a>. Num produto médio, <a href="https://www.pendo.io/resources/the-2019-feature-adoption-report/"target="_blank" rel="noopener">64% a 80% das features são raramente ou nunca usadas</a>. E refazer o que saiu errado é o gasto mais silencioso: times <a href="https://codeclimate.com/blog/rework-costs-millions"target="_blank" rel="noopener">retrabalham cerca de 26% do código antes mesmo de lançar</a>, e a maior parte disso vem de ter entendido errado o que construir, não de ter codado rápido.</p>
<p>Velocidade não é o inimigo do MVP que escala. Escopo cego é.</p>
<h2>O MVP não vira lixo por ser rápido. Vira por juntar tudo e manter a feature.<span class="hx:absolute hx:-mt-20" id="o-mvp-não-vira-lixo-por-ser-rápido-vira-por-juntar-tudo-e-manter-a-feature"></span>
    <a href="#o-mvp-n%c3%a3o-vira-lixo-por-ser-r%c3%a1pido-vira-por-juntar-tudo-e-manter-a-feature" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>A imagem de MVP que o founder carrega na cabeça é quase sempre a errada: uma versão pequena do produto inteiro. Um pouco de cada coisa. Todas as telas, todas as features, só que meia-boca.</p>
<blockquote>
  <p>&ldquo;MVP é pra validar rápido. Faz o mínimo de tudo, capricha depois.&rdquo;</p>

</blockquote>
<p>Esse &ldquo;mínimo de tudo&rdquo; é a armadilha. Mínimo não quer dizer raso em tudo. Quer dizer estreito: pouca coisa, inteira. Você escolhe a única coisa que o produto precisa fazer bem pra provar que tem gente querendo, e faz ela do começo ao fim. O resto não é &ldquo;feito pela metade&rdquo;. É cortado.</p>
<p>E aqui está o pulo do gato que o medo de retrabalho esconde: separar as coisas é barato, e juntá-las de novo é que custa. Feature é cara de fazer e barata de cortar. Quando você corta arquitetura pra ganhar tempo, economizou no que era barato e vai pagar caro depois. Quando você corta feature, economizou no que era caro e que provavelmente ninguém ia usar.</p>
<p><strong>MVP que vira lixo cortou no lugar errado.</strong></p>
<h2>O que cortar sem dó<span class="hx:absolute hx:-mt-20" id="o-que-cortar-sem-dó"></span>
    <a href="#o-que-cortar-sem-d%c3%b3" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Cortar bem é uma habilidade, e dói porque tudo parece essencial no começo. Não é. Comece por aqui:</p>
<ul>
<li><strong>Features que não validam a tese.</strong> Esse é o corte-mãe. Se a feature não serve pra provar que alguém quer o produto, ela não é v1. Os <a href="https://www.cbinsights.com/research/report/startup-failure-reasons-top/"target="_blank" rel="noopener">42% que morrem</a> construíram algo sem <dfn>product-market fit: a evidência de que existe gente o suficiente querendo o que você faz, no preço que você cobra</dfn>. Não morreram por falta de feature. Morreram de feature na direção errada.</li>
<li><strong>A segunda, a terceira e a quarta feature.</strong> Num produto médio, <a href="https://www.pendo.io/resources/the-2019-feature-adoption-report/"target="_blank" rel="noopener">só 12% das features geram 80% do uso</a>. No MVP você ainda não sabe qual é essa fatia. Mas sabe que não são as vinte. Aposta em uma, no máximo duas.</li>
<li><strong>Escala que não existe.</strong> Cache, fila, sharding, microservice pra dez usuários. Otimizar uma carga que você não tem é resolver um problema imaginário enquanto o problema real (alguém usar) segue sem resposta.</li>
<li><strong>Configurabilidade.</strong> Todo &ldquo;e se o cliente quiser mudar isso?&rdquo; vira um painel de settings que dobra o escopo. No MVP, deixa fixo no código. Configurável é problema de quem já tem cliente.</li>
<li><strong>Polish.</strong> Animação, dark mode, onboarding de cinco passos, tela vazia ilustrada. Tudo real, tudo fase 2.</li>
</ul>
<p>O que sobra parece pouco. É pra parecer. Se o seu MVP não te deixa um pouco constrangido, você cortou de MENOS.</p>
<h2>O que manter sempre (manter a separação é barato; refazê-la é que custa)<span class="hx:absolute hx:-mt-20" id="o-que-manter-sempre-manter-a-separação-é-barato-refazê-la-é-que-custa"></span>
    <a href="#o-que-manter-sempre-manter-a-separa%c3%a7%c3%a3o-%c3%a9-barato-refaz%c3%aa-la-%c3%a9-que-custa" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Cortar feature é a parte fácil depois que a ficha cai. Onde eu vejo o founder com pressa errar é no outro lado: o que NÃO se corta, nem no prazo mais apertado. São poucas coisas, todas baratas de deixar certas agora e caríssimas de refazer depois.</p>
<ul>
<li><strong>O modelo de domínio.</strong> Os nomes das coisas e como elas se ligam. Trocar &ldquo;usuário&rdquo; por &ldquo;conta&rdquo; e &ldquo;organização&rdquo; no mês seis é migração de dados, refactor que cruza o sistema inteiro e bug em produção. Decidir isso na semana 1 custa uma conversa.</li>
<li><strong>As divisões entre capacidades de negócio.</strong> Onde o pagamento termina e o pedido começa. Você não precisa implementar os dois bem. Precisa saber onde fica a linha entre eles, pra depois mexer num sem desmontar o outro.</li>
<li><strong>Identidade e quem-pode-o-quê.</strong> Se o produto tem mais de um tipo de usuário, enfiar auth e permissão depois é um dos refactors mais caros que existem, porque toca toda requisição.</li>
<li><strong>Um fio de observabilidade.</strong> Log estruturado e um jeito de saber o que quebrou. Não é feature. É o que te deixa dormir.</li>
</ul>
<p>O número que justifica a teimosia: times <a href="https://codeclimate.com/blog/rework-costs-millions"target="_blank" rel="noopener">retrabalham perto de 26% do código antes do release</a>, e a Carnegie Mellon aponta a mesma causa raiz há décadas. Mais da metade do retrabalho nasce de requisito mal entendido, não de código mal escrito. O retrabalho caro não vem de você ter codado rápido. Vem de ter traçado a separação no lugar errado, ou de não ter traçado nenhuma.</p>
<h3>Como manter a separação pro que eu nem sei se vai escalar?<span class="hx:absolute hx:-mt-20" id="como-manter-a-separação-pro-que-eu-nem-sei-se-vai-escalar"></span>
    <a href="#como-manter-a-separa%c3%a7%c3%a3o-pro-que-eu-nem-sei-se-vai-escalar" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Você não adivinha o que vai escalar, ninguém adivinha. Mas não precisa: em vez de decidir a implementação, você decide onde ficam as costuras. Manter a costura é barato (um módulo com nome claro, o pagamento que não está enfiado no meio do pedido) e atrás dela você faz o mais simples e burro que funciona hoje. Quando a carga aparecer, se aparecer, você troca o que está atrás sem mexer em quem depende dela. A fase 2 vira troca de peça, não recomeço.</p>
<p>A versão dessa disciplina no nível do código (organizar por feature, front e back no mesmo repositório, decisão registrada) a gente destrinchou em <a href="/posts/2026/06/15/codebase-novo-prompt-mvp-que-escala/">seu codebase é o novo prompt</a>, que é o que mantém um agente de IA produtivo no seu MVP seis meses depois. E o registro do porquê de cada decisão dessas mora nos <a href="/posts/2026/05/16/adrs-decisao-no-notion-sem-burocracia/">ADRs</a>. Este post é o andar de cima: o que cortar e o que manter antes de o código existir.</p>
<aside class="ns-cta ns-cta-mid" data-servico="sprint">
  <p class="eyebrow">● Nextside</p>

  <h3 class="ns-cta-title">Precisa de um MVP em semanas que não vire reescrita daqui a seis meses? Escopo fechado, time sênior, 4 semanas. É o que a gente faz num Sprint.</h3>

  <p class="ns-cta-meta">Escopo fechado · Preço fixo · 4 semanas · Time 100% sênior.</p>

  <div class="ns-cta-actions">
    <a href="https://www.nextside.tech/?utm_source=blog&amp;utm_medium=cta&amp;utm_campaign=sprint&amp;utm_content=mvp-o-que-cortar-e-o-que-manter-mid#sprint" class="btn btn-primary">Fale com a Nextside →</a></div>
</aside>

<h2>MVP é a fase 1, não o protótipo (a fase 2 é a prova)<span class="hx:absolute hx:-mt-20" id="mvp-é-a-fase-1-não-o-protótipo-a-fase-2-é-a-prova"></span>
    <a href="#mvp-%c3%a9-a-fase-1-n%c3%a3o-o-prot%c3%b3tipo-a-fase-2-%c3%a9-a-prova" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Tem uma palavra que denuncia que o MVP virou lixo: reescrita. Joel Spolsky chamou reescrever do zero de <a href="https://www.joelonsoftware.com/2000/04/06/things-you-should-never-do-part-i/"target="_blank" rel="noopener">&ldquo;o pior erro estratégico que uma empresa de software pode cometer&rdquo;</a>, e isso foi em 2000, muito antes de a IA deixar a reescrita ainda mais tentadora e mais cara. O MVP que escala nunca passa por ela. Passa por extensões: cada fase soma em cima da anterior, porque a anterior deixou a separação no lugar.</p>
<p>É o que a gente <a href="https://nextside.tech"target="_blank" rel="noopener">faz na Nextside</a> num Sprint: escopo fechado, time sênior, um MVP funcional em 4 semanas que já nasce com as divisões certas pra crescer por fases. A pressa fica no escopo, o rigor fica na separação. E o prazo curto não é limitação, é o mecanismo: ele força a conversa de corte que o founder adia por meses.</p>
<h2>O MVP que escala é o que você não precisa refazer<span class="hx:absolute hx:-mt-20" id="o-mvp-que-escala-é-o-que-você-não-precisa-refazer"></span>
    <a href="#o-mvp-que-escala-%c3%a9-o-que-voc%c3%aa-n%c3%a3o-precisa-refazer" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>A diferença entre o MVP que escala e o que vira lixo não está na stack, no tamanho do código nem no nome da arquitetura. Está em duas decisões que você toma antes de escrever a primeira linha: o que cortar e o que manter.</p>
<p>Corta a feature, a escala que não existe, o polish, o &ldquo;e se&rdquo;. Mantém o domínio, as divisões, a identidade. Faz pouca coisa inteira em vez de muita coisa pela metade, e a fase 2 vira uma extensão do que você já tem, não o velório do que jogou fora.</p>
<p>MVP que escala não é o que ficou pronto mais rápido. É o que você não vai precisar refazer.</p>
]]></content:encoded></item><item><title>Seu codebase é o novo prompt: o MVP que escala (ou vira lixo)</title><link>https://blog.nextside.tech/posts/2026/06/15/codebase-novo-prompt-mvp-que-escala/</link><pubDate>Mon, 15 Jun 2026 10:00:00 -0300</pubDate><guid>https://blog.nextside.tech/posts/2026/06/15/codebase-novo-prompt-mvp-que-escala/</guid><dc:creator>Pablo Winter</dc:creator><category>mvp-que-escala</category><category>arquitetura</category><category>coding-agents</category><category>monorepo</category><category>feature-first</category><category>divida-tecnica</category><description>Num MVP feito com IA, o que decide se ele escala ou vira lixo não é a stack. É se o coding agent ainda navega seu repositório seis meses depois.</description><content:encoded><![CDATA[<h2>TL;DR<span class="hx:absolute hx:-mt-20" id="tldr"></span>
    <a href="#tldr" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Seu codebase é o novo prompt. Num MVP feito com agente de IA, o que decide se ele escala por fases ou vira lixo descartável não é a stack que você escolheu. É se o agente ainda consegue se localizar no seu repositório daqui a seis meses. E isso você resolve na organização: código por feature, front e back no mesmo monorepo, decisões registradas em ADR. Não na esperteza do prompt.</p>
<p>O número que ancora isso: num estudo de trajetórias de coding agent em bugs reais, as tentativas que resolveram o problema mexeram no mesmo arquivo do patch correto em 93,6% das vezes. As que falharam, 62,7%. Localizar o código certo é metade do jogo, e localizável é uma propriedade da sua arquitetura, não do modelo.</p>
<p>Arquitetura parou de ser o imposto que você paga pra ir devagar. Virou o que mantém a IA rápida.</p>
<h2>O lixo não é o que foi feito rápido. É o que foi feito cego.<span class="hx:absolute hx:-mt-20" id="o-lixo-não-é-o-que-foi-feito-rápido-é-o-que-foi-feito-cego"></span>
    <a href="#o-lixo-n%c3%a3o-%c3%a9-o-que-foi-feito-r%c3%a1pido-%c3%a9-o-que-foi-feito-cego" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Todo founder técnico que me procura chega com o mesmo medo, e ele é legítimo: &ldquo;preciso lançar em semanas, mas não quero reescrever tudo daqui a três meses&rdquo;. Daí vem a crença que eu quero matar aqui:</p>
<blockquote>
  <p>&ldquo;Arquitetura é luxo de quem tem tempo. Lança logo, arruma depois.&rdquo;</p>

</blockquote>
<p>Eu ouço isso toda semana. E concordava em certo nível, até a IA mudar a conta. Porque &ldquo;arruma depois&rdquo; pressupõe uma escolha que não existe mais: ou você lança rápido, ou entrega bem-arquitetado. Aceitar essa escolha é aceitar que o MVP nasce protótipo descartável, e que a versão &ldquo;de verdade&rdquo; vem depois, do zero.</p>
<p>Calma lá. Essa dicotomia morreu, e quem matou foi a própria IA.</p>
<p>Antes, arquitetura boa custava tempo. Você desenhava boundaries, separava responsabilidade, escrevia doc. Cada hora disso era uma hora que não virava feature na tela. Num MVP com prazo de semanas, cortar arquitetura parecia o trade-off racional. Era. Não é mais.</p>
<p>O que mudou: o código que você gera hoje, na maior parte, não sai mais da sua cabeça direto pro editor. Sai de um <dfn>coding agent: um agente de IA que lê, edita e roda seu repositório por conta própria</dfn>, operando dentro de um harness, a plataforma que pluga o modelo nas ferramentas de código. Claude Code e Cursor são dois harnesses. E esse agente tem uma característica que muda o cálculo inteiro: ele é tão rápido quanto seu repositório deixa ele ser.</p>
<p>O vibe coding (o tal &ldquo;pede, aceita, deploya&rdquo; sem entender o que saiu) é ótimo pra protótipo de fim de semana. O problema é a conta, que não é linear. Um <a href="https://arxiv.org/abs/2512.11922"target="_blank" rel="noopener">paper de 2025</a> formalizou isso como <em>flow-debt trade-off</em>: a fluidez de gerar código mascara a dívida que se acumula em paralelo. Inconsistência arquitetural, dependência que ninguém avaliou, o mesmo problema resolvido de cinco jeitos diferentes. Lá pelo sexto mês, o custo de desfazer a dívida passa o valor do que foi construído.</p>
<p>Vira uma bola de ferro. E o detalhe cruel: a bola de ferro não trava só o seu time. Trava o próprio agente que a criou. Os sinais de que ele depende pra se achar (nome consistente, padrão previsível, baixo acoplamento) foram destruídos pela própria geração descuidada.</p>
<p><strong>MVP que vira lixo não é o que foi feito rápido. É o que foi feito CEGO</strong>, sem deixar pista nem pra IA nem pro humano que vai mexer nele depois.</p>
<h2>A IA lê seu repositório, não seu prompt<span class="hx:absolute hx:-mt-20" id="a-ia-lê-seu-repositório-não-seu-prompt"></span>
    <a href="#a-ia-l%c3%aa-seu-reposit%c3%b3rio-n%c3%a3o-seu-prompt" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Tem uma frase do Matt Pocock que resume a virada: &ldquo;seu codebase, não seu prompt, decide a qualidade do output da IA&rdquo;. Soa exagero. Não é.</p>
<p>Veja como o Claude Code acha código num repositório grande. Ele não usa busca semântica, não tem um índice mágico de embeddings. Ele faz o que um dev sênior faria: navega o filesystem, lê arquivo, e roda grep, a velha busca literal por texto do terminal, pra achar exatamente o que precisa. A Anthropic escolheu grep de propósito: embedding fica stale, o repo muda toda hora, e índice velho mente.</p>
<p>A consequência é física, não filosófica: grep acha string, não intenção. <em>&ldquo;grep finds strings, not intent.&rdquo;</em> Se a função que importa se chama <code>validateToken</code>, o agente acha de primeira. Se a lógica está espalhada em cinco arquivos frouxamente ligados por import, com nome genérico tipo <code>handler</code> ou <code>process</code>, ele vasculha, carrega arquivo demais, e <a href="/posts/2026/06/12/spec-driven-development-gargalo-execucao/">queima contexto</a> antes de começar o trabalho.</p>
<p>E aqui mora o número que abre esse post. Pesquisadores olharam trajetórias de coding agent em bugs reais do SWE-bench. As tentativas que consertaram o bug mexeram no mesmo arquivo do patch correto em 93,6% dos casos. As que falharam, 62,7%. Traduzindo: o gargalo do agente quase nunca é &ldquo;saber programar&rdquo;. É achar o trecho certo. Localizar bem é o que separa o PR que mergeia do que apodrece.</p>
<p>Organização por camada técnica sabota exatamente isso. Quando tudo é <code>controllers/</code>, <code>services/</code>, <code>models/</code>, pra mexer no checkout o agente abre cinco pastas e carrega arquivo de outras doze features que moram nas mesmas pastas. A janela de contexto vira, na frase de um artigo que li sobre isso, &ldquo;a junkyard of irrelevant stuff&rdquo;, um ferro-velho de coisa que não importa.</p>
<p>E não é só a IA que sofre. Camada técnica é a velha violação do SRP, o primeiro princípio do SOLID, que o Uncle Bob redefiniu como &ldquo;junte o que muda pela mesma razão, separe o que muda por razões diferentes&rdquo;. A organização por camada faz o oposto: estilhaça a feature (que muda junta) por quatro pastas, e amontoa em cada pasta código que só tem em comum o fato de ser &ldquo;um controller&rdquo;. A correção tem nome, e é o assunto da próxima seção.</p>
<h3>A IA não devia ser esperta o bastante pra achar sozinha?<span class="hx:absolute hx:-mt-20" id="a-ia-não-devia-ser-esperta-o-bastante-pra-achar-sozinha"></span>
    <a href="#a-ia-n%c3%a3o-devia-ser-esperta-o-bastante-pra-achar-sozinha" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>É a pergunta que todo CTO faz, e a resposta honesta é: ela é, até certo ponto, e isso piora a sua complacência. O agente acha, sim. Lê 25 arquivos pra responder sobre 3 funções, porque sem estrutura ele não sabia quais 3 eram. Funciona, e te cobra em tokens, em tempo, e em alucinação quando o contexto enche de ruído.</p>
<p>E aqui eu preciso ser honesto, porque a versão simplista dessa ideia (&ldquo;codebase ruim trava a IA&rdquo;) é exagerada. Não é que humano e agente travem igual. Eles têm forças opostas. A IA aguenta vasculhar um repo caótico na força bruta: regra de negócio espalhada em vinte arquivos, ela queima um milhão de tokens de contexto e acha mesmo assim. Um humano, no mesmo repo, levaria dias, ou desistiria. Nesse caso a IA é melhor que você.</p>
<p>Só que o humano tem uma arma que a IA não tem nativamente: o IDE. Você lança um evento com <code>ApplicationEventPublisher</code> no Spring, e o IntelliJ te mostra cada <code>@EventListener</code> que escuta aquele evento, em ordem, num clique. É um índice semântico do código inteiro, de graça. A IA não tem isso: ela cai em vários greps e em carregar arquivo atrás de arquivo no contexto, e é aí que bate o context rot, a degradação de qualidade do modelo conforme a janela enche.</p>
<p>Então a frase certa não é &ldquo;a IA expõe arquitetura ruim&rdquo;. É: arquitetura ruim cobra um pedágio diferente de cada um. Do humano, em tempo e em dependência de IDE. Da IA, em tokens e em context rot. Repo organizado baixa o pedágio pros dois ao mesmo tempo. É por isso que o codebase é o novo prompt: ele é, literalmente, o contexto que o agente lê antes de cada tarefa, e quanto mais limpo, menos ele paga pra te entender.</p>
<h2>Organize por feature, não por camada (e esqueça o nome da arquitetura)<span class="hx:absolute hx:-mt-20" id="organize-por-feature-não-por-camada-e-esqueça-o-nome-da-arquitetura"></span>
    <a href="#organize-por-feature-n%c3%a3o-por-camada-e-esque%c3%a7a-o-nome-da-arquitetura" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>A correção é mais chata do que parece, e é de graça: organize o código por feature, não por camada técnica.</p>
<p>Em vez de <code>controllers/</code>, <code>services/</code>, <code>repositories/</code> (onde cada feature está estilhaçada em quatro pastas), você faz uma pasta por capacidade de negócio: <code>orders/</code>, <code>payments/</code>, <code>refunds/</code>, cada uma com o seu controller, serviço e acesso a dados dentro. O nome disso, na literatura, é <dfn>vertical slice: uma fatia que vai da borda (a request) até o fundo (o banco), inteira, no mesmo lugar</dfn>. Jimmy Bogard cravou a regra de ouro: &ldquo;minimize coupling between slices, and maximize coupling in a slice&rdquo;. Acoplamento mínimo entre fatias, máximo dentro de uma.</p>
<p>Pra IA, isso é roteamento de atenção. O agente lê o nome da pasta antes de abrir qualquer arquivo, e infere o escopo da tarefa na hora. &ldquo;Mexe no refund&rdquo; já o leva pra <code>refunds/</code>, e tudo que importa está colocado ali junto. Uncle Bob chamou isso de Screaming Architecture há mais de dez anos: a estrutura de pastas deve gritar o que o sistema faz, não qual framework ele usa. Em 2011 era estética. Hoje é performance de quem vai codar. E quem vai codar é um agente.</p>
<p>Aqui cabe uma honestidade que desarma. No briefing desse post, alguém da equipe escreveu &ldquo;usem a arquitetura NGC ou a que for&rdquo;. Fui pesquisar o que é &ldquo;arquitetura NGC&rdquo;. Não existe. Não é um padrão consolidado; é provável typo de N-tier, ou só uma sigla que escapou. E sabe o que isso prova? Que o nome importa menos do que você acha. Clean, hexagonal, onion, N-tier: no fundo são a mesma ideia (regra de negócio no centro, framework e banco na borda) com vocabulário diferente. O que decide se o agente, e o seu time, vai conseguir evoluir o código não é o crachá da arquitetura. É a disciplina de fronteira.</p>
<p>Dito isso, não caia no extremo oposto. Clean Architecture com quatro camadas de abstração num MVP é over-engineering; alguém comparou a jogar Dark Souls: regra demais, cerimônia demais, pra um produto que talvez ninguém queira ainda. O ponto não é a arquitetura mais pura. É a mais navegável.</p>
<p>E tem trade-off, claro. Organizar por feature gera duplicação: duas fatias validam parecido, três features batem na mesma tabela. O instinto é abstrair tudo num <code>shared/</code>, e aí o <code>shared/</code> vira a lixeira que acopla todo mundo de novo. Sandi Metz tem a melhor regra pra isso: &ldquo;duplication is far cheaper than the wrong abstraction&rdquo;. Duplicação é mais barata que a abstração errada. Num MVP, topar um pouco de cópia pra manter as fatias independentes quase sempre vale mais do que o DRY religioso. Shared só pra infra de verdade: cliente de banco, log, auth. Nunca pra regra de negócio.</p>
<aside class="ns-cta ns-cta-mid" data-servico="discovery">
  <p class="eyebrow">● Nextside</p>

  <h3 class="ns-cta-title">Vai tirar um MVP do papel com IA e quer que ele escale por fases, não vire reescrita? A gente alinha arquitetura e stack num Discovery, antes de você queimar budget.</h3>

  <p class="ns-cta-meta">Validação técnica · 2-3 semanas · Entrega: roadmap &#43; protótipo.</p>

  <div class="ns-cta-actions">
    <a href="https://www.nextside.tech/?utm_source=blog&amp;utm_medium=cta&amp;utm_campaign=discovery&amp;utm_content=codebase-novo-prompt-mvp-que-escala-mid#discovery" class="btn btn-primary">Fale com a Nextside →</a></div>
</aside>

<h2>Monorepo e ADR: pare de fazer a IA (e seu time) adivinhar<span class="hx:absolute hx:-mt-20" id="monorepo-e-adr-pare-de-fazer-a-ia-e-seu-time-adivinhar"></span>
    <a href="#monorepo-e-adr-pare-de-fazer-a-ia-e-seu-time-adivinhar" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Organizar dentro do projeto resolve metade. A outra metade é o que está entre os projetos, e é onde o monorepo entra.</p>
<p>A ideia: front e back no mesmo repositório. Junto com a pasta de documentação, os ADRs, as convenções. Um histórico só. Tem uma frase do Francis Dortort que fecha o argumento: &ldquo;a repository boundary is a context wall. Every wall degrades the quality of AI-generated output&rdquo;. Toda fronteira de repositório é uma parede de contexto, e toda parede degrada o que a IA produz.</p>
<p>Pensa no caso concreto. Você pede &ldquo;adiciona um campo no cadastro&rdquo;. Num setup de dois repos separados, o agente precisa de duas conversas sem memória uma da outra, e o contrato entre front e back deriva no meio do caminho. Num monorepo, é uma transação só: ele renomeia o campo no banco, atualiza a API, ajusta a UI e o teste, num único contexto, num único commit. DB, API e UI sem trocar de janela. É exatamente o tipo de mudança cross-cutting que um MVP faz o tempo todo.</p>
<p>Ferramenta? Comece simples: pnpm workspaces com Turborepo resolve a maioria dos MVPs com baixíssima fricção. Nx quando a dor de escala aparecer, não antes. E o trade-off honesto: monorepo sem tooling de build seletivo te dá CI lento. Se cada commit rebuilda tudo, a conta explode. É um problema solucionável, mas é um problema que você assume de propósito.</p>
<p>O ADR é a outra peça, e a mais subestimada. ADR eu já <a href="/posts/2026/05/16/adrs-decisao-no-notion-sem-burocracia/">expliquei em outro post</a>: registro curto e datado de uma decisão técnica e do porquê dela. O que mudou com a IA é o uso. Sem os ADRs no contexto, o agente fica, na frase de um artigo, &ldquo;deprived of architectural intent&rdquo;: ele vê a implementação, mas não o raciocínio. Ele sabe que você usa Postgres. Não sabe por que você descartou Mongo, então pode &ldquo;melhorar&rdquo; seu código reintroduzindo exatamente o que você rejeitou. O ADR, junto com um <code>CLAUDE.md</code> ou <code>AGENTS.md</code> no repo, é como você entrega a intenção de mão beijada, em vez de rezar pra ele adivinhar.</p>
<p>Agora o contrapeso, porque eu não vendo milagre. Nada disso é mágica, e mais documento não é sempre melhor. Um estudo da ETH Zurich testou arquivos de contexto e achou que <code>AGENTS.md</code> gerado automaticamente PIOROU a taxa de acerto em vários cenários e subiu o custo de inferência em mais de 20%. A própria METR mediu devs sêniores experientes ficando 19% mais lentos com IA num estudo controlado, achando, eles mesmos, que estavam mais rápidos.</p>
<p>O que isso te diz: o ganho não vem de encher o repo de markdown. Vem do não-óbvio bem registrado: a decisão contraintuitiva, o gotcha que não dá pra inferir do código. ADR e convenção são bisturi, não enchente. Bom contexto, nas palavras da própria Anthropic, é &ldquo;the smallest possible set of high-signal tokens&rdquo;, o menor conjunto de tokens de alto sinal, não o maior monte de tokens.</p>
<h2>O MVP que escala é o que a IA ainda entende amanhã<span class="hx:absolute hx:-mt-20" id="o-mvp-que-escala-é-o-que-a-ia-ainda-entende-amanhã"></span>
    <a href="#o-mvp-que-escala-%c3%a9-o-que-a-ia-ainda-entende-amanh%c3%a3" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Junta tudo e o retrato é simples. O MVP que escala não tem stack mais cara nem arquitetura mais sofisticada que o MVP que vira lixo. Tem fronteira. Código por feature, front e back no mesmo lugar, decisão registrada. Três disciplinas baratas que, somadas, mantêm um agente de IA produtivo na fase 2, na fase 3, na fase 4, em vez de travado no mês seis.</p>
<p>Isso não quer dizer construir tudo. Quer dizer cortar a coisa certa, e <a href="/posts/2026/06/16/mvp-o-que-cortar-e-o-que-manter/">o que cortar e o que manter num MVP</a> virou um post só. Martin Fowler tem um quadrante de dívida técnica que todo founder devia conhecer: dívida pode ser deliberada e prudente (&ldquo;a gente precisa lançar agora e lida com a consequência depois&rdquo;) ou imprudente e cega (&ldquo;não temos tempo pra design&rdquo;). A primeira é uma decisão de negócio legítima. A segunda é o protótipo que vai explodir. O lixo não é ter dívida. É não saber que você tem.</p>
<p>E o que cortar primeiro? Escala prematura. O Startup Genome olhou mais de três mil startups e achou que 74% das que morreram, morreram por escalar antes da hora: otimização, microservices, infra distribuída pra uma carga que não existia. Microservices num MVP é o exemplo perfeito de dívida imprudente disfarçada de boa engenharia. Comece monólito, modular, com fronteira limpa. A fronteira é o que torna a fase seguinte uma extração, não uma demolição.</p>
<p>Foi o mesmo padrão sobre o qual escrevi quando <a href="/posts/2026/05/25/code-review-novo-gargalo-coderabbit/">code review virou o gargalo</a>: a IA acelerou o indivíduo, e a parte que não acompanhou virou o freio. Com arquitetura é igual, só que antes: o repositório desorganizado é o gargalo que você planta no dia um e só sente no dia cento e oitenta.</p>
<p>Seu MVP não precisa ser perfeito pra escalar. Precisa ser legível. O código que a IA ainda entende daqui a seis meses é o código que não vira lixo. O resto é reescrita esperando a data.</p>
]]></content:encoded></item><item><title>Spec-driven development: sair do vibe coding travado</title><link>https://blog.nextside.tech/posts/2026/06/13/spec-driven-development-sair-do-vibe-coding/</link><pubDate>Sat, 13 Jun 2026 08:00:00 -0300</pubDate><guid>https://blog.nextside.tech/posts/2026/06/13/spec-driven-development-sair-do-vibe-coding/</guid><dc:creator>Lucas Israel</dc:creator><category>spec-driven-development</category><category>vibe-coding</category><category>ai-tooling</category><category>agentes-de-ia</category><category>arquitetura</category><description>Por que o vibe coding empaca na hora de escalar, e como o spec-driven development entrega uma ordem de grandeza menos retrabalho com agentes de IA.</description><content:encoded><![CDATA[<h2>TL;DR<span class="hx:absolute hx:-mt-20" id="tldr"></span>
    <a href="#tldr" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Você prototipou rápido com IA. Agora o app não escala, e cada feature nova quebra duas antigas. Esse é o ponto exato onde o vibe coding para de ajudar, e onde o <dfn>spec-driven development (SDD)</dfn> começa a pagar. A ideia é simples e inverte a ordem do jogo: a <strong>especificação vira o artefato principal</strong>, e o agente implementa a partir dela em vez de adivinhar. O trade-off é real: você troca a euforia do &ldquo;deu certo de primeira&rdquo; por 30 minutos escrevendo spec antes de codar. Pra protótipo descartável, não compensa. Pra o que vai pra produção e precisa crescer, é o que separa entrega de gambiarra.</p>
<p>Vibe coding é ótimo pra descobrir o quê construir. É péssimo pra sustentar o que já existe.</p>
<h2>O vibe coding não falha por ser IA. Falha por ser ambíguo.<span class="hx:absolute hx:-mt-20" id="o-vibe-coding-não-falha-por-ser-ia-falha-por-ser-ambíguo"></span>
    <a href="#o-vibe-coding-n%c3%a3o-falha-por-ser-ia-falha-por-ser-amb%c3%adguo" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Num prompt solto, o modelo tem 30 formas de implementar a mesma feature, e roda a mesma instrução duas vezes, sai diferente. Essa ambiguidade é tolerável no protótipo e fatal na manutenção: ninguém (nem você, nem o próximo dev, nem o agente) sabe qual era a regra. O código é a única fonte de verdade, e ela muda a cada geração.</p>
<p>Se você é CTO e ainda está no vibe coding, o sintoma é familiar: o MVP saiu numa semana, o time dobrou a velocidade no começo, e agora cada PR de IA precisa de três rodadas de review porque o agente &ldquo;esqueceu&rdquo; uma decisão que nunca foi escrita em lugar nenhum. Vi isso de perto mais de uma vez: o pessoal acha que é questão de contratar mais um sênior. Não é.</p>
<p><strong>O gargalo deixou de ser escrever código. Virou alinhar contexto.</strong></p>
<h2>O que muda no spec-driven development<span class="hx:absolute hx:-mt-20" id="o-que-muda-no-spec-driven-development"></span>
    <a href="#o-que-muda-no-spec-driven-development" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>SDD coloca a especificação <strong>antes</strong> da geração de código: requisitos, regras de negócio, contratos de API e restrições de arquitetura viram um documento que o agente lê e segue. A spec é versionada, revisada e reusada: o código passa a ser saída, não a fonte de verdade. Menos adivinhação, menos loop de &ldquo;não era isso&rdquo;.</p>
<p>Na prática o fluxo é direto: você descreve o comportamento e as restrições → o agente propõe um plano contra a spec → você valida o plano (não 400 linhas de diff) → o agente implementa e testa contra os critérios que a própria spec definiu. O review deixa de ser &ldquo;isso está certo?&rdquo; e vira &ldquo;isso bate com a spec?&rdquo;. Uma pergunta que dá pra responder em minutos.</p>
<p>Não é teoria de blog. Em projetos internos com o <a href="https://www.turingpost.com/p/sdd"target="_blank" rel="noopener">Spec Kit, o GitHub relata cerca de uma ordem de grandeza menos ciclos de &ldquo;regerar do zero&rdquo;</a> que prompting ad-hoc. A AWS documenta com o Kiro <a href="https://towardsdatascience.com/from-vibe-coding-to-spec-driven-development/"target="_blank" rel="noopener">casos de features de 40 horas entregues em menos de 8 horas de tempo humano</a> quando o trabalho começou pela spec. E o próprio criador do termo &ldquo;vibe coding&rdquo;, Andrej Karpathy, já reconheceu publicamente o limite da abordagem pra software de verdade.</p>
<h3>SDD funciona com agentes de IA como Claude e Copilot?<span class="hx:absolute hx:-mt-20" id="sdd-funciona-com-agentes-de-ia-como-claude-e-copilot"></span>
    <a href="#sdd-funciona-com-agentes-de-ia-como-claude-e-copilot" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Sim, e é exatamente pra isso que foi feito. Ferramentas como GitHub Spec Kit e AWS Kiro integram com agentes como Claude Code, Copilot e Gemini CLI. A spec vira o contexto que o agente segue: o mesmo papel que um <code>CLAUDE.md</code> bem escrito cumpre no dia a dia, só que elevado a artefato de primeira classe do projeto.</p>
<aside class="ns-cta ns-cta-mid" data-servico="discovery">
  <p class="eyebrow">● Nextside</p>

  <h3 class="ns-cta-title">Tem uma ideia travada ou um MVP vibe-coded que precisa virar produto? Um Discovery transforma isso em spec executável: roadmap &#43; protótipo em 2-3 semanas.</h3>

  <p class="ns-cta-meta">Validação técnica · 2-3 semanas · Entrega: roadmap &#43; protótipo.</p>

  <div class="ns-cta-actions">
    <a href="https://www.nextside.tech/?utm_source=blog&amp;utm_medium=cta&amp;utm_campaign=discovery&amp;utm_content=spec-driven-development-sair-do-vibe-coding-mid#discovery" class="btn btn-primary">Fale com a Nextside →</a></div>
</aside>

<h2>Onde isso quebra<span class="hx:absolute hx:-mt-20" id="onde-isso-quebra"></span>
    <a href="#onde-isso-quebra" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>SDD não é bala de prata, e fingir que é seria cair no mesmo erro do hype do vibe coding.</p>
<blockquote>
  <p>&ldquo;Isso é só mais cerimônia. Mais um documento bonito que ninguém vai ler.&rdquo;</p>

</blockquote>
<p>Pode ser. Esse é o risco real, e eu já vi virar isso. Escrever spec custa tempo de cabeça: pra um spike de um dia, um teste de hipótese ou um throwaway, o overhead não se paga, vibe coding ganha. SDD também é tão bom quanto a spec: spec vaga gera código vago, e você só transferiu a ambiguidade pra um documento mais bonito.</p>
<p>A régua que uso é simples: <strong>se o código vai sobreviver mais de um mês ou passar pela mão de outra pessoa, especifique. Se é pra jogar fora, não.</strong> A decisão é por estágio, não por dogma.</p>
<h3>Spec-driven development substitui o vibe coding?<span class="hx:absolute hx:-mt-20" id="spec-driven-development-substitui-o-vibe-coding"></span>
    <a href="#spec-driven-development-substitui-o-vibe-coding" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Não pra tudo. Vibe coding continua ótimo pra protótipos, spikes e validação de hipótese, onde a velocidade de descobrir vale mais que a disciplina de sustentar. SDD ganha quando o código vai pra produção, precisa escalar ou passar pela mão de outras pessoas. Não é um substituindo o outro. É saber em que estágio você está.</p>
<h2>Como sair do vibe coding sem parar o time<span class="hx:absolute hx:-mt-20" id="como-sair-do-vibe-coding-sem-parar-o-time"></span>
    <a href="#como-sair-do-vibe-coding-sem-parar-o-time" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Não precisa reescrever tudo. A migração é incremental e começa na próxima feature, não num big bang:</p>
<ul>
<li><strong>Escreva a spec antes de chamar o agente</strong>, mesmo que curta. Comportamento esperado, regras e restrições. Cinco linhas já mudam o jogo.</li>
<li><strong>Toda regra de negócio mora na spec</strong>: não num comentário, não no Slack, não na cabeça de alguém. Se não está na spec, não existe pro agente.</li>
<li><strong>Use a spec como critério de review</strong>: a pergunta deixa de ser &ldquo;isso está bom?&rdquo; e vira &ldquo;isso bate com o que a gente especificou?&rdquo;.</li>
</ul>
<p>Em poucas semanas o retrabalho cai, porque o contexto parou de evaporar entre uma geração e outra.</p>
<h3>SDD deixa o desenvolvimento mais lento?<span class="hx:absolute hx:-mt-20" id="sdd-deixa-o-desenvolvimento-mais-lento"></span>
    <a href="#sdd-deixa-o-desenvolvimento-mais-lento" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>No começo de cada feature, sim, você investe os tais 30 minutos escrevendo a spec. No total, costuma ser mais rápido: é a diferença entre a ordem de grandeza menos ciclos de regerar do zero que o GitHub relata e as features de 40h entregues em menos de 8h que a AWS reporta. Você paga adiantado pra não pagar o juro composto do retrabalho depois.</p>
<h2>A spec é o contexto que não evapora<span class="hx:absolute hx:-mt-20" id="a-spec-é-o-contexto-que-não-evapora"></span>
    <a href="#a-spec-%c3%a9-o-contexto-que-n%c3%a3o-evapora" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Vibe coding te dá o primeiro quilômetro de graça e cobra o resto da estrada em retrabalho. SDD faz o oposto: cobra adiantado e devolve previsibilidade.</p>
<p>O ponto não é abandonar a IA: é parar de tratar o código gerado como fonte de verdade. A fonte de verdade é a spec. O código é só a saída.</p>
<p>Se a sua equipe vai gastar IA de qualquer jeito, gaste no que está especificado.</p>
]]></content:encoded></item><item><title>A spec era a parte fácil. O gargalo do SDD é a execução</title><link>https://blog.nextside.tech/posts/2026/06/12/spec-driven-development-gargalo-execucao/</link><pubDate>Fri, 12 Jun 2026 09:00:00 -0300</pubDate><guid>https://blog.nextside.tech/posts/2026/06/12/spec-driven-development-gargalo-execucao/</guid><dc:creator>Pablo Winter</dc:creator><category>spec-driven-development</category><category>dynamic-workflows</category><category>claude-code</category><category>context-rot</category><category>orquestracao</category><category>ia-development</category><description>Spec-Driven Development externaliza a intenção em markdown, mas empurra a dor pra execução. Por que orquestrar com o estado fora da janela do modelo é a saída.</description><content:encoded><![CDATA[<h2>TL;DR<span class="hx:absolute hx:-mt-20" id="tldr"></span>
    <a href="#tldr" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Spec-Driven Development resolveu um problema real: você externaliza a intenção em markdown versionado (PRD, tech spec, lista de tasks) e a spec vira a fonte da verdade. Só que ninguém te conta a conta da execução. Uma spec gera dezenas de tasks, e rodar tudo numa conversa só é onde o contexto degrada e você vira gerente de janela. A saída que a indústria inteira convergiu, de framework caro a <code>while</code> loop de bash, é a mesma: tirar o estado da janela do modelo e botar em arquivo ou código, com um revisor que nunca é quem escreveu. Os <dfn>Dynamic Workflows</dfn> da Anthropic, onde o próprio Claude escreve o script que orquestra os agentes, são uma forma disso. Tem várias.</p>
<p>Esse post é sobre por que a execução era o gargalo o tempo todo, e por que todo mundo está chegando nas mesmas duas regras.</p>
<h2>Ninguém te conta a conta da execução<span class="hx:absolute hx:-mt-20" id="ninguém-te-conta-a-conta-da-execução"></span>
    <a href="#ningu%c3%a9m-te-conta-a-conta-da-execu%c3%a7%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Spec-Driven Development é simples de descrever: você escreve a intenção antes do código. PRD vira tech spec, tech spec vira lista de tasks atômicas, e só então o agente gera código. GitHub Spec Kit, Amazon Kiro, Tessl, cada um com seu sabor. A spec é a fonte da verdade, o código é consequência.</p>
<p>Escrever a spec é a parte fácil.</p>
<p>Minha última spec gerou trinta e poucas tasks. O inferno não começou ali. Começou na hora de executar as trinta e poucas numa conversa só. Você roda task atrás de task, a janela enche, e lá pela vigésima o agente já esqueceu a decisão que ele mesmo tomou na quarta.</p>
<p>Isso tem nome e foi medido. <dfn>Context rot</dfn>, a queda de qualidade do modelo conforme o contexto cresce, foi testado pela Chroma em 18 modelos. Os 18 degradaram, e a degradação começa bem antes da janela encher. O paper &ldquo;Lost in the Middle&rdquo; já tinha mostrado a mesma curva: o modelo perde a informação enterrada no meio de um contexto longo.</p>
<p>O remendo que a comunidade adotou é abrir uma janela limpa por task: contexto novo, recola a spec, aponta a task, executa, repete. Funciona contra o rot. E te transforma em estagiário de copy-paste, trinta e poucas vezes.</p>
<p><strong>A spec era a parte fácil.</strong></p>
<h2>As três fases de quem carrega o contexto<span class="hx:absolute hx:-mt-20" id="as-três-fases-de-quem-carrega-o-contexto"></span>
    <a href="#as-tr%c3%aas-fases-de-quem-carrega-o-contexto" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O gargalo sempre foi o mesmo: alguém precisa segurar o estado e consolidar os resultados enquanto as tasks rodam. O que mudou foi quem carrega esse peso.</p>
<p><strong>Fase 1, na mão.</strong> Você é a janela de contexto. Roda task por task, dá <code>/clear</code>, relê a spec, segura o estado na cabeça e na conversa. Vai bem pra cinco tasks. Na trigésima, você já é o gargalo.</p>
<p><strong>Fase 2, delegando.</strong> Você joga a execução pros subagentes. Ajuda. Só que o output de todos volta pra mesma janela, a do agente principal que você está dirigindo, e é essa janela que vira o consolidador e apodrece. Agent Teams melhoraram com uma task list compartilhada, mas o lead ainda dirige passo a passo. O gargalo mudou de lugar, não sumiu.</p>
<p><strong>Fase 3, workflow.</strong> Aqui muda a física. O plano sai do seu contexto e vira código. Um script segura o loop e os resultados intermediários, e o contexto do modelo só vê a resposta final. Cada task roda numa janela isolada. Foi aqui que eu finalmente parei de ser o gargalo. É o que os Dynamic Workflows do Claude Code fazem: o próprio Claude escreve um script JavaScript de orquestração, e um runtime executa em segundo plano, com até 16 agentes simultâneos e teto de mil por run.</p>
<p>Jarred Sumner, criador do Bun, levou isso ao extremo. Portou o Bun de Zig pra Rust exatamente nesse esquema: tasks em paralelo, dois revisores contestando cada arquivo. Setecentas e cinquenta mil linhas de Rust, 99,8% da suíte de testes passando, onze dias do primeiro commit ao merge. Ainda não foi pra produção, é demonstração de capacidade. Mas o número é esse.</p>
<h3>Por que o revisor não pode ser quem escreveu?<span class="hx:absolute hx:-mt-20" id="por-que-o-revisor-não-pode-ser-quem-escreveu"></span>
    <a href="#por-que-o-revisor-n%c3%a3o-pode-ser-quem-escreveu" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Porque o modelo tem viés de auto-preferência. Self-preferential bias é a tendência do modelo de defender o próprio output quando ele mesmo é o juiz. Um corretor que escreveu a prova é um corretor suspeito.</p>
<p>O jeito de matar isso é estrutural. O revisor roda como um agente separado, com contexto próprio, às vezes num modelo diferente, com a única missão de tentar <a href="/posts/2026/05/25/code-review-novo-gargalo-coderabbit/">derrubar o resultado antes dele ser aceito</a>. No workflow você bota um verificador adversarial por output. No fim, os próprios agentes abrem os PRs. Quem produz NUNCA é quem aprova.</p>
<h2>Custa caro, e o ROI é de nicho<span class="hx:absolute hx:-mt-20" id="custa-caro-e-o-roi-é-de-nicho"></span>
    <a href="#custa-caro-e-o-roi-%c3%a9-de-nicho" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Vou ser honesto, porque a parte que ninguém posta é o custo. Dynamic Workflows é research preview e queima token sem dó. Tem relato de gente torrando o limite de cinco horas em dezoito minutos, e de runs de três milhões de tokens sem um aviso de custo no meio. Não é escala de graça.</p>
<p>Então pra quem isso paga?</p>
<p>Pra quem tem senioridade pra revisar. A alavanca do sênior é julgamento: saber quando a IA cuspiu slop, corrigir rota, barrar a task ruim. Júnior na mesma ferramenta é dinheiro no ralo, porque sem engenharia de software de verdade ele aceita o que vier e bate cabeça no resultado final. O ROI anda colado na senioridade, não na ferramenta.</p>
<p>Isso vira default no dia que rodar trinta tasks em paralelo, cada uma com seu revisor, custar o mesmo que rodar uma na mão. Quem quer antecipar esse dia já faz o token doer menos com roteamento de modelo: a maior parte das tasks num modelo barato, o caro só no plano e no review.</p>
<aside class="ns-cta ns-cta-mid" data-servico="discovery">
  <p class="eyebrow">● Nextside</p>

  <h3 class="ns-cta-title">Vai botar agente pra executar spec no seu time? A gente valida onde a IA acelera de verdade num Discovery, antes de você queimar budget.</h3>

  <p class="ns-cta-meta">Validação técnica · 2-3 semanas · Entrega: roadmap &#43; protótipo.</p>

  <div class="ns-cta-actions">
    <a href="https://www.nextside.tech/?utm_source=blog&amp;utm_medium=cta&amp;utm_campaign=discovery&amp;utm_content=spec-driven-development-gargalo-execucao-mid#discovery" class="btn btn-primary">Fale com a Nextside →</a></div>
</aside>

<h2>Ferramenta muda, a física é a mesma<span class="hx:absolute hx:-mt-20" id="ferramenta-muda-a-física-é-a-mesma"></span>
    <a href="#ferramenta-muda-a-f%c3%adsica-%c3%a9-a-mesma" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>A parte mais interessante não é nenhuma ferramenta específica. É que todo mundo, partindo de lugares diferentes, está chegando nas mesmas duas regras.</p>
<p><strong>Regra um: a memória do projeto vive nos arquivos, não no contexto.</strong> <a href="/posts/2026/05/16/adrs-decisao-no-notion-sem-burocracia/">ADR no repo</a>, <code>project-context.md</code>, <code>state.json</code>, <code>todo.md</code>, matriz de decisão versionada. O agente não precisa &ldquo;lembrar&rdquo; da decisão da task quatro. Ele lê o arquivo. O context rot some porque você parou de empilhar histórico na janela.</p>
<p><strong>Regra dois: o revisor nunca é o autor, por construção.</strong> Contextos separados pra quem gera e pra quem valida. O validador entra assumindo que tem bug e vai caçar.</p>
<p>Olha o tanto de gente que chegou nisso por caminhos opostos:</p>
<ul>
<li><strong>Ralph loop</strong> (Geoffrey Huntley): embrulha o agente num <code>while</code>, contexto limpo a cada volta, memória no disco. Monolítico de propósito. Ele rejeita multi-agente, e ainda assim externaliza o estado igualzinho.</li>
<li><strong>Dynamic Workflows</strong> (Anthropic): o oposto do Ralph, fan-out de centenas de agentes, mas o script segura o estado e o revisor adversarial é separado.</li>
<li><strong>BMAD, MDDD, cstk</strong>: frameworks da comunidade que, cada um do seu jeito (ADR mais reviewer adversarial, matriz de decisão, ondas com <code>state.json</code> e roteamento de modelo), implementam as mesmas duas regras.</li>
</ul>
<blockquote>
  <p>&ldquo;Vocês tão só reinventando um <code>while</code> loop com mais etapas.&rdquo;</p>

</blockquote>
<p>Em parte, sim. O Ralph loop é a forma mais crua disso, e funciona. A diferença é o que você pendura em cima: consolidador, revisor separado, roteamento de modelo, <a href="/posts/2026/05/16/claude-code-superpowers-plugin-na-pratica/">tudo codificado num harness</a> em vez de no seu prompt de três da manhã. O princípio é velho. A disciplina de aplicá-lo é o que muda o resultado.</p>
<h2>O trabalho que você achava que era pensar<span class="hx:absolute hx:-mt-20" id="o-trabalho-que-você-achava-que-era-pensar"></span>
    <a href="#o-trabalho-que-voc%c3%aa-achava-que-era-pensar" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Spec-Driven Development não falhou. Ele resolveu a parte que dava pra resolver escrevendo, e expôs a parte que faltava: executar sem o contexto apodrecer e sem você no meio do circuito copiando output de um lado pro outro.</p>
<p>A saída não é uma ferramenta. É uma física: estado fora da janela, revisor fora do autor. Dynamic Workflows, Ralph loop, cstk, BMAD, são sotaques da mesma frase.</p>
<p>O trabalho que você achava que era pensar sempre foi gerenciar contexto. A IA não mudou isso. Só deixou na cara.</p>
]]></content:encoded></item><item><title>Maestro + Claude Code: seu app testado no simulador como o Playwright testa a web</title><link>https://blog.nextside.tech/posts/2026/06/01/maestro-claude-code-testar-app-no-simulador/</link><pubDate>Mon, 01 Jun 2026 09:00:00 -0300</pubDate><guid>https://blog.nextside.tech/posts/2026/06/01/maestro-claude-code-testar-app-no-simulador/</guid><dc:creator>Bruno Raphael</dc:creator><category>maestro</category><category>mobile-testing</category><category>react-native</category><category>claude-code</category><category>qa-automation</category><description>Dá pra fazer o Claude navegar e testar seu app no simulador como o Playwright faz na web. Com Maestro: um YAML, iOS e Android, zero instrumentação.</description><content:encoded><![CDATA[<h2>TL;DR<span class="hx:absolute hx:-mt-20" id="tldr"></span>
    <a href="#tldr" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O Claude Code já navega seu site sozinho via Playwright: clica, preenche, valida regressão. Pra app mobile dá pra fazer a mesma coisa, mas ninguém explica direito como. Fui atrás. A resposta é o <dfn>Maestro</dfn>, um framework open source de teste E2E mobile com flows escritos em YAML, plugado no Claude Code. Um único arquivo de teste roda igual em iOS e Android, sobre o binário compilado, sem instrumentar o app. React Native, nativo ou Flutter, tanto faz. O Claude inspeciona a tela, escreve o flow, roda e conserta o que quebra. E não: o caminho certo NÃO é &ldquo;dar acesso à tela pro Claude&rdquo;. Screenshot por coordenada é o último recurso, não o primeiro.</p>
<p>Esse post é o setup que montei pra fechar no mobile o buraco que o <a href="/posts/2026/05/16/mcp-playwright-validacao-local-com-qualidade/">Playwright já fechou pra web</a>. <a href="https://nextside.tech"target="_blank" rel="noopener">Aqui na Nextside</a> ainda não virou pipeline de produção. É o caminho que estou adotando, com a engenharia destrinchada, os comandos na mão e os números de quem já trilhou ele.</p>
<h2>Não é &ldquo;dar acesso à tela&rdquo;. É ler a árvore.<span class="hx:absolute hx:-mt-20" id="não-é-dar-acesso-à-tela-é-ler-a-árvore"></span>
    <a href="#n%c3%a3o-%c3%a9-dar-acesso-%c3%a0-tela-%c3%a9-ler-a-%c3%a1rvore" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Quando eu conto isso, vem sempre a mesma pergunta, e eu também fiz ela no começo: &ldquo;o Claude não consegue só olhar a tela e clicar, igual um humano?&rdquo;. Consegue. Chama <dfn>Computer Use</dfn>: o Claude controla a interface por screenshot e clique em coordenada de pixel. Lançou no Claude Code em março de 2026, dirige o simulador, funciona pra demo.</p>
<p>Só que é o jeito errado pra teste.</p>
<p>O Playwright que você já usa nunca olhou pixel nenhum. Ele lê o <em>accessibility tree</em>, a árvore estruturada que descreve &ldquo;botão rotulado Entrar, aqui&rdquo;. Age por elemento, não por coordenada. É por isso que é rápido e não alucina onde clicar.</p>
<p>A diferença dá pra medir em token: a árvore de acessibilidade de uma tela sai por <a href="https://github.com/conorluddy/ios-simulator-skill"target="_blank" rel="noopener">uns 10 tokens, e um screenshot da mesma tela custa de 1.600 a 6.300</a>. Multiplica por cada passo de um teste de vinte telas e você entende por que visão não escala num loop de QA.</p>
<p>No fundo são três jeitos de fazer o Claude mexer no app, do melhor pro pior:</p>
<ul>
<li><strong>MCP ou CLI lendo a árvore.</strong> Estruturado, determinístico, barato em token. É o &ldquo;jeito Playwright&rdquo;, e é onde o Maestro vive.</li>
<li><strong>Computer Use por screenshot.</strong> O Claude enxerga a tela e chuta coordenada. Generaliza pra qualquer app, mas é lento (2 a 5 segundos por ação), erra clique e queima contexto.</li>
<li><strong>Nada.</strong> Você testando tudo na mão, que é de onde a gente tá saindo.</li>
</ul>
<p>A própria Anthropic ordena assim. A <a href="https://code.claude.com/docs/en/computer-use"target="_blank" rel="noopener">hierarquia de ferramentas do Claude Code</a> é MCP primeiro, depois shell, depois Chrome, e só cai pro controle de tela quando nada mais alcança: &ldquo;apps nativos, simuladores e ferramentas sem API&rdquo;.</p>
<p><strong>Screenshot é o último recurso, não o primeiro.</strong></p>
<h2>Maestro: um YAML, iOS e Android, zero instrumentação<span class="hx:absolute hx:-mt-20" id="maestro-um-yaml-ios-e-android-zero-instrumentação"></span>
    <a href="#maestro-um-yaml-ios-e-android-zero-instrumenta%c3%a7%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Se o jeito certo é ler a árvore, eu preciso de uma ferramenta que exponha a árvore do simulador pro Claude. Tem várias. Eu fechei no Maestro, e pra quem mantém React Native e app nativo, ele ganha por três motivos concretos:</p>
<ul>
<li><strong>Opera na camada de acessibilidade, sobre o binário compilado.</strong> Não importa se o app é React Native, Swift/Kotlin nativo ou Flutter. O Maestro testa o APK/IPA pronto, sem driver instalado nem mudança no código-fonte. Pra um time que toca RN e nativo lado a lado, isso é o fim de manter duas stacks de teste.</li>
<li><strong>O mesmo arquivo roda nos dois sistemas.</strong> Você escreve o flow uma vez. Roda no simulador do iPhone e no emulador do Android sem reescrever uma linha.</li>
<li><strong>YAML que humano e máquina leem.</strong> Não é código com seletor frágil. É uma sequência declarativa que o Claude gera e edita na hora.</li>
</ul>
<p>Um flow do Maestro começa simples assim:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">appId</span><span class="p">:</span><span class="w"> </span><span class="l">com.suaempresa.app</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nn">---</span><span class="w">
</span></span></span><span class="line"><span class="cl">- <span class="l">launchApp</span><span class="w">
</span></span></span><span class="line"><span class="cl">- <span class="nt">tapOn</span><span class="p">:</span><span class="w"> </span>{<span class="w"> </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;login_button&#34;</span><span class="w"> </span>}<span class="w">
</span></span></span><span class="line"><span class="cl">- <span class="nt">inputText</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;user@nextside.tech&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl">- <span class="nt">tapOn</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Entrar&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl">- <span class="nt">assertVisible</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Bem-vindo&#34;</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p><code>appId</code>, três hífens, e os comandos em linguagem quase natural: <code>launchApp</code>, <code>tapOn</code>, <code>inputText</code>, <code>assertVisible</code>. Quem nunca viu entende em dez segundos.</p>
<p>Onde isso fica sério é no reuso. O login se repete em todo teste, então você extrai ele uma vez e chama com <code>runFlow</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="c"># flows/login.yaml</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">appId</span><span class="p">:</span><span class="w"> </span><span class="l">com.suaempresa.app</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nn">---</span><span class="w">
</span></span></span><span class="line"><span class="cl">- <span class="nt">launchApp</span><span class="p">:</span><span class="w"> </span>{<span class="w"> </span><span class="nt">clearState</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w"> </span>}<span class="w">
</span></span></span><span class="line"><span class="cl">- <span class="nt">tapOn</span><span class="p">:</span><span class="w"> </span>{<span class="w"> </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;login_button&#34;</span><span class="w"> </span>}<span class="w">
</span></span></span><span class="line"><span class="cl">- <span class="nt">inputText</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;user@nextside.tech&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl">- <span class="nt">tapOn</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Entrar&#34;</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="c"># flows/comprar.yaml</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">appId</span><span class="p">:</span><span class="w"> </span><span class="l">com.suaempresa.app</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nn">---</span><span class="w">
</span></span></span><span class="line"><span class="cl">- <span class="nt">runFlow</span><span class="p">:</span><span class="w"> </span><span class="l">login.yaml         </span><span class="w"> </span><span class="c"># reusa o login inteiro</span><span class="w">
</span></span></span><span class="line"><span class="cl">- <span class="nt">tapOn</span><span class="p">:</span><span class="w"> </span>{<span class="w"> </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;produto_42&#34;</span><span class="w"> </span>}<span class="w">
</span></span></span><span class="line"><span class="cl">- <span class="nt">scrollUntilVisible</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">element</span><span class="p">:</span><span class="w"> </span>{<span class="w"> </span><span class="nt">text</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Finalizar compra&#34;</span><span class="w"> </span>}<span class="w">
</span></span></span><span class="line"><span class="cl">- <span class="nt">tapOn</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Finalizar compra&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl">- <span class="nt">assertVisible</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Pedido confirmado&#34;</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Muda a regra de login num lugar, vale nos vinte testes que chamam ele. Repara no <code>scrollUntilVisible</code> e no <code>clearState: true</code>: o Maestro tem comando pra rolar até achar, limpar estado, trocar permissão, setar localização. E <strong>espera o elemento aparecer sozinho</strong>, sem você espalhar <code>sleep</code> pelo teste. Sleep é cheiro de teste mal feito, aqui não precisa.</p>
<p><strong>Mesmo arquivo. iOS e Android. Sem tocar no código do app.</strong></p>
<h2>Do zero ao primeiro teste<span class="hx:absolute hx:-mt-20" id="do-zero-ao-primeiro-teste"></span>
    <a href="#do-zero-ao-primeiro-teste" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O &ldquo;como usar&rdquo; de verdade começa antes do Claude. Você precisa de três coisas na máquina:</p>
<ul>
<li><strong>Java 17 ou mais novo.</strong> O motor do Maestro roda em JVM. Confere com <code>java -version</code>.</li>
<li><strong>Xcode e o Command Line Tools.</strong> É o que destrava o simulador iOS.</li>
<li><strong>Android platform-tools com o <code>$ANDROID_HOME</code> setado e um emulador rodando.</strong> Confere com <code>adb devices</code>.</li>
</ul>
<p>Com isso no lugar, instala o Maestro num comando:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -fsSL <span class="s2">&#34;https://get.maestro.mobile.dev&#34;</span> <span class="p">|</span> bash
</span></span><span class="line"><span class="cl"><span class="c1"># ou, no macOS, via Homebrew:</span>
</span></span><span class="line"><span class="cl"><span class="c1"># brew install mobile-dev-inc/tap/maestro</span>
</span></span><span class="line"><span class="cl">maestro --help   <span class="c1"># confirma que tá vivo</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Boota um simulador (ou emulador), instala seu app nele, e roda o flow:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">maestro <span class="nb">test</span> flows/comprar.yaml      <span class="c1"># um flow</span>
</span></span><span class="line"><span class="cl">maestro <span class="nb">test</span> flows/                  <span class="c1"># a pasta inteira</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Só isso já te dá teste E2E rodando local, sem IA nenhuma. A IA entra pra você parar de escrever esses YAMLs na mão.</p>
<h2>O loop na prática: o Claude escreve o teste olhando o app<span class="hx:absolute hx:-mt-20" id="o-loop-na-prática-o-claude-escreve-o-teste-olhando-o-app"></span>
    <a href="#o-loop-na-pr%c3%a1tica-o-claude-escreve-o-teste-olhando-o-app" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Conecta o Maestro ao Claude Code num comando:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">claude mcp add maestro -- maestro mcp</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Isso entrega ao Claude um punhado de ferramentas: <code>inspect_screen</code> (pega a view hierarchy da tela como JSON compacto), <code>run</code> (executa um flow) e <code>open_maestro_viewer</code> (embute o simulador numa janela onde você vê cada comando rodar em tempo real).</p>
<p>O loop que isso destrava muda o jogo:</p>
<ol>
<li><strong>Claude inspeciona</strong> a tela ao vivo. Lê a árvore, não adivinha.</li>
<li><strong>Claude escreve</strong> o flow YAML, <a href="https://maestro.dev/blog/maestro-mcp-an-introduction"target="_blank" rel="noopener">sem você caçar element ID na mão</a>.</li>
<li><strong>Claude roda</strong> no simulador.</li>
<li><strong>Claude diagnostica</strong> o que falhou olhando a hierarquia, e conserta o próprio teste.</li>
</ol>
<p>O passo 4 é o que mais economiza saúde. Quando um <code>tapOn: &quot;Entrar&quot;</code> quebra porque o botão virou &ldquo;Acessar&rdquo; numa refatoração, o fluxo manual é: teste falha no CI, alguém abre, descobre, corrige o seletor, sobe de novo. Com o loop, o Claude relê a hierarquia, vê que o rótulo mudou, troca pro <code>id</code> estável e te mostra o diff. Você aprova ou não. <a href="https://maestro.dev/blog/maestro-mcp-an-introduction"target="_blank" rel="noopener">O Maestro chama isso de self-healing</a>. É a manutenção de teste, a parte mais chata de QA, saindo das suas costas.</p>
<p>No React Native, o que faz esse loop ser confiável é o <code>testID</code>. O que você já põe nos componentes vira o <code>id</code> do Maestro direto:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-jsx" data-lang="jsx"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">Button</span> <span class="na">title</span><span class="o">=</span><span class="s">&#34;Entrar&#34;</span> <span class="na">testID</span><span class="o">=</span><span class="s">&#34;login_button&#34;</span> <span class="na">onPress</span><span class="o">=</span><span class="p">{</span><span class="nx">onLogin</span><span class="p">}</span> <span class="p">/&gt;</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Prefira <code>testID</code> a texto sempre. Texto muda com tradução e com revisão de copy. O <code>testID</code> só muda se você mexer nele de propósito. E quando não souber qual seletor existe numa tela, <code>maestro studio</code> abre um inspetor visual no browser: você clica no elemento, ele mostra os seletores disponíveis e gera o YAML do passo. É assim que você ensina o Claude a mirar nos lugares certos do seu app.</p>
<h3>MCP ou Skill+CLI: qual usar?<span class="hx:absolute hx:-mt-20" id="mcp-ou-skillcli-qual-usar"></span>
    <a href="#mcp-ou-skillcli-qual-usar" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Os dois funcionam. A escolha é sobre contexto. O <strong>MCP</strong> é plug-and-play: um comando e o Claude tem as ferramentas. O preço é que todo MCP carrega o schema das tools no contexto do modelo, e isso come token a cada sessão.</p>
<p>A alternativa é uma <strong>Skill</strong> que ensina o Claude a rodar <code>maestro test flow.yaml</code> direto no terminal. Mais enxuto, porque você não paga o overhead do servidor. A <a href="https://news.ycombinator.com/item?id=45642911"target="_blank" rel="noopener">própria comunidade está migrando de MCP pra Skill+CLI por isso</a>. Minha regra: começo no MCP pra explorar e prototipar rápido. Quando o fluxo vira rotina, encapsulo numa Skill com o CLI e largo o servidor.</p>
<aside class="ns-cta ns-cta-mid" data-servico="discovery">
  <p class="eyebrow">● Nextside</p>

  <h3 class="ns-cta-title">Quer botar o Claude pra testar seu app mas não sabe se cola no seu stack? A gente valida o setup com você num Discovery.</h3>

  <p class="ns-cta-meta">Validação técnica · 2-3 semanas · Entrega: roadmap &#43; protótipo.</p>

  <div class="ns-cta-actions">
    <a href="https://www.nextside.tech/?utm_source=blog&amp;utm_medium=cta&amp;utm_campaign=discovery&amp;utm_content=maestro-claude-code-testar-app-no-simulador-mid#discovery" class="btn btn-primary">Fale com a Nextside →</a></div>
</aside>

<h2>O pedágio do iOS (a parte que ninguém posta)<span class="hx:absolute hx:-mt-20" id="o-pedágio-do-ios-a-parte-que-ninguém-posta"></span>
    <a href="#o-ped%c3%a1gio-do-ios-a-parte-que-ningu%c3%a9m-posta" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Agora a parte honesta, porque vender isso como mágica é desserviço.</p>
<p>Primeiro: teste gerado por IA acerta <a href="https://medium.com/coding-nexus/someone-built-a-tool-that-lets-claude-code-autonomously-test-your-entire-ios-app-5256d0a49703"target="_blank" rel="noopener">70 a 80% na primeira passada</a>. O Claude escolhe o seletor errado, esquece um wait. O fluxo que presta é deixar a IA gerar a v1, rodar uma vez pra validar, e devolver a manutenção pra ela. Não é &ldquo;manda e esquece&rdquo;.</p>
<p>Segundo, e pesado pra quem é de mobile: <strong>o iOS cobra pedágio.</strong> Um dev documentou montar o mesmo QA nas duas plataformas. <a href="https://christophermeiklejohn.com/ai/zabriskie/development/android/ios/2026/03/22/teaching-claude-to-qa-a-mobile-app.html"target="_blank" rel="noopener">Android levou 90 minutos, o iOS passou de seis horas</a>. A frase dele resume a década inteira de automação mobile. &ldquo;Android te dá um WebSocket e diz: aqui está o app, faça o que quiser. iOS te dá uma porta trancada e um bilhete pedindo pra usar o Xcode.&rdquo;</p>
<p>A boa notícia é que o Maestro abstrai boa parte desse pedágio, é o mesmo <code>tapOn</code> nos dois. Mas duas pedras você ainda vai pisar no React Native:</p>
<ul>
<li><strong>Componente aninhado no iOS.</strong> O iOS &ldquo;engole&rdquo; o toque quando você tem um <code>Text</code> dentro de um <code>TouchableOpacity</code> dentro de outro container tocável. A correção é <code>accessible={false}</code> no container de fora e <code>accessible={true}</code> no elemento de dentro. É chato, mas é uma vez por componente.</li>
<li><strong>Expo Go não aceita <code>launchApp</code>.</strong> Rodando via Expo Go, o app vive dentro do container do Expo, e o <code>launchApp</code> com seu <code>appId</code> não pega. Tem que usar <code>openLink</code> com a URL de dev, ou fazer um development build de verdade (EAS). Em bare React Native, <code>launchApp</code> funciona normal.</li>
</ul>
<blockquote>
  <p>&ldquo;Vocês vão deixar um bot escrever e rodar os testes do app? Isso vai dar ruim.&rdquo;</p>

</blockquote>
<p>Vai dar ruim se você tratar o teste gerado como verdade e largar. Não vai se você tratar como rascunho que o sênior revisa, igual você já faz (ou devia fazer) com código que a IA escreve. O Maestro ainda te entrega o YAML versionado: dá pra ler no PR, discordar, corrigir. O teste continua sendo seu. O Claude só parou de te fazer digitar ele do zero.</p>
<h2>De teste solto a rotina<span class="hx:absolute hx:-mt-20" id="de-teste-solto-a-rotina"></span>
    <a href="#de-teste-solto-a-rotina" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Um teste que você roda na mão quando lembra não é rede de segurança. É teatro. O ganho real aparece quando o flow vira rotina automática. Como o Maestro é só um binário de linha de comando, ele entra em qualquer lugar que rode shell:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">maestro <span class="nb">test</span> flows/    <span class="c1"># roda a suíte inteira; sai com código de erro se quebrar</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Esse <code>maestro test flows/</code> é a mesma linha que você roda local, no GitHub Actions a cada PR, ou num cron noturno. Aquele dev do case real <a href="https://christophermeiklejohn.com/ai/zabriskie/development/android/ios/2026/03/22/teaching-claude-to-qa-a-mobile-app.html"target="_blank" rel="noopener">deixou a suíte rodando como tarefa agendada toda manhã às 8:47</a>: boota os dois simuladores, varre as telas, analisa, e abre report do que parece quebrado. O dev acorda com o QA já feito.</p>
<p>O ciclo fecha aqui. O Claude escreve o flow olhando o app, o flow vira arquivo versionado, o arquivo roda no CI. A IA monta a rede, a máquina puxa ela toda noite.</p>
<h2>A IA escreve o código e o teste. Você ainda decide o que é &ldquo;funciona&rdquo;.<span class="hx:absolute hx:-mt-20" id="a-ia-escreve-o-código-e-o-teste-você-ainda-decide-o-que-é-funciona"></span>
    <a href="#a-ia-escreve-o-c%c3%b3digo-e-o-teste-voc%c3%aa-ainda-decide-o-que-%c3%a9-funciona" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>A gente <a href="/posts/2026/05/25/code-review-novo-gargalo-coderabbit/">já falou aqui que a IA revisa código mas não testa software</a>. Continua verdade, com um asterisco novo: agora ela TESTA, no simulador, navegando o app como usuário faria. O que ela não faz é decidir o que conta como &ldquo;funcionou&rdquo;.</p>
<p>Esse julgamento é seu. O critério de aceite é seu. O Maestro e o Claude tiram de você a parte chata: bootar o simulador, caçar o ID do botão, digitar o flow, rodar nos dois sistemas, consertar o seletor que mudou. Devolvem o tempo pra única coisa que a máquina não faz: olhar o app e decidir se está bom.</p>
<p>Ferramenta boa não substitui critério. Ela só tira a desculpa de não ter testado.</p>
]]></content:encoded></item><item><title>Code review virou o gargalo. CodeRabbit não salva sozinho</title><link>https://blog.nextside.tech/posts/2026/05/25/code-review-novo-gargalo-coderabbit/</link><pubDate>Mon, 25 May 2026 09:00:00 -0300</pubDate><guid>https://blog.nextside.tech/posts/2026/05/25/code-review-novo-gargalo-coderabbit/</guid><dc:creator>Pablo Winter</dc:creator><category>code-review</category><category>coderabbit</category><category>ai-tooling</category><category>claude-code</category><category>devops</category><category>produtividade-dev</category><description>Time saiu de 2 semanas de backlog de PR pra zero review humano em staging. Como o CodeRabbit funciona, onde quebra, e por que CLAUDE.md é a fonte única.</description><content:encoded><![CDATA[<h2>TL;DR<span class="hx:absolute hx:-mt-20" id="tldr"></span>
    <a href="#tldr" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>IA acelerou o dev. O gargalo migrou pra revisão. Vi time de consultoria com <strong>2 semanas de backlog de PR</strong> esperando o tech lead revisar, e o time achando que era questão de contratar mais um sênior. Não é. O ritmo do dev mudou, o ritmo do review não. CodeRabbit consegue tirar essa fila e deixar a esteira de PR pra <code>develop</code> 100% autônoma em mais ou menos um mês de calibração. Funciona. Mas tem uma pegadinha: o time começa a confiar tanto na esteira que larga o reflexo de testar local. E aí o deploy quebra em staging por bug que ninguém viu rodando.</p>
<p>Esse post é sobre os dois lados.</p>
<h2>IA não eliminou o gargalo. Empurrou pro tech lead.<span class="hx:absolute hx:-mt-20" id="ia-não-eliminou-o-gargalo-empurrou-pro-tech-lead"></span>
    <a href="#ia-n%c3%a3o-eliminou-o-gargalo-empurrou-pro-tech-lead" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Olha o número: código com coautoria de IA gera <a href="https://www.businesswire.com/news/home/20251217666881/en/CodeRabbits-State-of-AI-vs-Human-Code-Generation-Report-Finds-That-AI-Written-Code-Produces-1.7x-More-Issues-Than-Human-Code"target="_blank" rel="noopener"><strong>1.7x mais issues por PR</strong></a> que código 100% humano. Fonte é o State of AI Code Generation Report do próprio CodeRabbit, analisando 470 PRs de projetos open source em dezembro de 2025. O achado é consistente com o que qualquer TL que adotou Cursor ou Claude Code no time tá vendo na prática.</p>
<p>Faz sentido: o dev produz mais código, mais rápido, e nem sempre com a mesma carga de contexto que tinha quando escrevia tudo na mão. Mais código + menos contexto = mais coisa pra revisar e menos confiança automática de que o autor sabe o que tá fazendo.</p>
<p>Olha o efeito no time:</p>
<p>O TL vira funil. Peguei time de consultoria onde o backlog de PR pra revisão chegou a <strong>2 semanas</strong>. O sênior responsável tava acordando 6h pra revisar antes do daily, ficando depois do horário pra revisar antes de dormir, e ainda assim a fila crescia. O time achava que era subdimensionamento.</p>
<p>Não era. <dfn>Code review</dfn> (a etapa em que outro humano valida o PR antes do merge) virou o novo gargalo da esteira de entrega. O dev individual ficou mais rápido. O processo coletivo não.</p>
<p><strong>O gargalo só anda de andar.</strong></p>
<h2>O mês em que o TL ensinou o bot<span class="hx:absolute hx:-mt-20" id="o-mês-em-que-o-tl-ensinou-o-bot"></span>
    <a href="#o-m%c3%aas-em-que-o-tl-ensinou-o-bot" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>A jogada foi implantar o <dfn>CodeRabbit</dfn> (bot de AI code review que comenta linha por linha em cada PR) com o TL pilotando ele por um mês inteiro. Não foi &ldquo;instala e libera geral&rdquo;. Foi:</p>
<ol>
<li>CodeRabbit comenta o PR</li>
<li>TL revisa em cima: confirma o que tá certo, contesta o que tá errado</li>
<li>Quando contesta, vai no <code>.coderabbit.yaml</code> e adiciona regra pra próxima vez</li>
<li>Quando o CodeRabbit passa batido em algo importante, vai no <code>.coderabbit.yaml</code> e adiciona <dfn>path instruction</dfn>: instrução de revisão escrita em português natural com glob de arquivo</li>
<li>Repete</li>
</ol>
<p>Em duas semanas a quantidade de regra que o TL adicionava por dia caiu. Em três semanas o CodeRabbit acertava mais que errava. No fim do primeiro mês a curva achatou: regra nova virou exceção.</p>
<p>A virada de chave foi conectar duas coisas que o CodeRabbit não pega sozinho:</p>
<ul>
<li><strong>Notion via MCP</strong>: todo <a href="/posts/2026/05/16/adrs-decisao-no-notion-sem-burocracia/">ADR e decisão arquitetural do time fica no Notion</a>. Conectando o CodeRabbit no Notion via MCP, ele lê o contexto antes de revisar. Acaba o tipo de comentário &ldquo;isso devia usar pattern X&rdquo; quando o ADR diz pra usar Y.</li>
<li><strong>JIRA na description do PR</strong>: toda PR é obrigada a citar o ID da issue JIRA. CodeRabbit puxa a US e cruza com o diff.</li>
</ul>
<p>A segunda muda mais o jogo do que parece.</p>
<h3>Por que exigir JIRA ID na description do PR muda o jogo?<span class="hx:absolute hx:-mt-20" id="por-que-exigir-jira-id-na-description-do-pr-muda-o-jogo"></span>
    <a href="#por-que-exigir-jira-id-na-description-do-pr-muda-o-jogo" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Porque o CodeRabbit deixa de revisar só código e passa a revisar <strong>se o PR entrega a história</strong>. Os critérios de aceite estão na US? Então o bot bate cada AC contra o diff e flagra: &ldquo;AC #3 fala em validação de e-mail duplicado, mas não vejo essa checagem no PR&rdquo;. Aqui não é opinião: é checklist.</p>
<p>Só que tem um pré-requisito que pouco time quer encarar: a US precisa estar bem dimensionada e com AC escrito decente. Vejo time atrás de time falhando exatamente aí. PO cospe US gigante, vaga, com AC tipo &ldquo;validar formulário&rdquo;. O CodeRabbit lê isso e não consegue fazer nada com isso. Aí o pessoal acha que a ferramenta não serve. Serve. Quem não serve é o refinamento.</p>
<p><strong>Sem AC bem escrito, CodeRabbit vira régua sem números.</strong></p>
<h2>Hoje, PR pra staging não passa mais por humano<span class="hx:absolute hx:-mt-20" id="hoje-pr-pra-staging-não-passa-mais-por-humano"></span>
    <a href="#hoje-pr-pra-staging-n%c3%a3o-passa-mais-por-humano" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Depois desse mês de calibração, o que mudou no fluxo:</p>
<ul>
<li><strong>PR pra <code>develop</code> (staging):</strong> após N iterações entre dev e CodeRabbit, o próprio bot aprova. Zero humano. Merge.</li>
<li><strong>PR pra <code>master</code> (produção):</strong> ainda passa por humano. Sempre.</li>
</ul>
<blockquote>
  <p>&ldquo;Vocês deixam IA aprovar código sozinha. Isso vai dar ruim.&rdquo;</p>

</blockquote>
<p>Esse é o comentário que aparece toda vez que conto isso. Geralmente vem de alguém que nunca viu o que é um TL revisando 8 horas de PR por dia em vez de fazer arquitetura. Sim, deixa. Em staging. Onde o pior cenário é o deploy quebrar e a gente reverter. Não em produção. Em staging.</p>
<p>E a diferença prática: o TL voltou a fazer arquitetura. O time entrega mais. O dev pega o feedback do CodeRabbit em minutos em vez de em dias.</p>
<h3>CodeRabbit vs GitHub Copilot Code Review vs Greptile: qual escolher?<span class="hx:absolute hx:-mt-20" id="coderabbit-vs-github-copilot-code-review-vs-greptile-qual-escolher"></span>
    <a href="#coderabbit-vs-github-copilot-code-review-vs-greptile-qual-escolher" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Resposta curta: depende do que dói mais.</p>
<ul>
<li><strong>CodeRabbit</strong>: line-by-line, learnings persistentes, integrações fortes (MCP, JIRA, Notion). Trade-off: ~3min por review e $24/dev/mês. Ganha em profundidade e em encaixar no workflow.</li>
<li><strong>GitHub Copilot Code Review</strong>: $10/user/mês, zero atrito porque o time já paga Copilot. Review mais raso, sem learnings persistentes, sem integração nativa com Jira/Notion. Bom pra começar.</li>
<li><strong>Greptile</strong>: <a href="https://wetheflywheel.com/en/guides/best-ai-code-review-tools-2026/"target="_blank" rel="noopener">bench dele mesmo diz 82% de catch contra 44% do CodeRabbit</a>, mas gera <strong>11 falso-positivos</strong> contra 2 do CodeRabbit. Escolha sua dor: ou perde bug ou afoga o dev em ruído.</li>
</ul>
<p>Time pequeno que já paga Copilot: começa com Copilot Code Review e vê até onde vai. TL afogado em backlog de review: CodeRabbit paga ele mesmo no primeiro mês.</p>
<p>E honestidade: auditoria independente de 28 PRs revisados pelo CodeRabbit achou 15% de comentários &ldquo;useless/noise&rdquo; e 21% de nitpicking. <strong>Não é bala de prata.</strong> Tem que tunar. Tem que ensinar. Tem que usar os learnings. Quem instala e deixa rodando vai reclamar que é ruim. Porque é, pra esse uso.</p>
<aside class="ns-cta ns-cta-mid" data-servico="auditoria">
  <p class="eyebrow">● Nextside</p>

  <h3 class="ns-cta-title">Esse padrão tá no seu time? Auditamos seu pipeline e mapeamos onde a IA acelera entrega e onde tá criando dívida silenciosa.</h3>

  <p class="ns-cta-meta">Auditoria independente · 1-2 semanas · Sem amarras comerciais.</p>

  <div class="ns-cta-actions">
    <a href="https://www.nextside.tech/?utm_source=blog&amp;utm_medium=cta&amp;utm_campaign=auditoria&amp;utm_content=code-review-novo-gargalo-coderabbit-mid#auditoria" class="btn btn-primary">Fale com a Nextside →</a></div>
</aside>

<h2>Um arquivo, três cérebros: CLAUDE.md vira fonte única<span class="hx:absolute hx:-mt-20" id="um-arquivo-três-cérebros-claudemd-vira-fonte-única"></span>
    <a href="#um-arquivo-tr%c3%aas-c%c3%a9rebros-claudemd-vira-fonte-%c3%banica" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Esse aqui é o pulo do gato que pouca gente sacou ainda.</p>
<p>CodeRabbit auto-detecta <code>CLAUDE.md</code>, <code>AGENTS.md</code>, <code>.cursor/rules/*.mdc</code> e <code>.github/copilot-instructions.md</code> como knowledge base. A regra que você escreve uma vez em <code>CLAUDE.md</code> vale pra:</p>
<ol>
<li><strong>Claude Code</strong> ao codar: segue a regra na hora de escrever</li>
<li><strong>CodeRabbit</strong> ao revisar: bate o diff contra a mesma regra</li>
<li><strong>Cursor</strong> ao auto-completar: respeita a convenção</li>
</ol>
<p>Um arquivo, três cérebros lendo. Você para de manter regra duplicada em três sistemas. PR que sobe já tá quase aprovado porque foi escrito sob as mesmas regras que vão ser checadas no review.</p>
<p>E tem outro detalhe que fecha o loop: a CLI do CodeRabbit (<code>coderabbit --prompt-only</code>) cospe o feedback do review em formato consumível por agente. Dá pra montar um slash command no Claude Code que resolve os comentários em ciclo e fica empurrando back-push até o bot aprovar.</p>
<p>Salva isso como <code>.claude/commands/coderabbit-loop.md</code> no repo e usa <code>/coderabbit-loop</code> no Claude Code:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">Resolva os comentários do CodeRabbit no PR atual até obter approve.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">ANTES de aceitar qualquer sugestão, invoque o skill <span class="sb">`receiving-code-review`</span>
</span></span><span class="line"><span class="cl">do plugin superpowers. Sem isso, vira capacho do bot.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Fluxo:
</span></span><span class="line"><span class="cl"><span class="k">1.</span> Execute <span class="sb">`coderabbit --prompt-only`</span> e capture os comentários
</span></span><span class="line"><span class="cl"><span class="k">2.</span> Para cada comentário:
</span></span><span class="line"><span class="cl">   <span class="k">-</span> Se faz sentido técnico: aplique a mudança e commite com mensagem
</span></span><span class="line"><span class="cl">     ligando ao comentário (&#34;addresses CodeRabbit: &lt;resumo&gt;&#34;)
</span></span><span class="line"><span class="cl">   <span class="k">-</span> Se NÃO faz sentido: responda no PR com justificativa técnica e
</span></span><span class="line"><span class="cl">     marque como wontfix via <span class="sb">`@coderabbitai resolve`</span>
</span></span><span class="line"><span class="cl"><span class="k">3.</span> <span class="sb">`git push`</span> na branch
</span></span><span class="line"><span class="cl"><span class="k">4.</span> Aguarde re-review (polling do PR via <span class="sb">`gh pr view`</span> a cada 60s, máx 5min)
</span></span><span class="line"><span class="cl"><span class="k">5.</span> Se ainda houver comentários novos não-resolvidos, volte ao passo 2
</span></span><span class="line"><span class="cl"><span class="k">6.</span> Pare quando CodeRabbit aprovar OU ao atingir 5 iterações
</span></span><span class="line"><span class="cl">   (nesse ponto, chame o humano: provavelmente há discordância real)
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Use <span class="sb">`gh pr view --comments`</span> pra status. Use <span class="sb">`gh pr comment`</span> pra responder.
</span></span><span class="line"><span class="cl">Nunca <span class="sb">`--force-push`</span>: commit incremental sempre.</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>A linha do <code>receiving-code-review</code> não é detalhe. É o ponto.</p>
<p>Sem ela, o Claude Code aceita qualquer sugestão do CodeRabbit em modo &ldquo;performative agreement&rdquo;: concorda pra parecer educado, refatora código que tava bom, e o PR cresce com mudança que não devia existir. O skill <a href="/posts/2026/05/16/claude-code-superpowers-plugin-na-pratica/">receiving-code-review do plugin superpowers</a> força rigor técnico: validar a sugestão antes de aplicar, contestar quando discorda, exigir evidência. É o filtro que mantém o dev no comando, mesmo quando o dev é uma IA.</p>
<h2>Onde a esteira quebra: o dev parou de testar local<span class="hx:absolute hx:-mt-20" id="onde-a-esteira-quebra-o-dev-parou-de-testar-local"></span>
    <a href="#onde-a-esteira-quebra-o-dev-parou-de-testar-local" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Aqui é a parte que ninguém posta no LinkedIn.</p>
<p>Time com a stack completa (Claude Code + Superpowers + CodeRabbit) começa a confiar demais na esteira. O dev acha que se passou pelo CodeRabbit, tá bom. O TL acha que se o CodeRabbit aprovou, foi revisado. O QA acha que se chegou em staging, foi testado.</p>
<p>Resultado: NINGUÉM roda nada localmente antes do push. Vi isso acontecer em três times diferentes. Sintoma sempre o mesmo: PR mergeado em <code>develop</code>, deploy em staging, e aí descobre que a feature não funciona porque ninguém abriu o browser pra confirmar que o botão clica.</p>
<p>A IA revisa código. A IA não testa software.</p>
<p>A correção que adotei como inegociável: <strong>workflow obrigatório com command de validação E2E antes do push</strong>. No meu caso é um <code>/validar-e2e</code> que sobe a stack Docker do projeto, dispara 3 agents em paralelo (QA matrix, backend via <code>curl</code>/SQL, frontend via <a href="/posts/2026/05/16/mcp-playwright-validacao-local-com-qualidade/">MCP Playwright no Claude Code</a>) e só libera push quando todo cenário passa. Re-executa tudo após qualquer fix, nunca valida parcial.</p>
<p>Esse é o esqueleto pra adaptar ao teu projeto. Salva como <code>.claude/commands/validar-e2e.md</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">Validação E2E orquestrada antes de pedir review humano.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Sobe a stack local, gera a matriz de cenários, e SÓ DEPOIS dispara
</span></span><span class="line"><span class="cl">backend + frontend em paralelo com a matriz como input. NÃO pare em
</span></span><span class="line"><span class="cl">parcial. Após qualquer fix, RE-EXECUTE TUDO, não só o que mudou.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">REGRA DE QUALIDADE: se um agent entregar resultado raso, sem evidência
</span></span><span class="line"><span class="cl">concreta (sem log/SQL/print), com cenários pulados sem justificativa,
</span></span><span class="line"><span class="cl">ou claramente incompleto: RELANCE o agent com briefing mais explícito
</span></span><span class="line"><span class="cl">sobre o que faltou. Aceitar saída ruim contamina a decisão de merge.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="gu">## Fase 1: Subir/validar stack
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">-</span> <span class="sb">`docker compose -f docker-compose.e2e.yml up -d`</span>
</span></span><span class="line"><span class="cl"><span class="k">-</span> Aguardar health checks responderem 200 (timeout 5min)
</span></span><span class="line"><span class="cl"><span class="k">-</span> Se algum serviço falhou, reporte log do container e pare
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="gu">## Fase 2: Agent A: QA matrix (BLOQUEANTE, roda sozinho)
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Lance UM agent e ESPERE o output completo antes de prosseguir.
</span></span><span class="line"><span class="cl">Os agents B e C dependem dessa matriz: sem ela, vão testar no escuro.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Briefing do Agent A:
</span></span><span class="line"><span class="cl">  Produza matriz com ≥20 cenários baseada nos commits desta branch
</span></span><span class="line"><span class="cl">  vs develop. Categorias: happy path, regressão, edge cases (null/
</span></span><span class="line"><span class="cl">  vazio/limites), erro (DB indisponível, auth falha), migration
</span></span><span class="line"><span class="cl">  (idempotência). Para cada: ID, descrição, severidade (P0/P1/P2),
</span></span><span class="line"><span class="cl">  steps, resultado esperado. Salve em
</span></span><span class="line"><span class="cl">  <span class="sb">`docs/specs/&lt;feature&gt;-qa-matrix.md`</span>. Reporte contagem por
</span></span><span class="line"><span class="cl">  categoria + os 3 cenários P0 prioritários + os fluxos de UI
</span></span><span class="line"><span class="cl">  críticos a serem cobertos pelo frontend.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="gu">## Fase 3: Agents B e C em paralelo (alimentados pela matriz)
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">REGRA: UMA mensagem com 2 Agent tool calls simultâneos. Cole os 3
</span></span><span class="line"><span class="cl">cenários P0 (saída do Agent A) no briefing de B e os fluxos de UI
</span></span><span class="line"><span class="cl">críticos no briefing de C. Limite ≤80 tool calls por agent (acima
</span></span><span class="line"><span class="cl">disso dá socket error: relance com escopo menor se crashar).
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="gu">### Agent B: Backend E2E
</span></span></span><span class="line"><span class="cl">Execute os cenários P0 abaixo via curl contra a stack local. Valide
</span></span><span class="line"><span class="cl">DB após cada chamada (psql/mongosh/redis-cli conforme stack). Rode
</span></span><span class="line"><span class="cl">também unit tests das branches alteradas. Reporte PASS/FAIL com
</span></span><span class="line"><span class="cl">evidência (1-2 linhas de log/SQL) em ≤600 palavras. Não rebuild
</span></span><span class="line"><span class="cl">Docker, não toque em código de produção.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  Cenários P0 do QA: &lt;colar saída do Agent A aqui&gt;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="gu">### Agent C: Frontend MCP Playwright
</span></span></span><span class="line"><span class="cl">Execute os fluxos de UI críticos abaixo no browser via MCP Playwright.
</span></span><span class="line"><span class="cl">Para cada: screenshot do estado, inspeção do console (JS errors),
</span></span><span class="line"><span class="cl">validação de network requests. Reporte regressões em ≤700 palavras
</span></span><span class="line"><span class="cl">com prints.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  Fluxos críticos do QA: &lt;colar saída do Agent A aqui&gt;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="gu">## Fase 4: Consolidar
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">-</span> B e C ambos PASS com evidência → libere <span class="sb">`git push`</span> e abertura do PR
</span></span><span class="line"><span class="cl"><span class="k">-</span> Algum FAIL → corrija o código e VOLTE à Fase 3 (re-execute B e C
</span></span><span class="line"><span class="cl">  com a mesma matriz; só re-rode o Agent A se o fix mudou cenários)
</span></span><span class="line"><span class="cl"><span class="k">-</span> BLOCKED → diagnostique infra/contexto antes de tentar de novo
</span></span><span class="line"><span class="cl"><span class="k">-</span> Socket error num agent → relance com escopo reduzido (≤50 tool calls)
</span></span><span class="line"><span class="cl"><span class="k">-</span> Resultado raso/sem evidência → RELANCE o agent com briefing reforçado
</span></span><span class="line"><span class="cl">  pedindo exatamente o que faltou (logs, SQL queries, screenshots,
</span></span><span class="line"><span class="cl">  asserções específicas). Não aceite PASS sem prova.</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>E não é só fricção burocrática: é a forma de manter o reflexo. Quem testa local pega bug em 30 segundos. Quem espera staging pega em 30 minutos. Quem espera produção paga muito mais.</p>
<h2>A esteira é tua. A IA é só o motor.<span class="hx:absolute hx:-mt-20" id="a-esteira-é-tua-a-ia-é-só-o-motor"></span>
    <a href="#a-esteira-%c3%a9-tua-a-ia-%c3%a9-s%c3%b3-o-motor" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>CodeRabbit + Claude Code + Superpowers é stack. Stack boa. Tira gargalo real. Devolve tempo de TL pra arquitetura, zera backlog de review, e PR sai mais redondo porque a regra é única.</p>
<p>Mas é <strong>stack</strong>. Não é processo.</p>
<p>Processo é a disciplina de US bem escopada, AC bem escrito, teste local obrigatório, e a humildade de aceitar que a IA acelera o que tá certo e acelera junto o que tá errado.</p>
<p>Quem confunde stack com processo vai descobrir do jeito ruim. Provavelmente num deploy de sexta-feira.</p>
]]></content:encoded></item><item><title>MCP Playwright: validação local com qualidade real</title><link>https://blog.nextside.tech/posts/2026/05/16/mcp-playwright-validacao-local-com-qualidade/</link><pubDate>Sat, 16 May 2026 12:00:00 -0300</pubDate><guid>https://blog.nextside.tech/posts/2026/05/16/mcp-playwright-validacao-local-com-qualidade/</guid><dc:creator>Pablo Winter</dc:creator><category>mcp</category><category>playwright</category><category>claude-code</category><category>qualidade</category><category>testes</category><description>Antes de pedir review humano, o Claude com MCP Playwright já navegou seu app, tirou screenshot e flagou regressão. Local, no seu dev, em segundos.</description><content:encoded><![CDATA[<p>Cenário recorrente: você termina uma feature de frontend, dá <code>git diff</code>, parece tudo certo, comita. Cinco minutos depois alguém abre PR e diz &ldquo;o botão sumiu em mobile&rdquo;. Bem-vindo ao buraco da regressão visual. Pergunta: dá pra pegar isso antes do PR? Resposta seca: dá. E o caminho mais barato hoje passa por MCP + Playwright.</p>
<p><strong>TL;DR:</strong> MCP Playwright não é um framework de teste novo. Não substitui CI/CD. Não substitui o suite de E2E que seu engenheiro escreveu. <strong>É o seu jeito de pedir pra Claude testar local pra você</strong>, e te entregar screenshots de prova.</p>
<p>O fluxo de dev sempre foi: codar, escrever unit, rodar a aplicação local e testar à mão, abrir PR. O passo &ldquo;rodar e testar à mão&rdquo; era o que mais era pulado. &ldquo;Ah, unit passou, manda pra CI.&rdquo; Aí cai em produção bug que CI não pegou porque CI não cobre todo path. Com MCP Playwright, esse passo deixa de ser seu. Vira a IA navegando seu app, validando o fluxo, tirando print de cada estado relevante. Você ganha tempo. O PR ganha evidência. O CI continua fazendo o trabalho dele.</p>
<h2>O que é MCP, sem o palavreado<span class="hx:absolute hx:-mt-20" id="o-que-é-mcp-sem-o-palavreado"></span>
    <a href="#o-que-%c3%a9-mcp-sem-o-palavreado" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p><dfn>MCP: Model Context Protocol</dfn> é um protocolo aberto criado pela Anthropic pra ligar LLMs a ferramentas externas. Pensa em USB pra IA: padrão único, plug, e qualquer LLM compatível conversa com qualquer &ldquo;MCP server&rdquo; do mercado.</p>
<p>Antes de MCP, integrar IA com ferramenta externa era artesanal. Cada cliente (Claude Code, Cursor, Continue) tinha sua própria forma de invocar tools. Cada tool precisava de adaptador específico. Caos.</p>
<p>MCP padroniza isso. Você tem três pedaços:</p>
<ul>
<li><strong>Cliente</strong>: o app onde a IA roda (Claude Code, Claude Desktop, etc.)</li>
<li><strong>Servidor MCP</strong>: processo separado que expõe ferramentas via protocolo. Pode rodar local, remoto, em containers, qualquer lugar.</li>
<li><strong>Tools/Resources</strong>: o que o servidor expõe. &ldquo;navegue pra URL X&rdquo;, &ldquo;leia este arquivo&rdquo;, &ldquo;execute essa query&rdquo;.</li>
</ul>
<p>Cliente pergunta ao servidor o que ele oferece. Servidor responde com lista de tools. IA escolhe a tool, manda parâmetros, servidor executa, responde. Simples. Padronizado. Universal.</p>
<p>Tem servidor MCP pra praticamente tudo hoje: GitHub, Linear, Notion, Postgres, browser via Playwright, filesystem, Slack. Você pluga o que precisa. A IA passa a operar essas ferramentas como se fossem extensões do próprio cliente.</p>
<h2>Playwright como MCP server: por que importa<span class="hx:absolute hx:-mt-20" id="playwright-como-mcp-server-por-que-importa"></span>
    <a href="#playwright-como-mcp-server-por-que-importa" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Playwright é a stack de automação de browser do Microsoft. Headless ou não. Cross-browser (Chromium, Firefox, WebKit). API consistente, performante, com excelente DX. O que Selenium queria ser e nunca conseguiu.</p>
<p>Quando alguém empacota Playwright como MCP server, acontece o seguinte: o Claude ganha <strong>olhos no browser</strong>. Literalmente. Ele consegue:</p>
<ul>
<li>Abrir página em URL</li>
<li>Tirar screenshot</li>
<li>Ler o DOM via accessibility snapshot</li>
<li>Clicar em elemento</li>
<li>Preencher formulário</li>
<li>Esperar elemento aparecer</li>
<li>Verificar console por errors</li>
<li>Inspecionar requisição de rede</li>
<li>Executar JavaScript arbitrário no contexto da página</li>
</ul>
<p>Tudo isso através de comandos que o LLM escolhe baseado no contexto. Você não precisa escrever spec de teste. Você descreve em linguagem natural (&ldquo;valide se o card de post abre corretamente em mobile 375px&rdquo;) e Claude monta a sequência: navegar, redimensionar viewport, clicar, esperar, screenshot, verificar.</p>
<p>Pra quem nunca usou: parece feitiço. Pra quem usou: vira hábito em 3 dias.</p>
<blockquote>
  <p>&ldquo;Mas isso não é só mais um wrapper de Playwright?&rdquo; Não. Wrapper exige você escrever código. MCP Playwright deixa a IA escolher o passo certo baseado no contexto da tarefa. Diferença não é técnica: é de abstração. Você sai do &ldquo;como&rdquo; e fica no &ldquo;o quê&rdquo;.</p>

</blockquote>
<h2>Fluxo real: validar UX de um post antes do commit<span class="hx:absolute hx:-mt-20" id="fluxo-real-validar-ux-de-um-post-antes-do-commit"></span>
    <a href="#fluxo-real-validar-ux-de-um-post-antes-do-commit" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Pra ilustrar, fluxo que a gente da Nextside usa nesse próprio blog. Toda vez que um post novo sai do <a href="/posts/2026/05/16/claude-code-superpowers-plugin-na-pratica/">agent revisor codificado via Claude Code superpowers</a> pronto pro commit, lança um agent dedicado de <strong>UX review</strong> que usa MCP Playwright. Sequência:</p>
<ul>
<li><strong>Sobe Hugo local</strong>: <code>hugo server -D --port 1313</code></li>
<li><strong>Lança o agent</strong>: descreve a tarefa: &ldquo;valide o post X em light/dark e em mobile 375px/desktop 1280px&rdquo;</li>
<li><strong>Claude navega via MCP Playwright</strong>: abre <code>localhost:1313/posts/.../{slug}/</code>, espera carregar, tira screenshot</li>
<li><strong>Inspeciona console</strong>: verifica se tem JS error, warning de fonts, ou aviso de imagem broken</li>
<li><strong>Toggle dark mode</strong>: clica no toggle de tema, espera transição, tira screenshot</li>
<li><strong>Resize pra mobile</strong>: redimensiona viewport pra 375px, screenshot</li>
<li><strong>Reporta</strong>: markdown com prints embedded + checklist (✓ contraste, ✓ tipografia, ⚠ código longo overflow em mobile, ✓ ember glow só no CTA)</li>
</ul>
<p>Tempo total: 30 a 90 segundos. Custo: zero infra extra. Saída: relatório que eu, humano, leio em 2 minutos e decido se commito ou ajusto.</p>
<p>Compara com o fluxo antigo:</p>
<ul>
<li>Abrir manualmente no Chrome: 15s</li>
<li>Abrir DevTools, simular mobile: 20s</li>
<li>Ver dark mode: 10s</li>
<li>Ver console: 10s</li>
<li>Esquecer de testar uma das combinações pelo menos uma vez por semana: garantido</li>
</ul>
<p>E aqui mora o ganho real. Não é velocidade: é <strong>consistência</strong>. O Claude não esquece de testar dark mode. Não pula mobile na pressa. Não diz &ldquo;ah, depois eu vejo o console&rdquo;. Toda vez que roda, roda tudo.</p>
<p><strong>Disciplina automatizada bate disciplina humana cansada.</strong></p>
<h2>Antes vs depois: o que muda no fluxo do dev<span class="hx:absolute hx:-mt-20" id="antes-vs-depois-o-que-muda-no-fluxo-do-dev"></span>
    <a href="#antes-vs-depois-o-que-muda-no-fluxo-do-dev" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Olha o fluxo tradicional. O que a gente sempre fez:</p>
<ol>
<li>Coda a feature</li>
<li>Escreve teste unitário</li>
<li><strong>Roda a aplicação local e testa à mão</strong>: clica, navega, valida visualmente</li>
<li>Abre o PR</li>
<li>CI roda Playwright + unit completos</li>
<li>Reviewer humano olha o código</li>
</ol>
<p>O passo 3 é onde o tempo evapora. E é o mais pulado: &ldquo;ah, unit passou, manda pra CI&rdquo;. Aí cai em produção um bug que CI não pegou porque CI não cobre todo path possível.</p>
<p>Com MCP Playwright, o passo 3 vira:</p>
<blockquote>
  <p>3. <strong>Peço pra Claude testar:</strong> &ldquo;valida o fluxo de checkout com cupom no localhost:3000, me dá screenshots de cada etapa&rdquo;</p>

</blockquote>
<p>E a Claude abre o browser via MCP, navega, preenche, clica, verifica, tira screenshot de cada estado, reporta erro de console se houver. Você recebe: &ldquo;funcionou. Evidências em <code>/tmp/checkout-*.png</code>&rdquo;. Anexa as screenshots no PR. <strong>Reviewer humano abre o PR com prova visual na mão.</strong> CI continua rodando o suite completo, esse não muda. O que muda é o seu passo manual de teste local.</p>
<h3>Então isso não substitui meus testes E2E?<span class="hx:absolute hx:-mt-20" id="então-isso-não-substitui-meus-testes-e2e"></span>
    <a href="#ent%c3%a3o-isso-n%c3%a3o-substitui-meus-testes-e2e" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Não. E nem deveria. Seu E2E tradicional roda em CI sem precisar de IA, vive bem, valida regressão com determinismo. Esse é trabalho que engenheiro escreve uma vez e roda mil vezes. MCP Playwright é diferente: é o seu <strong>teste exploratório local</strong>, automatizado pela IA, com prova visual. É o passo que você fazia clicando, agora delegado.</p>
<h2>Cenário concreto: PO escreve, IA valida<span class="hx:absolute hx:-mt-20" id="cenário-concreto-po-escreve-ia-valida"></span>
    <a href="#cen%c3%a1rio-concreto-po-escreve-ia-valida" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Olha como isso vira fluxo real. Quinta de manhã, o PO escreve no Notion um cenário em Gherkin:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gherkin" data-lang="gherkin"><span class="line"><span class="cl"><span class="k">Funcionalidade:</span><span class="nf"> Checkout com cupom de desconto
</span></span></span><span class="line"><span class="cl"><span class="nf">  Como cliente
</span></span></span><span class="line"><span class="cl"><span class="nf">  Quero aplicar um cupom no checkout
</span></span></span><span class="line"><span class="cl"><span class="nf">  Para pagar menos no pedido
</span></span></span><span class="line"><span class="cl"><span class="nf">
</span></span></span><span class="line"><span class="cl"><span class="nf">  </span><span class="k">Cenário:</span><span class="nf"> Cupom válido aplica desconto
</span></span></span><span class="line"><span class="cl"><span class="k">    Dado </span><span class="nf">que estou na página de checkout
</span></span></span><span class="line"><span class="cl"><span class="nf">    </span><span class="k">E </span><span class="nf">meu carrinho tem </span><span class="s">2</span><span class="nf"> itens somando R$ </span><span class="s">200</span><span class="nf">
</span></span></span><span class="line"><span class="cl"><span class="nf">    </span><span class="k">Quando </span><span class="nf">eu insiro o cupom &#34;</span><span class="s">NEXTSIDE10</span><span class="nf">&#34; no campo de desconto
</span></span></span><span class="line"><span class="cl"><span class="nf">    </span><span class="k">E </span><span class="nf">clico em &#34;</span><span class="s">Aplicar</span><span class="nf">&#34;
</span></span></span><span class="line"><span class="cl"><span class="nf">    </span><span class="k">Então </span><span class="nf">o total deve cair para R$ </span><span class="s">180</span><span class="nf">
</span></span></span><span class="line"><span class="cl"><span class="nf">    </span><span class="k">E </span><span class="nf">uma mensagem &#34;</span><span class="s">Cupom aplicado: 10% off</span><span class="nf">&#34; deve aparecer
</span></span></span><span class="line"><span class="cl"><span class="nf">    </span><span class="k">E </span><span class="nf">o botão &#34;</span><span class="s">Finalizar pedido</span><span class="nf">&#34; deve continuar habilitado</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>A dev abre o terminal, e em vez de rodar o app e clicar ela mesma em cada passo pra confirmar que o cenário passa (aquele clique manual de pré-PR que todo mundo pula), passa pra IA:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>Valida o cenário Gherkin abaixo no app rodando em http://localhost:3000.
Use o MCP Playwright. Reporta cada Then com ✅ ou ❌ &#43; screenshot 
quando algo falhar. Não corrija o código: só audita.

&lt;cola o Gherkin aqui&gt;</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>A IA com MCP Playwright:</p>
<ol>
<li>Abre o browser em <code>http://localhost:3000/checkout</code></li>
<li>Valida que está na página de checkout (<code>networkidle</code> + <code>&lt;h1&gt;Checkout&lt;/h1&gt;</code> visível)</li>
<li>Lê o DOM e confirma 2 itens no carrinho somando R$ 200</li>
<li>Preenche o campo &ldquo;cupom&rdquo; com <code>NEXTSIDE10</code></li>
<li>Clica no botão &ldquo;Aplicar&rdquo;</li>
<li>Aguarda mudança no DOM (<code>expect(total).toContain('180')</code>)</li>
<li>Verifica visibilidade da mensagem &ldquo;Cupom aplicado: 10% off&rdquo;</li>
<li>Verifica que o botão &ldquo;Finalizar pedido&rdquo; continua <code>enabled</code></li>
</ol>
<p>Reporte de volta:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><pre><code>✅ Cenário: Cupom válido aplica desconto
  ✅ Dado: na página de checkout (h1 visível, URL correta)
  ✅ E: 2 itens, total R$ 200 (lido do .cart-total)
  ✅ Quando: cupom NEXTSIDE10 aplicado
  ✅ Então: total atualizou pra R$ 180
  ✅ E: mensagem de sucesso visível
  ❌ E: botão &#34;Finalizar pedido&#34; está DISABLED

Screenshot do estado final: /tmp/checkout-disabled-btn.png
Suspeita: regressão no cupom-success-handler que setou disabled=true 
por engano após aplicar desconto.</code></pre></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Tempo total: <strong>35 segundos</strong>. Sem teste E2E escrito, sem stub, sem mock. <strong>Validou contra o app de verdade, no seu localhost, antes do PR ir pra review.</strong></p>
<h3>Mas isso não substitui CI/CD com Playwright real?<span class="hx:absolute hx:-mt-20" id="mas-isso-não-substitui-cicd-com-playwright-real"></span>
    <a href="#mas-isso-n%c3%a3o-substitui-cicd-com-playwright-real" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Não substitui. CI/CD continua rodando o suite completo no PR. Esse fluxo é o <strong>pre-flight</strong>: antes de você abrir o PR, antes do CI gastar 6min, antes do reviewer humano abrir tab pra ver, você já sabe que o cenário do PO passa ou falha. A regressão acima (botão DISABLED por engano) é exatamente o tipo de bug que aparece em produção 2 sprints depois porque ninguém testou esse path manual.</p>
<p>O Gherkin do PO virou input executável. <strong>A documentação de aceitação virou teste de aceitação rodando.</strong> Sem ninguém escrever código de teste.</p>
<h2>O que muda vs teste E2E tradicional<span class="hx:absolute hx:-mt-20" id="o-que-muda-vs-teste-e2e-tradicional"></span>
    <a href="#o-que-muda-vs-teste-e2e-tradicional" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Aqui um ponto importante pra não confundir. MCP Playwright não substitui sua suíte E2E em CI. ABSOLUTAMENTE NÃO. Os dois resolvem coisas diferentes, e a confusão costuma nascer porque o nome &ldquo;Playwright&rdquo; aparece nos dois.</p>
<p>O E2E tradicional é o que o <strong>engenheiro escreve em código, versiona no repositório, e que o CI roda em todo PR automaticamente</strong>. Esse não muda. Esse continua lá.</p>
<p>MCP Playwright é o <strong>passo 3 do fluxo do dev</strong>: aquele clique manual que você fazia (ou pulava) antes de abrir o PR. Só que agora a IA faz no lugar de você.</p>
<p>E2E tradicional (Playwright spec rodando em CI):</p>
<ul>
<li><strong>Roda automático em todo PR</strong>: bloqueia merge se quebrar</li>
<li><strong>Especificado em código</strong>: assertion explícita, versionada, revisada</li>
<li><strong>Cobre regression suite inteira</strong>: não depende de você lembrar</li>
<li><strong>Lento</strong>: minutos por execução, exige infra de CI</li>
</ul>
<p>MCP Playwright no Claude local:</p>
<ul>
<li><strong>Roda quando você pede</strong>: não bloqueia nada por padrão</li>
<li><strong>Especificado em linguagem natural</strong>: flexível mas não versionado</li>
<li><strong>Cobre o que você descreve na hora</strong>: depende da instrução</li>
<li><strong>Rápido</strong>: segundos por execução, zero infra</li>
</ul>
<p>Caso de uso ideal: <strong>MCP Playwright é pra a primeira camada de validação, ANTES de você pedir review humano</strong>. É o sanity check que você faria com as mãos, automatizado. Não é a rede de segurança da CI. É o pré-voo.</p>
<p>Suíte E2E real continua sendo necessária pra:</p>
<ul>
<li>Regression bloqueante em PR</li>
<li>Cobertura crítica de fluxos de pagamento, auth, etc.</li>
<li>Documentação executável do comportamento esperado</li>
</ul>
<p>MCP Playwright é necessário pra:</p>
<ul>
<li>Sanity check rápido durante desenvolvimento</li>
<li>Validação visual de feature em mudança ativa</li>
<li>&ldquo;Será que quebrou algo?&rdquo; antes de pedir review</li>
</ul>
<p>São complementares, não rivais. Quem trocar suíte E2E por MCP Playwright vai sentir saudade quando der refactor grande e nada quebrar no CI mas tudo quebrar em produção.</p>
<h2>Limites e armadilhas<span class="hx:absolute hx:-mt-20" id="limites-e-armadilhas"></span>
    <a href="#limites-e-armadilhas" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Calma lá. Tem armadilha:</p>
<ul>
<li><strong>Não é determinístico como teste em código</strong>: você descreve &ldquo;valide o card&rdquo;, Claude interpreta. Duas execuções podem checar coisas levemente diferentes. Pra sanity check é OK. Pra regression bloqueante, não.</li>
<li><strong>Custo de tokens</strong>: cada screenshot consumido pelo Claude vira input. Em sessão longa, isso pesa. Cure o que você manda inspecionar.</li>
<li><strong>Falhas silenciosas</strong>: se Claude não enxergou algo, ele não reporta. Falso negativo. Você precisa instruir bem o que olhar.</li>
<li><strong>Setup do servidor MCP</strong>: instalar o MCP server local, configurar no Claude Code, garantir que browser tá disponível. Primeira vez leva tempo. Depois esquece.</li>
<li><strong>Local-only</strong>: MCP Playwright no Claude Code roda na sua máquina. Não é solução pra QA em ambiente compartilhado. Pra isso, ainda é Playwright tradicional em CI.</li>
</ul>
<p>E tem uma armadilha de cultura: <strong>dev vira preguiçoso em escrever teste real porque &ldquo;Claude testa pra mim&rdquo;</strong>. Isso é cilada. MCP Playwright complementa teste, não substitui. Quem usar como substituto vai aprender da pior maneira: quando a feature crítica quebrar em produção sem teste cobrindo.</p>
<blockquote>
  <p>&ldquo;Mas se MCP Playwright é tão bom, pra quê CI?&rdquo; Porque CI bloqueia o que humano esquece. MCP Playwright só roda se você pedir. CI roda sempre. O CI é o seguro, o MCP é o pré-voo. Tira o seguro, e na primeira batida você lembra.</p>

</blockquote>
<h2>O que isso diz sobre o futuro do QA local<span class="hx:absolute hx:-mt-20" id="o-que-isso-diz-sobre-o-futuro-do-qa-local"></span>
    <a href="#o-que-isso-diz-sobre-o-futuro-do-qa-local" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Aqui o ponto que importa.</p>
<p>Por muito tempo, validação local de frontend foi ruim. Você abria browser, abria DevTools, lembrava (ou não) de testar mobile, lembrava (ou não) de testar dark mode, lembrava (ou não) de checar console. Toda vez. Manualmente. Cansando.</p>
<p>Resultado: bug visual virava bug de produção. Não porque o dev é ruim, mas porque o cérebro humano não é máquina de checklist confiável depois de 4 horas de pair programming.</p>
<p>MCP Playwright muda esse jogo porque deixa o <strong>checklist virar código</strong> que outra entidade, a IA, executa por você. Você nunca mais esquece de testar dark mode. Você nunca mais comita sem ver o console. Não porque você ficou melhor, mas porque o processo agora roda sozinho. É a mesma lógica que aplicamos pra <a href="/posts/2026/05/16/adrs-decisao-no-notion-sem-burocracia/">documentar decisão técnica em ADRs no Notion</a>: tira da memória humana, bota num formato que sobrevive ao cansaço.</p>
<p>Isso é o que mais me empolga em MCP de modo geral: é a primeira vez que vejo automação de tarefas chatas com IA dando resultado REAL, não promessa. Playwright é só o exemplo mais maduro. Vai ter MCP server pra tudo que você odeia fazer mas precisa fazer. E quando dá pra avaliar tech nova em 2 semanas em vez de comprar a ideia inteira, <a href="https://nextside.tech/#discovery"target="_blank" rel="noopener">Discovery é o formato certo</a>: não precisa apostar 6 meses pra saber se MCP cabe no seu pipeline.</p>
<p>E o time que adotar primeiro vai ganhar consistência que time que não adotar nunca vai conseguir replicar com força de vontade.</p>
<p>Por isso a gente da Nextside roda MCP Playwright em todo agent de UX review. Não como gimmick de IA. Como <strong>forma de garantir que o checklist boring acontece toda vez, sem depender de eu lembrar às 23h de sexta</strong>.</p>
<p>A IA cansa menos que você. Use isso a seu favor.</p>
]]></content:encoded></item><item><title>Claude Code superpowers: o plugin que muda o time</title><link>https://blog.nextside.tech/posts/2026/05/16/claude-code-superpowers-plugin-na-pratica/</link><pubDate>Sat, 16 May 2026 11:00:00 -0300</pubDate><guid>https://blog.nextside.tech/posts/2026/05/16/claude-code-superpowers-plugin-na-pratica/</guid><dc:creator>Pablo Winter</dc:creator><category>claude-code</category><category>superpowers</category><category>ia</category><category>produtividade</category><category>skills</category><description>Superpowers do Claude Code não é mais um plugin de IA. É a forma de codificar conhecimento de time num lugar que a máquina lê e executa.</description><content:encoded><![CDATA[<p><strong>TL;DR:</strong> dá pra entregar software de qualidade só com Claude Code puro? Dá. Mas tem letra miúda.</p>
<p>A letra miúda é: depende do seu nível de senioridade pra cobrir o que a IA não cobre, e da metodologia que você consegue manter na cabeça. Pra 1-2 tarefas em paralelo, vibe coding com Claude Code resolve. Pra 5-6 tarefas simultâneas, onde a Nextside vive, a cabeça humana não aguenta. Aí entra metodologia codificada.</p>
<p>Superpowers é a metodologia codificada num plugin: skills, agents, slash commands, hooks. Em vez de você reinventar SDD (Spec-Driven Development) e harness engineering próprios, o que custa semanas de R&amp;D, você usa o que milhares de devs estão validando em paralelo. Bug fix do plugin chega pra você de graça. Feature nova chega pra você de graça. É open-source funcionando do jeito que open-source deveria.</p>
<p>Eu testei. A gente testou. Esse blog que você está lendo foi construído com Claude Code + superpowers do começo ao fim: design system, layouts Hugo, pipeline de agents, frontmatter, esse próprio post. E o que mais me chamou atenção não foi velocidade. Foi disciplina.</p>
<h2>Claude Code puro com Vibe Coding funciona, até quebrar<span class="hx:absolute hx:-mt-20" id="claude-code-puro-com-vibe-coding-funciona-até-quebrar"></span>
    <a href="#claude-code-puro-com-vibe-coding-funciona-at%c3%a9-quebrar" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O <a href="https://akitaonrails.com/2026/02/23/vibe-code-fiz-um-indexador-inteligente-de-imagens-com-ia-em-2-dias/"target="_blank" rel="noopener">Fabio Akita escreveu sobre Agile Vibe Coding</a> e tem razão. Você pode entregar feature inteira em 30min usando Claude Code puro, conversando com a IA, iterando rápido. Vibe.</p>
<p>E funciona. Pra 1 tarefa. Pra 2 tarefas.</p>
<h3>Então pra que o plugin?<span class="hx:absolute hx:-mt-20" id="então-pra-que-o-plugin"></span>
    <a href="#ent%c3%a3o-pra-que-o-plugin" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Porque o trabalho real da Nextside não é 1 tarefa. É 5. Às vezes 6.</p>
<p>Vibe coding com 1 contexto = produtivo. Vibe coding mudando de contexto a cada 15min = sua cabeça em pedaços às 17h, sem entregar nada sólido.</p>
<p>Quando o paralelismo entra, vibe não basta. Você precisa de:</p>
<ul>
<li><strong>Brainstorming forçado antes de codificar</strong>: pra não começar a tarefa errada</li>
<li><strong>Testes obrigatórios na hora do código</strong>: pra não voltar pra debugar em 2 dias</li>
<li><strong>Plano escrito por agent</strong>: pra você ler depois e lembrar onde estava</li>
<li><strong>UX-review automático</strong>: pra não esquecer de checar o resultado visual</li>
<li><strong>Skill com checklist</strong>: pra cada tipo de tarefa rodar do mesmo jeito</li>
</ul>
<p>Você pode construir tudo isso sozinho. Vai gastar 2-3 semanas, validar com seu time, debugar a primeira iteração. <strong>Ou usar o plugin superpowers que já tem isso, e ganhar features novas que outros engenheiros já validaram.</strong></p>
<p>Plugin não te tira a vibe. Tira a <strong>bagunça da paralelização</strong>. Continua sendo você no comando, só com guarda-corpo onde a fadiga humana já trairia o resultado.</p>
<h2>O que é superpowers, sem hype<span class="hx:absolute hx:-mt-20" id="o-que-é-superpowers-sem-hype"></span>
    <a href="#o-que-%c3%a9-superpowers-sem-hype" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Superpowers é um plugin pro Claude Code (claude.ai/code, a CLI da Anthropic) que adiciona três coisas concretas:</p>
<ul>
<li><strong>Skills</strong>: markdown files que descrevem &ldquo;como fazer X&rdquo;. Cada skill tem trigger (quando usar), passos (o que fazer), e regras (o que não esquecer). Claude lê a skill antes de executar a tarefa.</li>
<li><strong>Agents/Subagents</strong>: invocações especializadas. Você lança um &ldquo;subagent de revisão UX&rdquo; que tem contexto próprio, prompts próprios, e ferramentas próprias. Não polui contexto principal.</li>
<li><strong>Slash commands</strong>: atalhos que você digita (<code>/code-review</code>, <code>/ship</code>, <code>/init</code>) e disparam fluxos complexos. Cada um lê o repo, executa passos, e reporta.</li>
</ul>
<p>Soa parecido com prompts salvos? É. Mas a diferença não é o conteúdo: é o <strong>ritual</strong>. Skill enforced significa que o Claude lê a skill ANTES de começar a trabalhar. Não tem chance de pular o passo de TDD. Não tem chance de pular o checkpoint de brainstorming. A skill é gatilho automático.</p>
<p>E é aí que mora a virada.</p>
<h2>Como muda o fluxo de trabalho real<span class="hx:absolute hx:-mt-20" id="como-muda-o-fluxo-de-trabalho-real"></span>
    <a href="#como-muda-o-fluxo-de-trabalho-real" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Sem superpowers, Claude Code é IA generalista boa. Você abre, descreve a tarefa, ele tenta resolver. Se você esquecer de pedir teste, ele não escreve teste. Se você esquecer de pedir brainstorming antes de codar, ele já parte pra implementação. Resultado: muito código gerado, muito código jogado fora.</p>
<p>Com superpowers, o jogo é outro:</p>
<ul>
<li><strong>TDD enforced</strong>: skill <code>test-driven-development</code> força Claude a escrever teste falhando ANTES de escrever implementação. Sempre. Pra todo bugfix, pra toda feature. Não negocia.</li>
<li><strong>Brainstorming antes de código</strong>: skill <code>brainstorming</code> exige que, antes de qualquer trabalho criativo, Claude explore o problema com o usuário. Faz perguntas. Lista alternativas. Só depois propõe solução.</li>
<li><strong>Systematic debugging</strong>: encontrou bug? Skill <code>systematic-debugging</code> força investigação metódica em vez de chute. Primeira hipótese não é a aposta. É o ponto de partida da árvore de causas.</li>
<li><strong>Verification before completion</strong>: Claude não pode dizer &ldquo;feito&rdquo; sem rodar verificação. Roda os testes, mostra output, depois afirma. Adeus &ldquo;deve funcionar&rdquo;.</li>
</ul>
<p>Notem o padrão: cada skill é uma forma de codificar disciplina de engenharia sênior. O que devs experientes fazem por hábito (TDD, brainstorming antes de código, debug metódico, verificar antes de afirmar) vira regra que a máquina executa.</p>
<p>E aqui mora o ponto: <strong>isso não é sobre dar superpoder pra IA. É sobre dar a IA o conjunto de hábitos do seu melhor dev sênior.</strong></p>
<h2>Como a Nextside usou pra construir o próprio blog<span class="hx:absolute hx:-mt-20" id="como-a-nextside-usou-pra-construir-o-próprio-blog"></span>
    <a href="#como-a-nextside-usou-pra-construir-o-pr%c3%b3prio-blog" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>A gente da Nextside montou esse blog (<code>blog.nextside.tech</code>) usando Claude Code + superpowers. Stack: Hugo + tema Hextra, design system próprio em CSS, pipeline editorial de agents, bilíngue pt-BR/EN.</p>
<p>Fluxo típico de uma feature do design system:</p>
<ol>
<li><strong>Brainstorming session</strong>: eu descrevo &ldquo;preciso de hover state pro card de post&rdquo;. Claude (via skill brainstorming) faz 3-4 perguntas: &ldquo;ember glow ou só elevation?&rdquo;, &ldquo;mobile também ou só desktop?&rdquo;, &ldquo;comportamento em dark mode?&rdquo;. Só depois disso propõe abordagem.</li>
<li><strong>Plano escrito</strong>: skill <code>writing-plans</code> força Claude a escrever plano detalhado antes de codar. Plano vai pra um arquivo de spec. Eu reviso. Aprovo ou peço ajuste.</li>
<li><strong>Execução com TDD</strong>: skill <code>executing-plans</code> segue o plano. Cada passo do plano vira checkpoint. Skill TDD força teste antes de código (quando aplicável: em CSS puro, vira verificação visual).</li>
<li><strong>UX review automática</strong>: antes do commit, lança um <a href="/posts/2026/05/16/mcp-playwright-validacao-local-com-qualidade/">agent dedicado de revisão UX que abre o site no browser via MCP Playwright</a>, navega, tira screenshot, e flagra problema.</li>
<li><strong>Commit + push</strong>: só depois de tudo verde.</li>
</ol>
<p>Notem: zero &ldquo;vibe coding&rdquo; desorganizado. Zero &ldquo;deixa eu tentar uma coisa&rdquo;. Zero &ldquo;deve funcionar&rdquo;. É um pipeline.</p>
<p>E o resultado vem porque o pipeline é repetível. A próxima feature passa pelos mesmos checkpoints. A skill é a mesma. O agent é o mesmo. Não depende da minha memória de &ldquo;o que eu pedi da última vez&rdquo;.</p>
<p>Isso é o que muda em time. Quando o conhecimento tá codificado em skill, qualquer dev do time invoca o mesmo Claude e ganha o mesmo padrão. Não tem dev &ldquo;que sabe usar Claude bem&rdquo; e dev &ldquo;que não sabe&rdquo;. O conhecimento mora no plugin.</p>
<h2>O que melhora vs Claude Code puro<span class="hx:absolute hx:-mt-20" id="o-que-melhora-vs-claude-code-puro"></span>
    <a href="#o-que-melhora-vs-claude-code-puro" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Diferença concreta de antes e depois:</p>
<ul>
<li><strong>Velocidade real (não percebida)</strong>: Claude puro entrega rápido demais. Você acha que economizou tempo, mas gastou 2h refazendo. Com superpowers, primeira entrega leva um pouco mais, porque tem brainstorming, plano, TDD, mas é a entrega que fica.</li>
<li><strong>Menos slop</strong>: slop é código gerado que parece certo mas tá errado. Sem superpowers, slop aparece direto. Com superpowers, o verification step pega antes do commit.</li>
<li><strong>Reprodutibilidade</strong>: outro dev do time invoca o mesmo <code>/code-review</code> e ganha review com critérios idênticos aos meus. Não depende do prompt que eu escrevi às 3 da manhã num sábado.</li>
<li><strong>Onboarding mais rápido</strong>: dev novo no time não precisa decorar processo. Ele instala superpowers, lê o catálogo de skills e slash commands, e já trabalha como o time trabalha.</li>
</ul>
<p>A última é a que mais me surpreendeu. Eu sempre achei que &ldquo;processo de time&rdquo; era doc no Notion. Vira que não: é skill no Claude. Doc no Notion ninguém lê. Skill no Claude executa toda vez que a tarefa começa.</p>
<p>Isso é importante: <strong>doc de processo é ficção. Skill executada é processo de verdade.</strong></p>
<h2>Limites honestos (não é mágica)<span class="hx:absolute hx:-mt-20" id="limites-honestos-não-é-mágica"></span>
    <a href="#limites-honestos-n%c3%a3o-%c3%a9-m%c3%a1gica" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Calma lá. Superpowers não resolve tudo:</p>
<ul>
<li><strong>Não substitui dev sênior</strong>: substitui o trabalho braçal do dev sênior. As decisões arquiteturais reais ainda exigem humano no loop. Quem escolhe stack, quem decide trade-off de performance vs DX, quem faz call de produto, é gente.</li>
<li><strong>Slip pode escapar</strong>: verification step não é onisciente. Se o teste tá errado, o &ldquo;tudo verde&rdquo; é falso positivo. Você ainda precisa olhar.</li>
<li><strong>Custo de contexto</strong>: skills enchem o contexto inicial. Se você tem 30 skills carregadas e o repo é gigante, performance cai. Tem que curar skill ativa.</li>
<li><strong>Aprende mal sozinho</strong>: superpowers não evolui sozinho. Se um padrão do time muda, alguém tem que atualizar a skill. Sem manutenção, ela vira obsoleta, e aí a IA executa processo velho com convicção.</li>
</ul>
<p>E o ponto crítico: <strong>superpowers é alavanca, não autopilot</strong>. Você ainda precisa pensar. Você precisa revisar o plano que Claude escreveu. Você precisa decidir quando a brainstorming session já durou demais. A skill é régua, mas você é quem segura a régua.</p>
<blockquote>
  <p>&ldquo;Mas se a IA faz tudo, qual é o papel do dev?&rdquo; Boa pergunta. Resposta: o dev vira <strong>arquiteto + revisor + ditador de gosto</strong>. Não digita mais boilerplate. Decide o quê, revisa o como, e ajusta o tom. É papel mais sênior, não menos.</p>

</blockquote>
<h2>O que esse plugin diz sobre o futuro do trabalho<span class="hx:absolute hx:-mt-20" id="o-que-esse-plugin-diz-sobre-o-futuro-do-trabalho"></span>
    <a href="#o-que-esse-plugin-diz-sobre-o-futuro-do-trabalho" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Aqui o ponto que mais importa.</p>
<p>Por anos, processo de time foi documento. <a href="/posts/2026/05/16/adrs-decisao-no-notion-sem-burocracia/">ADR no Notion</a>. Checklist no Confluence. Playbook no Google Doc. Tudo passivo. Tudo ignorado depois da segunda semana.</p>
<p>Superpowers muda isso porque transforma processo em <strong>código executável pela IA</strong>. A skill não é doc: é instrução que dispara toda vez que a tarefa começa. Ninguém precisa lembrar de &ldquo;rodar o playbook&rdquo;. A IA roda sozinha.</p>
<p>Isso tem implicação grande: o conhecimento de engenharia que ficava nas cabeças dos seniores agora cabe num markdown que outro membro do time invoca via slash command. <strong>Conhecimento codificado</strong>, executado por máquina, escalado pra todo time.</p>
<p>Não é mágica. Não substitui senioridade. Mas é a primeira vez que eu vejo &ldquo;processo de time&rdquo; sair do papel e virar comportamento real e repetível, sem depender de alguém policiar.</p>
<p>E isso muda jogo. Ponto.</p>
<p>Por isso a gente da Nextside roda Claude Code + superpowers em <a href="https://nextside.tech/#sprint"target="_blank" rel="noopener">todo Sprint de 4 semanas</a>. Não como ferramenta de produtividade. Como <strong>forma de garantir que o jeito Nextside de trabalhar acontece toda vez, sem precisar do humano lembrar</strong>.</p>
<p>Quem documenta processo em PDF tá lutando guerra antiga. Quem codifica processo em skill tá entregando enquanto o outro escreve playbook.</p>
]]></content:encoded></item><item><title>ADRs no Notion, sem burocracia</title><link>https://blog.nextside.tech/posts/2026/05/16/adrs-decisao-no-notion-sem-burocracia/</link><pubDate>Sat, 16 May 2026 10:00:00 -0300</pubDate><guid>https://blog.nextside.tech/posts/2026/05/16/adrs-decisao-no-notion-sem-burocracia/</guid><dc:creator>Pablo Winter</dc:creator><category>adr</category><category>decisao-tecnica</category><category>notion</category><category>processo</category><category>time-pequeno</category><category>claude-code</category><description>ADR não é cerimônia corporativa. É a forma mais barata de não repetir burrice, e de fazer Claude Code consultar suas decisões antes de codar.</description><content:encoded><![CDATA[<p>Toda vez que alguém fala &ldquo;ADR&rdquo; numa reunião, metade do time pensa em planilha do Sharepoint, comitê de arquitetura e documento de 14 páginas que ninguém lê. Eu também pensava. E aí qual é a pergunta real: ADR vale a pena pra time pequeno? Resposta curta: vale, mas não do jeito que o livro diz.</p>
<p><dfn>ADR: Architecture Decision Record</dfn> é registro de decisão técnica. Curto. Datado. Imutável. Você decide algo importante hoje, escreve por que decidiu, e daqui a 6 meses quando alguém perguntar &ldquo;por que diabos a gente escolheu Postgres em vez de Mongo?&rdquo;, a resposta tá lá. Sem ter que reconvocar a reunião perdida no calendário de fevereiro.</p>
<p>O ponto não é o template. O ponto é não perder história.</p>
<h2>Por que a maioria dos times falha em ADR<span class="hx:absolute hx:-mt-20" id="por-que-a-maioria-dos-times-falha-em-adr"></span>
    <a href="#por-que-a-maioria-dos-times-falha-em-adr" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>A maioria dos times que tenta adotar ADR copia o template do Michael Nygard (ou o do AWS prescriptive guidance, ou o do ThoughtWorks) na primeira semana, escreve 3 ADRs em 4 dias, e abandona no quinto. Eu já fiz isso. Time pequeno tem zero paciência pra ritual.</p>
<p>O problema é simples: o template tradicional tem 6 seções (Context, Decision, Status, Consequences, Alternatives Considered, Stakeholders). Em time de 4 pessoas com prazo apertado, ninguém escreve &ldquo;Alternatives Considered&rdquo; com bullet points. Ninguém. Você abre o doc, olha pra 6 headers vazios, fecha o doc, e volta pro código.</p>
<p>Resultado: o ADR vira piada. &ldquo;Cara, lembra quando a gente ia documentar decisões? Bons tempos.&rdquo;</p>
<blockquote>
  <p>&ldquo;Mas se vocês não documentam direito, como mantêm histórico?&rdquo; Pergunta justa. Resposta: a gente documenta SIM, só que num formato que cabe em time pequeno. Não no formato que cabe num livro de arquitetura corporativa.</p>

</blockquote>
<p>E é aí que mora a diferença. ADR de time pequeno não é &ldquo;Architecture Decision Record&rdquo; no sentido pomposo. É <strong>bilhete pro seu eu do futuro</strong>. Você está escrevendo pra você daqui a 4 meses, que esqueceu por que escolheu Redis em vez de Memcached. Isso é tudo.</p>
<h2>Como a gente da Nextside faz no Notion<span class="hx:absolute hx:-mt-20" id="como-a-gente-da-nextside-faz-no-notion"></span>
    <a href="#como-a-gente-da-nextside-faz-no-notion" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Não tem repo separado pra ADRs. Não tem <code>docs/adr/0001-use-postgres.md</code>. Tem uma database no Notion chamada <code>Decisões</code>. Schema bobo:</p>
<ul>
<li><strong>Title</strong>: frase declarativa curta: &ldquo;Usar Postgres como banco principal&rdquo;, &ldquo;Adotar Hugo em vez de Next pro blog&rdquo;</li>
<li><strong>Status</strong>: Proposta / Aceita / Substituída / Descartada</li>
<li><strong>Data</strong>: quando foi decidida</li>
<li><strong>Tags</strong>: área (backend, frontend, infra, processo)</li>
<li><strong>Body</strong>: 3 seções: <strong>Contexto</strong> (1-3 parágrafos), <strong>Decisão</strong> (1 parágrafo seco), <strong>Consequências</strong> (bullets curtos: o que ganhamos, o que perdemos)</li>
</ul>
<p>E só.</p>
<p>Notem o que NÃO tem: &ldquo;Stakeholders&rdquo;, &ldquo;Voting&rdquo;, &ldquo;Alternatives Considered&rdquo; formalizado. Se as alternativas importam, viram parágrafo no Contexto. Se não importam, não viram nada. O critério é simples: <strong>o ADR existe pra alguém entender a decisão daqui a 6 meses, não pra defender em auditoria</strong>.</p>
<p>A regra de ouro que a gente segue: <strong>se você decidiu algo que vai ser caro reverter, escreve um ADR</strong>. Se vai dar pra reverter num PR de 50 linhas, não escreve nada. Documentar tudo é o mesmo que documentar nada: vira ruído.</p>
<h2>Exemplo concreto (decisão real-ish)<span class="hx:absolute hx:-mt-20" id="exemplo-concreto-decisão-real-ish"></span>
    <a href="#exemplo-concreto-decis%c3%a3o-real-ish" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Cenário típico: time precisa decidir entre dois ORMs num projeto Node novo. Prisma vs Drizzle. Discussão dura 40 minutos no Slack. Alguém abre o Notion e escreve:</p>
<blockquote>
  <p><strong>Título:</strong> Usar Drizzle como ORM no projeto X</p>
<p><strong>Status:</strong> Aceita</p>
<p><strong>Data:</strong> 2026-04-12</p>
<p><strong>Contexto:</strong> Projeto X precisa de ORM com bom suporte a TypeScript, migrations versionadas e performance previsível em query analytics. Avaliamos Prisma (mais maduro, melhor DX, mas runtime engine em Rust pesa cold-start em serverless) e Drizzle (mais novo, zero-cost abstraction, SQL-first). Time já tem familiaridade com SQL puro.</p>
<p><strong>Decisão:</strong> Adotar Drizzle. SQL-first encaixa no perfil do time, cold-start em serverless é problema concreto pra esse projeto, e a curva de aprendizado é menor que o ganho de DX do Prisma.</p>
<p><strong>Consequências:</strong></p>
<ul>
<li>Ganhamos cold-start mais rápido em Vercel/AWS Lambda</li>
<li>Perdemos algumas features avançadas que Prisma tem out-of-the-box (Prisma Studio, melhor introspection)</li>
<li>Migrations ficam mais manuais: exige disciplina maior do time</li>
<li>Se ferrar, dá pra migrar pra Prisma. Drizzle é fininho, sem lock-in pesado</li>
</ul>

</blockquote>
<p>Pronto. 180 palavras. 4 minutos pra escrever. Daqui a 6 meses, quando um dev novo chegar e perguntar &ldquo;por que Drizzle?&rdquo;, a resposta tá ali, datada, com contexto.</p>
<p>Isso é todo o segredo. Não tem mágica.</p>
<h2>O que acontece quando você NÃO faz isso<span class="hx:absolute hx:-mt-20" id="o-que-acontece-quando-você-não-faz-isso"></span>
    <a href="#o-que-acontece-quando-voc%c3%aa-n%c3%a3o-faz-isso" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O que acontece é o que eu chamo de <strong>history losing</strong>. Decisão tomada, ninguém anotou, 6 meses depois o time inteiro esqueceu. Aí surge a tentação de revisitar a decisão. &ldquo;Cara, será que a gente devia ter usado Prisma?&rdquo; Discussão de 40 minutos. De novo. As mesmas 4 pessoas. Com mais ou menos os mesmos argumentos. Conclusão idêntica.</p>
<p>Você acabou de pagar o preço da decisão DUAS VEZES.</p>
<p>Pior: às vezes a conclusão é diferente, porque alguém esqueceu o argumento crítico que pesou da primeira vez. Aí o time muda de Drizzle pra Prisma, refatora tudo, e 3 meses depois bate no mesmo problema de cold-start que motivou Drizzle originalmente. Voltamos pra Drizzle. Mais 3 meses queimados.</p>
<p>Isso é a pior coisa que pode acontecer em time pequeno: <strong>repetir burrice porque ninguém anotou a burrice anterior</strong>. Empresa grande aguenta. Time de 4 pessoas, não.</p>
<p><strong>Memória institucional num time pequeno não é Confluence. É hábito.</strong></p>
<p>ADR não substitui conversa. Não substitui pair programming. Não substitui <a href="https://nextside.tech/#discovery"target="_blank" rel="noopener">RFC pra coisa grande, que cabe melhor num Discovery dedicado</a>. Mas substitui o &ldquo;espera, deixa eu lembrar por que a gente decidiu isso&hellip;&rdquo;. E esse &ldquo;espera, deixa eu lembrar&rdquo; custa mais caro do que parece. Custa contexto interrompido, custa retrabalho, e custa confiança no histórico do time.</p>
<blockquote>
  <p>&ldquo;Mas ninguém vai voltar ler ADR depois!&rdquo; Vão sim. Eu volto. Toda vez que entro num projeto antigo e me pergunto &ldquo;por quê?&rdquo;. O ADR é o atalho pro porquê. Sem ele, atalho some.</p>

</blockquote>
<h2>Como começar amanhã (sem virar processo pesado)<span class="hx:absolute hx:-mt-20" id="como-começar-amanhã-sem-virar-processo-pesado"></span>
    <a href="#como-come%c3%a7ar-amanh%c3%a3-sem-virar-processo-pesado" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Se você nunca teve ADR no time e quer começar, três passos:</p>
<ul>
<li><strong>Cria uma database no Notion (ou Linear, ou Trello, ou um diretório <code>docs/decisoes/</code> no monorepo)</strong>. Não importa a ferramenta. Importa ter UM lugar.</li>
<li><strong>Define a regra de gatilho</strong>: qualquer decisão que custaria 1+ dia pra reverter merece ADR. Decisão de framework, banco, padrão de auth, escolha de fila, padrão de erro. Decisão de naming de variável NÃO precisa.</li>
<li><strong>Bota gatilho no PR template</strong>: pergunta opcional no template: &ldquo;Essa PR introduz decisão arquitetural? Se sim, link do ADR&rdquo;. Soft enforcement. Sem isso, o hábito morre na segunda semana.</li>
</ul>
<p>Em 3 meses, o time tem 10-15 ADRs. Em 1 ano, 30-40. Não é volume. É <strong>densidade de contexto</strong>. Cada ADR é um sinal claro de &ldquo;aqui tomamos uma decisão que importava&rdquo;.</p>
<p>E aqui mora o detalhe que ninguém fala: o valor real do ADR não tá no documento. Tá no <strong>ato de escrever</strong>. Quando você senta pra explicar a decisão em 3 parágrafos, você descobre que metade da decisão tava implícita e mal formada. O ADR força clareza. É o pair-programming da decisão técnica.</p>
<p>Quem quiser ir além e <a href="/posts/2026/05/16/claude-code-superpowers-plugin-na-pratica/">codificar o processo em skill que a IA executa</a>, pra que o ato de escrever ADR vire gatilho automático, esse é o próximo passo natural. Mas começa pelo hábito humano. Skill sem hábito por trás é teatro.</p>
<p>Por isso eu nem ligo se ninguém ler depois. Já valeu pelo ato de escrever.</p>
<h2>INDEX dos ADRs: o ponto que ninguém ainda fala<span class="hx:absolute hx:-mt-20" id="index-dos-adrs-o-ponto-que-ninguém-ainda-fala"></span>
    <a href="#index-dos-adrs-o-ponto-que-ningu%c3%a9m-ainda-fala" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Aqui vai a parte que mudou pra mim em 2026.</p>
<p>ADR é ótimo pro humano. Sócio entra no time, abre <code>docs/adr/0042-prisma-vs-sequelize.md</code>, entende a decisão em 5min. Bom.</p>
<p>Mas agora a IA também lê seu repo. E ela precisa de <strong>índice</strong>, não de busca por força bruta.</p>
<h3>Mas a IA não consegue só grep no diretório?<span class="hx:absolute hx:-mt-20" id="mas-a-ia-não-consegue-só-grep-no-diretório"></span>
    <a href="#mas-a-ia-n%c3%a3o-consegue-s%c3%b3-grep-no-diret%c3%b3rio" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Consegue. E enche o contexto com 47 ADRs irrelevantes pra responder uma pergunta. Custa token, custa qualidade, custa tempo.</p>
<p>A solução veio do próprio Claude Code: o sistema de auto-memória dele usa um arquivo <code>MEMORY.md</code> que é só <strong>index</strong>: cada linha aponta pra um arquivo de memória detalhado com uma descrição de 1 linha. Quando o Claude precisa decidir algo, ele lê o <code>MEMORY.md</code> (200 linhas máximo), escolhe a memória relevante, e só aí abre o arquivo detalhado.</p>
<p>O paralelo pra ADRs é exato. No nosso Notion (ou em <code>docs/adr/INDEX.md</code> se você usa repo), faz uma página <code>INDEX</code> no mesmo nível dos ADRs:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl"><span class="k">-</span> [<span class="nt">ADR-0042 Prisma sobre Sequelize</span>](<span class="na">./0042-prisma-vs-sequelize.md</span>): Postgres com tipagem forte; rejeita Sequelize por dor de migração
</span></span><span class="line"><span class="cl"><span class="k">-</span> [<span class="nt">ADR-0043 Server Components no Next 15</span>](<span class="na">./0043-rsc-next-15.md</span>): Default; só &#34;use client&#34; onde tem interação real
</span></span><span class="line"><span class="cl">- [<span class="nt">ADR-0044 Sem Redux</span>](<span class="na">./0044-sem-redux.md</span>): Zustand pra estado global pequeno; URL state pro resto</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Uma linha por ADR. Descrição que cabe em search.</p>
<p>Agora o Claude (ou qualquer outra IA) chega no seu repo, lê o <code>INDEX.md</code> em 2s, decide quais 2-3 ADRs são relevantes pro problema em mãos, e carrega só esses no contexto. <strong>A diferença entre 3 ADRs lidos e 47 é a diferença entre IA útil e IA confusa.</strong></p>
<p>E o melhor: você ganha o índice de graça. Humano novo também usa. Sem custo adicional.</p>
<p>Sem INDEX, seus ADRs viram cemitério de documentação ótima que ninguém lê: nem humano, nem IA.</p>
<h2>Configurando ADRs no seu Claude<span class="hx:absolute hx:-mt-20" id="configurando-adrs-no-seu-claude"></span>
    <a href="#configurando-adrs-no-seu-claude" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Tem o INDEX. Humano usa. Ótimo. Mas o pulo do gato é fazer <strong>a IA usar do jeito certo, sem você lembrar de mandar</strong>.</p>
<p>Esse blog roda em Claude Code + superpowers. Quando a gente executa <a href="/posts/2026/05/16/claude-code-superpowers-plugin-na-pratica/">um spec do superpowers, a skill que força brainstorming, plano escrito, TDD, verification</a>, decisões arquiteturais aparecem naturalmente no meio do caminho. &ldquo;Vai ser Drizzle ou Prisma?&rdquo; &ldquo;Server Component default?&rdquo; Cada uma é candidata a ADR.</p>
<p>Mas IA esquece.</p>
<p>Pede pra anotar uma vez, ela anota. Próxima sessão, esqueceu. Por isso a anotação precisa virar <strong>instrução de sistema</strong>, não pedido.</p>
<h3>CLAUDE.md aponta pra ADR (e pro INDEX)<span class="hx:absolute hx:-mt-20" id="claudemd-aponta-pra-adr-e-pro-index"></span>
    <a href="#claudemd-aponta-pra-adr-e-pro-index" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Claude Code carrega um arquivo <code>CLAUDE.md</code> na raiz do projeto em TODA sessão. É a memória padrão do projeto, o equivalente em IA do &ldquo;leia isso antes de tudo&rdquo;. Você não manda. Ela lê sozinha.</p>
<p>Lá embaixo, sem ritual:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl"><span class="gu">## Architecture Decision Records
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Consulte <span class="sb">`docs/adr/INDEX.md`</span> antes de tomar qualquer decisão técnica significativa.
</span></span><span class="line"><span class="cl"><span class="k">-</span> Se uma ADR existente cobre o assunto, siga.
</span></span><span class="line"><span class="cl"><span class="k">-</span> Se a decisão é nova e cara de reverter, proponha nova ADR ao final do plano.
</span></span><span class="line"><span class="cl">- Toda nova ADR entra no INDEX no mesmo PR.</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Pronto. 4 linhas. A IA passa a consultar o INDEX sempre que entra em modo de planejamento.</p>
<p>O detalhe que importa: não enche o CLAUDE.md com 47 ADRs in-line. Aponta pro INDEX. CLAUDE.md é carregado em TODA sessão: cada token gasto ali rouba contexto de coisa útil. Mantém leve. Aponta. Confia no INDEX pra fazer o resto.</p>
<h3>E se a IA ignorar a instrução?<span class="hx:absolute hx:-mt-20" id="e-se-a-ia-ignorar-a-instrução"></span>
    <a href="#e-se-a-ia-ignorar-a-instru%c3%a7%c3%a3o" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Vai ignorar uma ou outra vez, sim. Por isso entra o segundo pilar.</p>
<h3>Slash command <code>/adr</code> pra forçar o ritual<span class="hx:absolute hx:-mt-20" id="slash-command-adr-pra-forçar-o-ritual"></span>
    <a href="#slash-command-adr-pra-for%c3%a7ar-o-ritual" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>CLAUDE.md é leitura passiva: a IA usa se lembrar. Slash command é ATIVO: você dispara, ela executa. No Claude Code, basta criar <code>.claude/commands/adr.md</code> no repo:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">Planeje uma nova tarefa:
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">-</span> Leia <span class="sb">`docs/adr/INDEX.md`</span> e identifique ADRs relevantes a: $ARGUMENTS
</span></span><span class="line"><span class="cl"><span class="k">-</span> Carregue só os ADRs relevantes no contexto (não todos)
</span></span><span class="line"><span class="cl"><span class="k">-</span> Se a tarefa introduz decisão arquitetural NOVA, proponha rascunho de ADR antes do plano técnico
</span></span><span class="line"><span class="cl"><span class="k">-</span> Se a tarefa muda ou supersede ADR existente, sinalize explicitamente
</span></span><span class="line"><span class="cl">- Toda ADR nova precisa ser confirmada por mim antes de virar arquivo em <span class="sb">`docs/adr/`</span></span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Daí o fluxo diário vira:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">/adr Migrar autenticação de JWT pra session cookie</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>Claude lê o INDEX, identifica a ADR-0023 (que escolheu JWT originalmente), carrega só ela, e propõe ADR-0044 supersedindo. Você revisa. Aprova. Vai pra implementação.</p>
<p>Sem <code>/adr</code>, você dependeria de lembrar de mandar a IA consultar histórico. Com <code>/adr</code>, o ritual está no slash command. <strong>A IA não pula. Você não esquece.</strong></p>
<h3>Integrando com superpowers<span class="hx:absolute hx:-mt-20" id="integrando-com-superpowers"></span>
    <a href="#integrando-com-superpowers" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>E aqui mora a beleza. Se você já roda superpowers, a skill <code>writing-plans</code> força plano escrito antes de código. A skill <code>brainstorming</code> força exploração antes de implementação. Encaixar ADR nesse fluxo é uma linha no <code>CLAUDE.md</code>:</p>
<div class="hextra-code-block hx:relative hx:mt-6 hx:first:mt-0 hx:group/code">

<div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl"><span class="gu">## Regras invioláveis
</span></span></span><span class="line"><span class="cl"><span class="k">-</span> Todo plano gerado pela skill <span class="sb">`writing-plans`</span> referencia ADRs relevantes no início.
</span></span><span class="line"><span class="cl">- Toda decisão arquitetural detectada por <span class="sb">`brainstorming`</span> vira candidata a ADR. Propõe rascunho ao usuário.</span></span></code></pre></div></div><div class="hextra-code-copy-btn-container hx:opacity-0 hx:transition hx:group-hover/code:opacity-100 hx:flex hx:gap-1 hx:absolute hx:m-[11px] hx:right-0 hx:top-0">
  <button
    class="hextra-code-copy-btn hx:group/copybtn hx:cursor-pointer hx:transition-all hx:active:opacity-50 hx:bg-primary-700/5 hx:border hx:border-black/5 hx:text-gray-600 hx:hover:text-gray-900 hx:rounded-md hx:p-1.5 hx:dark:bg-primary-300/10 hx:dark:border-white/10 hx:dark:text-gray-400 hx:dark:hover:text-gray-50"
    title="Copy code"
  >
    <div class="hextra-copy-icon hx:group-[.copied]/copybtn:hidden hx:pointer-events-none hx:h-4 hx:w-4"></div>
<div class="hextra-success-icon hx:hidden hx:group-[.copied]/copybtn:block hx:pointer-events-none hx:h-4 hx:w-4"></div>
  </button>
</div>
</div>
<p>A skill superpowers já tem o gatilho de &ldquo;antes de codar, planeje&rdquo;. Agora o plano sai com ADRs citados. E decisão nova já sai com rascunho de ADR pronto pro humano aprovar.</p>
<p>ADR deixa de ser tarefa separada que você esquece. Vira <strong>subproduto natural do fluxo de spec → plano → código</strong>. Vem de graça.</p>
<h3>Onde colocar o quê<span class="hx:absolute hx:-mt-20" id="onde-colocar-o-quê"></span>
    <a href="#onde-colocar-o-qu%c3%aa" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><p>Claude Code carrega <code>CLAUDE.md</code> em três níveis: global (<code>~/.claude/CLAUDE.md</code>), projeto (<code>./CLAUDE.md</code>) e subdiretório (<code>./modulo/CLAUDE.md</code>). Mais específico ganha de mais geral.</p>
<p>Pra ADR, a regra que eu uso:</p>
<ul>
<li><strong>Global</strong>: nada de ADR aqui. Suas convenções pessoais de código, sim. ADR é do time, não seu.</li>
<li><strong>Projeto</strong>: referencia <code>docs/adr/INDEX.md</code>. Lista as 3-5 ADRs mais críticas (banco, framework, padrão de auth) explicitamente, pra IA não precisar abrir o INDEX em 90% dos casos.</li>
<li><strong>Subdiretório</strong>: só se um módulo tem decisões que só valem ali. Raro. Não force.</li>
</ul>
<p>Maioria dos times só precisa do nível projeto. Não complica.</p>
<h3>Três armadilhas<span class="hx:absolute hx:-mt-20" id="três-armadilhas"></span>
    <a href="#tr%c3%aas-armadilhas" class="subheading-anchor" aria-label="Permalink for this section"></a></h3><ul>
<li><strong>Não cole ADRs in-line no CLAUDE.md</strong>. Vira arquivo de 800 linhas, performance da IA cai, e você perdeu o ganho do INDEX.</li>
<li><strong>Não deixe a IA escrever ADR sozinha sem aprovação humana</strong>. ADR é decisão. Decisão exige humano. IA propõe rascunho, humano aprova. Sempre.</li>
<li><strong>Não esqueça de atualizar o INDEX quando criar ADR nova</strong>. O INDEX é o contrato. Se a ADR existe mas não tá no INDEX, ela não existe pra IA.</li>
</ul>
<p>Skill sem ritual humano é teatro. Ritual humano sem skill é fadiga. Os dois juntos é como ADR fica vivo num time pequeno usando IA pesada.</p>
<h2>O que o ADR realmente protege<span class="hx:absolute hx:-mt-20" id="o-que-o-adr-realmente-protege"></span>
    <a href="#o-que-o-adr-realmente-protege" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>O ADR não protege você de tomar decisão errada. ABSOLUTAMENTE NÃO. Você vai tomar decisão errada de qualquer jeito. Todo time toma. O ADR protege você de tomar a MESMA decisão errada duas vezes. Que é coisa diferente.</p>
<p>Time bom não é o time que acerta sempre. É o time que erra menos a cada iteração. ADR é o registro que permite saber qual erro você cometeu e por quê, pra não cometer outra vez na próxima decisão parecida. É o equivalente, em decisão de produto, da <a href="/posts/2026/05/16/mcp-playwright-validacao-local-com-qualidade/">validação local com qualidade real que a gente faz via MCP Playwright em frontend</a>: você não previne todo erro, mas garante que erros viram aprendizado registrado.</p>
<p>Em time pequeno, a margem pra repetir burrice é zero. Cada semana queimada em decisão refeita é semana que você não tinha. Discovery, MVP, refatoração: não tem folga.</p>
<p>Por isso a gente da Nextside escreve ADR no Notion. Curto. Datado. Honesto. Sem template gigante. Sem cerimônia. Sem reunião extra.</p>
<p>ADR não é para impressionar auditor. É para o time. E o time é pequeno. E o tempo é curto.</p>
<p>Quem não anota a história, repete a história. E repetir burrice é o luxo que time pequeno não pode pagar.</p>
]]></content:encoded></item><item><title>Bruno Raphael</title><link>https://blog.nextside.tech/autores/bruno-raphael/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.nextside.tech/autores/bruno-raphael/</guid><content:encoded>&lt;p>Sou sócio da Nextside e engenheiro há mais de 10 anos. Já mexi com
geoprocessamento e GIS, com mobile — de Android nativo a React Native — e com
backend distribuído: microserviços em Node.js/NestJS e Java/Spring Boot,
pagamentos, locks distribuídos e arquitetura hexagonal rodando em Kubernetes
na AWS.&lt;/p>
&lt;p>Aqui no blog escrevo sobre desenvolvimento mobile, arquitetura de sistemas
distribuídos e o que aprendi construindo software que não pode errar conta.&lt;/p>
</content:encoded></item><item><title>Lucas Israel</title><link>https://blog.nextside.tech/autores/lucas-israel/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.nextside.tech/autores/lucas-israel/</guid><content:encoded><![CDATA[<p>Faço parte da Nextside e crio produtos digitais há mais de 14 anos.
Comecei como desenvolvedor e virei arquiteto de sistemas — passei por
arrecadação eletrônica de pedágio (COMPSIS), fui CTO de uma das primeiras
legaltechs do Brasil (a Justto, que transacionou mais de R$ 1 bilhão na
plataforma e acabou adquirida) e hoje atuo com tecnologia e produto na
Projuris.</p>
<p>Gosto de transformar ideia em solução que gera valor rápido — ou de encerrar
a ideia rápido pra não queimar investimento. Foco em plataformas SaaS,
arquitetura na AWS, IA aplicada com pragmatismo e times pequenos de alta
performance. Também empreendo, avalio novos negócios e invisto em startups.
Gosto de medir, testar e ajustar.</p>
<p>Aqui no blog escrevo sobre arquitetura que aguenta produção, IA aplicada com
critério e como tirar um MVP da garagem sem virar gambiarra.</p>
]]></content:encoded></item><item><title>Pablo Winter</title><link>https://blog.nextside.tech/autores/pablo-winter/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.nextside.tech/autores/pablo-winter/</guid><content:encoded>&lt;p>Sou sócio da Nextside e CTO em produtos digitais voltados à mobilidade e
arrecadação. Engenheiro há mais de 10 anos — Java/Spring Boot, Node.js,
Next.js, Python. Foco em arquitetura hexagonal, sistemas orientados a eventos
(SQS, SNS, RabbitMQ, Kafka) e integrações sêniores com ERPs e gateways.&lt;/p>
&lt;p>Aqui no blog escrevo sobre IA aplicada com critério, gestão de times pequenos
e por que entrega rápida não é mágica.&lt;/p>
</content:encoded></item><item><title>Sobre este blog</title><link>https://blog.nextside.tech/sobre/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.nextside.tech/sobre/</guid><description>Por que este blog existe, quem escreve, com quem falar.</description><content:encoded><![CDATA[<h2>Por que este blog existe<span class="hx:absolute hx:-mt-20" id="por-que-este-blog-existe"></span>
    <a href="#por-que-este-blog-existe" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>A Nextside entrega Sprints de 4 semanas, Discoveries técnicas e Auditorias.
Este blog é onde a gente conta — em primeira pessoa, sem corporativês —
como pensamos, o que funciona, e o que dá errado.</p>
<h2>Quem escreve<span class="hx:absolute hx:-mt-20" id="quem-escreve"></span>
    <a href="#quem-escreve" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><p>Sócios e engenheiros sêniores da Nextside. Cada post tem um nome,
uma foto e um LinkedIn embaixo. Sem ghost-writer.</p>
<h2>Sobre o que escrevemos<span class="hx:absolute hx:-mt-20" id="sobre-o-que-escrevemos"></span>
    <a href="#sobre-o-que-escrevemos" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><ul>
<li><strong>Tecnologia</strong> — IA aplicada, stacks, arquitetura, decisões técnicas</li>
<li><strong>Gestão</strong> — como rodamos times pequenos com gente cara</li>
<li><strong>Entregas rápidas</strong> — o método Sprint, escopo fechado, MVPs em 4 semanas</li>
<li><strong>Cases</strong> — relatos com clientes (autorizados), bastidores, números</li>
</ul>
<h2>Com quem falar<span class="hx:absolute hx:-mt-20" id="com-quem-falar"></span>
    <a href="#com-quem-falar" class="subheading-anchor" aria-label="Permalink for this section"></a></h2><ul>
<li><strong>Quer contratar um Sprint, Discovery ou Auditoria?</strong> → <a href="https://nextside.tech"target="_blank" rel="noopener">nextside.tech</a></li>
<li><strong>Quer trabalhar com a gente?</strong> → <a href="https://linkedin.com/company/nextside-tech"target="_blank" rel="noopener">LinkedIn da Nextside</a></li>
<li><strong>Quer só conversar sobre um post?</strong> → LinkedIn ou X do autor</li>
</ul>
<p>Sem newsletter, sem pop-up, sem fórmula. Você lê, decide se gosta, volta.</p>
]]></content:encoded></item></channel></rss>