Para devs AI-native
A base SaaS
que seu agente não consegue quebrar
Você não está comprando código que seu agente já sabe escrever. Está comprando os guardrails que ele não consegue escrever sozinho: as paredes que impedem ele de quebrar seu login quando mexe em pagamentos — garantidas pelo compilador e pelo CI, não uma convenção frouxa que ele racionaliza e contorna.
O agente vê uma fatia, e mesmo assim edita com confiança
A cada sessão seu agente vê só uma parte do projeto — então muda código sem saber o que depende dele em outro lugar. O primeiro mês parece elétrico. No sexto mês a mesma ferramenta fica mais lenta que antes, porque a dívida técnica não é paga: é acumulada, e uma hora vai ser cobrada. Um repo vazio piora tudo: sem padrões pra se apoiar, o agente deriva pros próprios defaults e corrói a arquitetura em silêncio. No prompt 50 já é spaghetti.
Nas palavras de quem entrega com agentes
Dívida que é cobrada mais tarde
"Tech debt isn't paid down, it's being added to, and at some point in the future it will need to be collected." — antihipocrat, Hacker News (item 45405177)
Nenhum padrão consistente pra se apoiar
"llm code has none of that [consistent patterns], if yes its by pure chance that won't repeat." — kakacik, Hacker News (item 45405177)
Os edge cases de segurança que ele deixa passar
Os agentes de IA "generate RLS policies that accidentally expose data to other tenants, forget to validate webhook signatures on payment events, create permission checks that authenticated users can bypass." — blog da MakerKit
Paredes que o agente fisicamente não consegue cruzar
Aponte seu agente pra camada domain e diga pra ele simplesmente importar o Prisma ali. Ele não consegue — o ESLint quebra o build. Fronteiras DDD garantidas pelo compilador e pelo lint: o código de domain não pode importar Express, Prisma ou infraestrutura. Isso não é uma sugestão frouxa de um AGENTS.md que o agente racionaliza e contorna. É uma parede no CI.
1 modules/billing/domain/subscription.ts
2 import { prisma } from '@prisma/client'
3 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4 error no-restricted-imports
5 domain/ deve continuar framework-agnostic.
6 Ver ADR-001.
7
8 ✖ 1 problem — CI bloqueado
Payload drift, pego antes de ir pro ar
O agente renomeia um campo no server e esquece do cliente. O type drift o compilador pega. Mas o payload drift — o form manda fullName, o server espera name — passa no typecheck e dá 400 em produção. Aqui os schemas Zod do cliente importam de um pacote compartilhado @app/contracts, e os tipos do openapi-fetch são regerados e ficam sob o check de CI api-types-fresh. A superfície gerada e o server não podem discordar sem deixar o CI vermelho.
1 $ bun run generate:api
2 $ git diff --exit-code \
3 apps/server/openapi.json \
4 apps/client/lib/api/openapi-types.ts
5
6 openapi.json mudou — os tipos estão desatualizados
7 ✖ api-types-fresh falhou — regere e commite
Os três bugs que um repo vazio entrega sempre — aqui já fechados
Sessões que sobrevivem a um reset
O bug recorrente que os reviews de segurança encontram em apps geradas por IA: sessões que não encerram ao trocar a senha — você reseta a senha e o login antigo continua funcionando. Aqui as sessões são registros server-side no Postgres — qualquer uma pode ser revogada on demand, e encerrar as sessões concorrentes ao trocar a credencial é um flag documentado, não um rewrite.
Webhooks que cobram duas vezes
O outro clássico é o webhook handler sem idempotência: quando o Stripe manda a mesma mensagem duas vezes (e manda), o app cobra ou credita duas vezes. Aqui as compras são idempotentes sobre externalOrderId, entregues por um event bus com outbox durável.
Dados de tenant que vazam
Os agentes de IA "generate RLS policies that accidentally expose data to other tenants" (makerkit.dev). Aqui um tenant-isolation guard escopado por org — repos org-scoped mais um query guard do Prisma — devolve 404 entre orgs. Sem RLS pra esquecer.
Um harness contra o qual seu agente pode se autoverificar
E2E Playwright no CI
Os fluxos golden-path rodam em cada PR (bun run e2e:golden). O loop code → test → code que o agente precisa pra se autocorrigir — com um passo de validação que reflete o que você realmente quer, não o que parece plausível.
Fronteiras DDD, lint-enforced
O layering são regras de ESLint, não documentação: domain e application não podem importar frameworks, e os imports cross-context em runtime são proibidos. A parede que o agente bate é a parede que mantém sua arquitetura intacta.
Um CLAUDE.md de regras garantidas
Um CLAUDE.md vem no repo — layering DDD, a regra de contratos, disciplina de commits e PRs — pra que o agente herde seu pensamento de longo prazo em vez de tirar a média da internet pública. TypeScript estrito de ponta a ponta.
Resolvido uma vez, pra que seu agente só construa o que é seu
Auth
BetterAuth — 2FA, magic-link, OAuth, verificação de email, password reset. Sessões e fluxos já ligados e testados.
Billing
Stripe, MercadoPago e Polar atrás de uma interface tipada — checkout, customer portal, mudanças de plano, webhooks assinados.
Orgs e RBAC
Organizações, membros, convites, permissões por papel e API keys — multi-tenancy de verdade, não uma tabela users com uma coluna role.
Jobs
Filas, processors e schedulers do BullMQ, com um dashboard do Bull Board pra acompanhar.
Events
Um event bus com outbox durável pra que os domain events sobrevivam a um crash e sejam entregues de forma confiável.
Observabilidade
OpenTelemetry, Sentry (@sentry/bun), Pino, /metrics — cada um sobe como no-op até você configurar.
Perguntas de quem entrega com agentes
Um CLAUDE.md ou um AGENTS.md não basta?+
Vocês vendem velocidade?+
Qual é a stack?+
Com quais agentes funciona?+
Aponte seu agente pra cá, não pra um repo vazio.
Um repo vazio obriga o agente a inventar arquitetura e a repetir os mesmos três bugs de segurança. Dê a ele paredes que não consegue cruzar.