Portas de uma via, num ano em que o modelo muda a cada trimestre
Quando modelo, preço por token e tooling viram a cada trimestre, a competência real é saber qual decisão de arquitetura tornar reversível.

Bezos gosta de separar decisões em dois tipos. Porta de duas vias: você atravessa, e se o outro lado for ruim, você volta pelo mesmo lugar. Porta de uma via: fecha atrás de você. O erro caro não é escolher mal numa porta de duas vias. É tratar uma porta de uma via como se fosse de duas, atravessar distraído e só perceber o clique da fechadura meses depois.
Foi o que fiz. Casei o schema do produto com o formato de saída de um modelo específico, e jurava que tinha preservado a reversibilidade. O que ficou pelo caminho foi exatamente ela.
O provider da vez tem prazo de validade
Estamos num ano em que o modelo muda a cada trimestre. O preço por token despenca e sobe de novo, o formato de tool call é redesenhado, o campo do qual você dependia vira legado, um concorrente lança algo melhor e mais barato na semana em que você terminou de integrar. A cadência de mudança do fornecedor é maior que a cadência de release do seu produto.
Nesse cenário, padronizar o núcleo no provider da vez é um erro de categoria. Você pega a dependência que mais se mexe no sistema inteiro e a transforma no alicerce que não pode se mexer. Acopla o que é volátil por natureza ao que precisa ser estável por contrato.
Onde a reversibilidade vaza
A parte perversa é que a fronteira parecia existir. Eu tinha um adapter, um cliente isolado, uma função só para falar com o modelo. Achei que estava coberto.
O vazamento foi mais fundo. O formato que o modelo devolvia, aquele JSON com aqueles nomes de campo e aquela estrutura aninhada, atravessou o adapter e virou o schema que eu persistia no banco. Depois virou o contrato da API. Depois o frontend passou a ler os campos com os nomes do provider. Quando um modelo melhor apareceu com um formato de saída diferente, trocar deixou de ser configuração e virou migração de banco, com a API e o frontend acoplados atrás dela.
A porta de uma via tinha fechado no commit em que salvei a saída crua. Eu não estava olhando para a fechadura naquele dia.
// vaza: o formato do provider vira o schema persistido
await db.save(await provider.generate(prompt));
// porta de duas vias: o núcleo só conhece o tipo canônico
await db.save(toDecision(await provider.generate(prompt)));
A fronteira que mantém a porta aberta
A disciplina que faltou tem nome antigo: o núcleo define a forma canônica, e o adapter traduz o provider para ela. O modelo nunca fala direto com o schema. Ele fala com uma função de tradução, e é só ela que conhece os nomes de campo do fornecedor da vez.
Trocar de modelo, nesse desenho, é escrever um toDecision novo. Uma tarde de trabalho, não um projeto de migração. O banco não sabe qual provider gerou o dado. A API não sabe. O frontend não sabe. Só o adapter sabe, e o adapter é descartável por design.
Acoplar o núcleo ao provider da vez é transformar a dependência que muda a cada trimestre no alicerce que não pode mudar nunca.
É a mesma fronteira de baixa confiança que a gente coloca ao redor de qualquer integração instável, com uma responsabilidade a mais: além de validar a saída, ela impede que a forma do fornecedor contamine o vocabulário do produto. Validação protege da resposta errada. Tradução protege da reversibilidade perdida.
Reversibilidade não aparece no diagrama, não melhora métrica nenhuma, não impressiona ninguém enquanto a porta está aberta. Ela cobra o preço inteiro num único dia: aquele em que você tenta voltar e descobre que atravessou uma via só.