O segredo sujo do vibe coding

Você manda um prompt, recebe uma UI linda em 30 segundos. Aí pede mais uma feature… e o app desmorona em silêncio. Não com crash — com falha comportamental silenciosa.

O caso clássico: você pede um cupom de desconto no seu e-commerce. O agente cria o input, o botão Aplicar, o toast de sucesso. Você digita SAVE20, a tela mostra "Desconto aplicado!" — e o novo total nunca foi persistido, nunca foi renderizado, nunca foi escrito em lugar nenhum. A interface está mentindo pra você. 😱

Essa é a parte que ninguém comenta no hype do vibe coding. A falha não aparece. Pra achar, você tem que clicar em tudo, ler logs e, no fim, ler o código gerado — o que destrói completamente a proposta de não ler código.

Por que as soluções óbvias não resolvem

  • LLM como juiz: pedir pro agente debugar a si mesmo gera alucinação confiante. Modelos de fronteira erram casos de borda e não enxergam fluxo entre handlers.
  • Testes unitários: você escreve mais código pra checar código gerado. Quem não programa não consegue, e quase nunca cobre a integração UI → backend.
  • Análise estática na mão: é determinística e precisa, mas a curva de aprendizado é violenta — você teria que escrever queries CodeQL do zero.

Existe um quarto caminho, e é sobre ele que a gente vai falar agora. Vamos lá! 🚀

Developer prompting an AI coding agent in a chat interface to build a web app Software Concept Art

FlowCheck: expresse a intenção na UI, verifique no código

O FlowCheck é uma linguagem de restrições + um pipeline de análise estática. A ideia central: você descreve o comportamento clicando no seu próprio app, e a ferramenta compila isso em queries CodeQL contra o código gerado.

Passo 1 — Aponte para o que importa

Você passa o path do app. O FlowCheck abre numa aba com um overlay:

Quando eu faço [ação], estes componentes atualizam: [componente].

Você clica nos elementos reais da UI — o input do cupom, o total, a camada de storage — do jeito que você já interagiria com o app.

Passo 2 — A restrição vira algo formal

O template compila pra uma restrição probabilística:

P(evento | condição) = [0, 1]

Leia como: a probabilidade do evento acontecer, dada a condição, é 1 (sempre) ou 0 (nunca). Pro bug do cupom:

P(w(total) | A(promo-input)) = 1

Ou seja: sempre que o cupom for aplicado, o total tem que ser escrito.

Passo 3 — Compilando pra CodeQL

O FlowCheck faz o parse da AST da restrição, extrai a ação, o tipo de evento (ex: escrita) e o elemento alvo. Depois mapeia esses componentes de UI para sources e sinks no banco relacional do CodeQL em cima do seu código, e emite duas checagens:

path_exists      // existe ALGUM caminho alcançável da ação até a escrita?
all_paths_write  // a escrita acontece em TODO caminho de execução a partir da ação?

A segunda é a estrela. A maioria das falhas silenciosas não é "não existe caminho" — é "existe no branch feliz, mas não no condicional".

Passo 4 — Verificação determinística

O CodeQL roda as queries. Se uma restrição for violada, o FlowCheck aponta qual aspecto falhou e as linhas exatas onde o fluxo quebra. Sem modelo no meio, sem alucinação, zero falsos positivos na avaliação dos autores.

Os números

Eles construíram quatro apps inspirados em Amazon, Twitter, Airbnb e Slack usando Claude Code, injetaram 30 bugs sutis de fluxo de dados e escreveram restrições pra cada um.

MétodoBugs pegos (de 30)
FlowCheck30 / 30 (100%)
Claude Opus 4.7 (melhor prompt)26 / 30 (87%)
DeepSeek V3abaixo
Gemini Proabaixo

O achado mais interessante: detalhar o prompt nem sempre ajuda. Com mais contexto, os modelos leem o código com mais cuidado — e aí ficam mais dispostos a confiar nele, justificando bugs como design intencional em vez de apontar erro. É um modo de falha que prompt engineering nenhum conserta.

Os modelos quebraram consistentemente em fluxos entre handlers. No clone da Amazon, a ação "aplicar cupom" limpava o resumo do carrinho enquanto o handler de checkout ainda tentava ler aquilo. Como nenhum handler referenciava o outro, o modelo avaliou cada um isolado e nunca traçou o fluxo entre eles.

Web application UI with a cart and promo code field under static analysis debugging Algorithm Concept Visual

Onde essa abordagem tem limite

Vamos ser honestos sobre as fronteiras, porque o paper também é.

  • A cobertura das restrições é sua responsabilidade. O FlowCheck pega 100% das falhas alvo — aquelas que você pensou em expressar. Bug num comportamento que você nunca especificou é invisível pra ferramenta.
  • Só formato de fluxo de dados. O pipeline é construído em cima de source → sink. Erro puramente de lógica (cálculo de desconto errado, off-by-one na paginação) não é violação de fluxo e não vai ser pego.
  • Viés pro ecossistema JS/TS. O suporte do CodeQL é mais forte em web apps JS/TS. Se seu app é backend Python ou Go, o mileage varia.
  • Fricção de setup. Você ainda precisa rodar a ferramenta, apontar pra um build e deixar o CodeQL indexar o código. Não é extensão de navegador com um clique.

Dica prática pro seu fluxo

Não trate isso como "substituir a leitura de código". Trate como proteção de regressão pra intenção. Escreva cinco restrições pros fluxos que custam dinheiro em silêncio — checkout, auth, persistência, estado de pagamento — e rode depois de cada iteração do agente. É aí que está o ROI.

Se você curte pensar em como pipelines gerados por IA se comportam em escala, a mesma lição vale pra infraestrutura: verifique o fluxo de dados, não a vibe. Uma boa leitura complementar é esse deep dive sobre escalar pipelines de processamento de mídia na Netflix, onde o mesmo princípio — instrumente o fluxo, não confie na superfície — aparece num contexto bem diferente.

E se você quer ver o que acontece quando a camada de compute fica drasticamente mais rápida, vale a pena conferir essa análise do Presto acelerado por GPU no NVIDIA GB200 NVL72 — analytics mais rápido deixa o loop de verificação mais curto, não opcional.

CodeQL static analysis query scanning generated JavaScript for silent data flow bugs Programming Illustration

Conclusão

Vibe coding não vai sumir, e as falhas silenciosas também não. A jogada vencedora não é "confiar mais no agente" nem "ler cada linha" — é tornar a intenção checável por máquina. A contribuição do FlowCheck é mostrar que uma linguagem de restrições em nível de UI pode compilar pra análise estática determinística e vencer modelos de fronteira no próprio jogo deles.

O que estudar depois

  1. Fundamentos de CodeQL — mesmo um entendimento raso de taint tracking source/sink já te deixa muito melhor em raciocinar sobre código gerado.
  2. Property-based testing — a mesma filosofia (exprima invariantes, deixe a máquina achar violações) aplicada em runtime em vez de análise estática.
  3. Especificação de restrições pra não-programadores — área de pesquisa aberta, e é o gargalo real pro vibe coding virar mainstream.

O paper completo e o repositório estão abertos — o estudo é a 근거자료 por trás de tudo acima, e o repo aceita stars e issues. 🔥

Este conteúdo foi elaborado com o auxílio de ferramentas de IA, com base em fontes confiáveis, e revisado pela nossa equipe editorial antes da publicação. Não substitui o aconselhamento de um profissional especializado.