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á! 🚀

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étodo | Bugs pegos (de 30) |
|---|---|
| FlowCheck | 30 / 30 (100%) |
| Claude Opus 4.7 (melhor prompt) | 26 / 30 (87%) |
| DeepSeek V3 | abaixo |
| Gemini Pro | abaixo |
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.

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.

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
- Fundamentos de CodeQL — mesmo um entendimento raso de taint tracking source/sink já te deixa muito melhor em raciocinar sobre código gerado.
- 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.
- 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. 🔥