CTO no Integrar Plus • Publicado em 25 de October de 2026
Quando uma decisão de arquitetura tomada há quatro anos começa a cobrar juros em produção, o time invariavelmente se divide em dois campos opostos. De um lado, os defensores da governança corporativa insistem que o problema foi a falta de documentação formal em um Confluence ou Notion da vida. Do outro, os puristas do desenvolvimento ágil retrucam que documentos externos apodrecem em semanas, e que testes automatizados somados a código limpo deveriam bastar para explicar o sistema.
Eu discordo frontalmente das duas posturas. Ambas falham feio no longo prazo, só que por motivos diferentes.
A turma da wiki cria cemitérios de páginas órfãs. Alguém agenda três reuniões de alinhamento, preenche um formulário com vinte campos burocráticos e publica uma matriz comparativa bonita. Seis meses depois, o time mudou, as permissões de acesso mudaram, o link que estava colado na issue quebrou e a implementação real seguiu outro rumo na branch seguinte. Ninguém que está depurando uma pane de concorrência às duas da madrugada em um servidor vai abrir um navegador para procurar textos desatualizados em um serviço externo.
A turma do código como verdade única, por sua vez, confunde mecânica com contexto. O código diz exatamente o que a máquina está fazendo naquele instante. O teste diz quais comportamentos foram previstos para não quebrar. Nenhum dos dois explica o que foi considerado, testado e sumariamente descartado antes do merge.
Imagine que você encontre um loop manual de processamento com pausas fixas em um serviço de background no Ruby on Rails, consumindo diretamente de uma tabela do PostgreSQL, em vez de recorrer a uma biblioteca padrão de jobs assíncronos. Se você olhar apenas o diff do commit e a suíte do RSpec, a reação imediata de qualquer engenheiro experiente será a mesma: considerar aquilo uma aberração amadora, abrir um pull request e refatorar tudo para a convenção padrão do framework.
Dois dias depois do deploy em produção, o servidor satura a memória, o provedor externo bloqueia a sua conta por excesso de requisições simultâneas e você descobre o motivo daquela solução aparentemente tosca. A API externa não suportava conexões paralelas, a equipe precisava limitar o throughput por contrato e a infraestrutura própria da época não justificava subir um serviço extra só para coordenar taxas de entrega.
Sem o contexto da decisão, refatorar código legado é como desmontar uma cerca sem saber por que ela foi colocada ali. O perigo quase nunca reside naquilo que o autor escreveu, mas nas alternativas que ele tentou e viu falharem antes de chegar naquela linha de código.
Para que um registro de decisão arquitetural sobreviva ao tempo sem virar peso morto, a primeira regra é geográfica: ele precisa morar dentro da árvore do Git, no mesmo repositório do código que ele afeta. Se um desenvolvedor precisa clonar o projeto para trabalhar, ele já baixou todo o histórico técnico junto.
A segunda regra é o formato. Nada de planilhas, nada de diagramas proprietários. Arquivos de texto simples em Markdown, organizados em uma pasta dedicada na raiz do projeto, numerados sequencialmente.
O conteúdo não precisa passar de uma página. Na minha rotina, uma estrutura que realmente funciona há anos se apoia em quatro pontos:
## 0014. Processamento síncrono de webhooks via fila interna
Data: 2023-11-04
Status: Aceito
## Contexto
O volume de notificações do parceiro de pagamentos atingiu picos
que abriam concorrência desordenada no banco de dados. Precisamos
garantir ordem estrita por cliente sem introduzir dependências externas.
## Decisão
Implementar fila consumida em processo único via tabela dedicada
no PostgreSQL com bloqueio explícito de linha (SELECT FOR UPDATE SKIP LOCKED).
## Alternativas descartadas
- Redis com Sidekiq: adicionaria um serviço novo na VPS e um ponto
adicional de falha em infraestrutura sem ganho de escala no momento.
- Processamento direto na controladora HTTP: causava timeout no gateway
durante picos de tráfego.
## Consequências negativas aceitas
- A latência média de confirmação para o usuário final sobe em até
quatro segundos durante rajadas de dados.
- O throughput máximo fica travado no limite de escrita da VPS atual.
Essa simplicidade garante que qualquer pessoa que rode uma busca por texto no editor localize a explicação em três segundos, sem sair do fluxo de trabalho.
A maior falha dos documentos técnicos é que eles quase sempre soam como panfletos de vendas. O autor passa oitenta por cento do texto tentando justificar como a escolha dele é elegante, moderna e brilhante. Isso é inútil para quem vai ler o arquivo daqui a quatro anos.
A seção mais valiosa de um registro técnico é o registro do trade-off negativo, a dor concreta que o time concordou em tolerar naquele instante. Toda decisão técnica madura carrega um preço. Se você optou por centralizar tudo no PostgreSQL em vez de distribuir a carga entre múltiplos bancos especializados, você ganhou simplicidade operacional, mas aceitou que a contenção de conexões será o seu primeiro teto de escala.
Quando essa limitação finalmente aparecer três anos depois, a postura da equipe muda por completo. Ninguém precisa apontar dedos ou caçar culpados por incompetência. O documento deixa evidente que a limitação era conhecida, foi aceita de forma consciente e serviu ao seu propósito enquanto o negócio estava naquele estágio. A decisão não estava errada; ela simplesmente atingiu a data de validade que já estava prevista no papel.
Existe um erro clássico cometido por quem adota registros de decisão: tentar editar o passado. Quando o cenário muda e a equipe decide trocar a fila do PostgreSQL por um cluster distribuído, a tentação inicial é abrir o arquivo antigo e reescrever o texto para refletir a nova realidade.
Isso destrói o valor da trilha histórica. Decisões arquiteturais são imutáveis. Se a premissa de três anos atrás caiu por terra, você não apaga o registro original. Você cria um novo registro que declara explicitamente que ele substitui o anterior, explicando quais restrições mudaram: o volume subiu dez vezes, o orçamento aumentou ou a equipe agora tem capacidade de operar mais serviços em paralelo.
Tratar decisões como fatos imutáveis no tempo tira o peso emocional de admitir que uma arquitetura ficou para trás. O sistema evolui porque o contexto mudou, não porque alguém no passado tomou uma atitude leviana.
Nem toda mudança no código merece um registro formal. Se você começar a abrir um arquivo para cada migração de coluna, para cada componente visual no Hotwire ou para cada ajuste de rota, o time vai sabotar o processo em menos de um mês por puro esgotamento.
O critério de corte que eu uso é direto: só merece registro aquilo que não tem retorno trivial e cujo custo de reversão envolva migração de dados, mudança na topologia de servidores ou alteração estrutural no fluxo de concorrência. Se uma decisão pode ser revertida em um pull request de trinta minutos em uma tarde comum, ela não precisa de registro. Se reverter a decisão vai exigir um fim de semana inteiro de manutenção e dor de cabeça, escreva o arquivo antes de colocar a mão no código.
CTO e arquiteto full stack especializado em Ruby on Rails, Vue.js, sistemas multi-tenant e infraestrutura distribuída.