TL;DR
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.
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.
Arquitetura parou de ser o imposto que você paga pra ir devagar. Virou o que mantém a IA rápida.
O lixo não é o que foi feito rápido. É o que foi feito cego.
Todo founder técnico que me procura chega com o mesmo medo, e ele é legítimo: “preciso lançar em semanas, mas não quero reescrever tudo daqui a três meses”. Daí vem a crença que eu quero matar aqui:
“Arquitetura é luxo de quem tem tempo. Lança logo, arruma depois.”
Eu ouço isso toda semana. E concordava em certo nível, até a IA mudar a conta. Porque “arruma depois” 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 “de verdade” vem depois, do zero.
Calma lá. Essa dicotomia morreu, e quem matou foi a própria IA.
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.
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 coding agent: um agente de IA que lê, edita e roda seu repositório por conta própria, 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.
O vibe coding (o tal “pede, aceita, deploya” sem entender o que saiu) é ótimo pra protótipo de fim de semana. O problema é a conta, que não é linear. Um paper de 2025 formalizou isso como flow-debt trade-off: 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.
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.
MVP que vira lixo não é o que foi feito rápido. É o que foi feito CEGO, sem deixar pista nem pra IA nem pro humano que vai mexer nele depois.
A IA lê seu repositório, não seu prompt
Tem uma frase do Matt Pocock que resume a virada: “seu codebase, não seu prompt, decide a qualidade do output da IA”. Soa exagero. Não é.
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.
A consequência é física, não filosófica: grep acha string, não intenção. “grep finds strings, not intent.” Se a função que importa se chama validateToken, o agente acha de primeira. Se a lógica está espalhada em cinco arquivos frouxamente ligados por import, com nome genérico tipo handler ou process, ele vasculha, carrega arquivo demais, e queima contexto antes de começar o trabalho.
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 é “saber programar”. É achar o trecho certo. Localizar bem é o que separa o PR que mergeia do que apodrece.
Organização por camada técnica sabota exatamente isso. Quando tudo é controllers/, services/, models/, 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, “a junkyard of irrelevant stuff”, um ferro-velho de coisa que não importa.
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 “junte o que muda pela mesma razão, separe o que muda por razões diferentes”. 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 “um controller”. A correção tem nome, e é o assunto da próxima seção.
A IA não devia ser esperta o bastante pra achar sozinha?
É 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.
E aqui eu preciso ser honesto, porque a versão simplista dessa ideia (“codebase ruim trava a IA”) é 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ê.
Só que o humano tem uma arma que a IA não tem nativamente: o IDE. Você lança um evento com ApplicationEventPublisher no Spring, e o IntelliJ te mostra cada @EventListener 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.
Então a frase certa não é “a IA expõe arquitetura ruim”. É: 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.
Organize por feature, não por camada (e esqueça o nome da arquitetura)
A correção é mais chata do que parece, e é de graça: organize o código por feature, não por camada técnica.
Em vez de controllers/, services/, repositories/ (onde cada feature está estilhaçada em quatro pastas), você faz uma pasta por capacidade de negócio: orders/, payments/, refunds/, cada uma com o seu controller, serviço e acesso a dados dentro. O nome disso, na literatura, é vertical slice: uma fatia que vai da borda (a request) até o fundo (o banco), inteira, no mesmo lugar. Jimmy Bogard cravou a regra de ouro: “minimize coupling between slices, and maximize coupling in a slice”. Acoplamento mínimo entre fatias, máximo dentro de uma.
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. “Mexe no refund” já o leva pra refunds/, 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.
Aqui cabe uma honestidade que desarma. No briefing desse post, alguém da equipe escreveu “usem a arquitetura NGC ou a que for”. Fui pesquisar o que é “arquitetura NGC”. 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.
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.
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 shared/, e aí o shared/ vira a lixeira que acopla todo mundo de novo. Sandi Metz tem a melhor regra pra isso: “duplication is far cheaper than the wrong abstraction”. 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.
Monorepo e ADR: pare de fazer a IA (e seu time) adivinhar
Organizar dentro do projeto resolve metade. A outra metade é o que está entre os projetos, e é onde o monorepo entra.
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: “a repository boundary is a context wall. Every wall degrades the quality of AI-generated output”. Toda fronteira de repositório é uma parede de contexto, e toda parede degrada o que a IA produz.
Pensa no caso concreto. Você pede “adiciona um campo no cadastro”. 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.
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.
O ADR é a outra peça, e a mais subestimada. ADR eu já expliquei em outro post: 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, “deprived of architectural intent”: 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 “melhorar” seu código reintroduzindo exatamente o que você rejeitou. O ADR, junto com um CLAUDE.md ou AGENTS.md no repo, é como você entrega a intenção de mão beijada, em vez de rezar pra ele adivinhar.
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 AGENTS.md 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.
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, é “the smallest possible set of high-signal tokens”, o menor conjunto de tokens de alto sinal, não o maior monte de tokens.
O MVP que escala é o que a IA ainda entende amanhã
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.
Isso não quer dizer construir tudo. Quer dizer cortar a coisa certa, e o que cortar e o que manter num MVP 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 (“a gente precisa lançar agora e lida com a consequência depois”) ou imprudente e cega (“não temos tempo pra design”). 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.
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.
Foi o mesmo padrão sobre o qual escrevi quando code review virou o gargalo: 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.
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.
