| Bellacosa Mainframe e o guard rails em desenvolvimento de software |
Guard Rails: A Arte de Impedir que um Desenvolvedor Derrube o Banco
Uma conversa que todo desenvolvedor COBOL deveria ter
Imagine a seguinte situação.
Você acabou de entrar em uma instituição financeira.
É seu terceiro mês como desenvolvedor COBOL.
Depois de semanas corrigindo pequenos bugs, finalmente recebe uma tarefa importante.
Uma rotina responsável pelo envio de notificações para clientes.
O gerente explica:
— Precisamos incluir um novo tipo de comunicação.
Você faz a alteração.
Compila.
Executa os testes.
Tudo parece funcionar.
A mudança é promovida para produção.
Horas depois, milhares de clientes recebem uma mensagem errada.
O call center entra em colapso.
O aplicativo registra picos de acesso.
O time de negócios inicia uma reunião de emergência.
A diretoria quer explicações.
E então surge a pergunta:
Como isso foi possível?
A resposta geralmente não é:
"Porque o desenvolvedor errou."
A resposta correta costuma ser:
"Porque o sistema permitiu que um erro chegasse à produção."
É exatamente nesse ponto que surge um dos conceitos mais importantes da engenharia moderna:
Guard Rails.
O que são Guard Rails?
A tradução literal seria:
"trilhos de proteção".
A inspiração vem das rodovias.
Quando um carro sai da pista, existe uma barreira metálica para impedir que ele caia de um penhasco.
O guard rail não evita o erro do motorista.
Ele reduz as consequências.
Na engenharia de software acontece exatamente a mesma coisa.
Os desenvolvedores inevitavelmente cometerão erros.
Os analistas inevitavelmente esquecerão requisitos.
Os operadores inevitavelmente clicarão em algo errado.
Os administradores inevitavelmente executarão comandos incorretos.
O objetivo não é eliminar o erro humano.
O objetivo é impedir que o erro se transforme em desastre.
O erro é inevitável
Desenvolvedores juniores costumam acreditar que sistemas caem porque alguém não sabia programar.
Essa visão desaparece rapidamente em ambientes corporativos.
Os maiores incidentes da história da tecnologia não foram causados por programadores incompetentes.
Foram causados por profissionais experientes trabalhando sob pressão.
Pessoas excelentes.
Pessoas inteligentes.
Pessoas treinadas.
Pessoas humanas.
A questão nunca foi:
"Quem errou?"
A questão sempre foi:
"Por que o sistema permitiu?"
Essa diferença muda completamente a forma de construir software.
Um exemplo COBOL simples
Considere um programa que realiza transferência bancária.
Versão sem Guard Rails:
IF SALDO-CONTA > 0
SUBTRACT VALOR FROM SALDO-CONTA
END-IF.
Parece correto.
Mas existe um problema.
Suponha:
Saldo = 100
Transferência = 1000
O programa permitirá saldo negativo.
Agora uma versão mais segura.
IF VALOR > SALDO-CONTA
DISPLAY "TRANSFERENCIA NEGADA"
GO TO FIM-PROGRAMA
END-IF.
O sistema agora protege o negócio.
Isso é um Guard Rail.
Guard Rail não é regra de negócio
Esse é um erro comum.
Muitos desenvolvedores confundem os dois conceitos.
Regra de negócio:
"O cliente não pode sacar mais que possui."
Guard Rail:
"Mesmo que alguém esqueça a regra, o sistema impedirá a operação."
Uma regra define comportamento.
Um Guard Rail protege comportamento.
A filosofia do mainframe
Durante décadas, os ambientes mainframe desenvolveram uma cultura diferente do mundo moderno.
Em startups existe uma frase famosa:
Move fast.
Nos bancos existe outra:
Don't break production.
A razão é simples.
Um erro em rede social gera reclamações.
Um erro bancário gera prejuízo.
Por isso o mundo COBOL sempre valorizou:
validação;
redundância;
auditoria;
segregação;
rastreabilidade.
Sem perceber, os ambientes mainframe implementavam Guard Rails muito antes do conceito ganhar popularidade.
O caso clássico do JCL
Todo profissional de mainframe já ouviu histórias de horror envolvendo JCL.
Imagine um dataset:
CLIENTES.PRODUCAO
Agora imagine um utilitário de exclusão.
DELETE CLIENTES.PRODUCAO
Um comando simples.
Um erro simples.
Um desastre gigantesco.
Por isso empresas maduras criam Guard Rails.
Por exemplo:
confirmação obrigatória;
aprovação dupla;
ambiente segregado;
backup automático.
A exclusão continua possível.
Mas torna-se muito mais difícil.
O princípio do “Are You Sure?”
Existe uma categoria inteira de Guard Rails baseada em confirmação.
Exemplo.
Você tenta apagar um arquivo.
O sistema pergunta:
"Tem certeza?"
Parece algo trivial.
Mas essa simples pergunta já evitou milhões de erros ao longo da história da computação.
Em sistemas financeiros essa ideia evolui.
Em vez de uma confirmação:
duas confirmações;
dois operadores;
dois gestores;
duas aprovações.
Chamamos isso de Four Eyes Principle.
Princípio dos quatro olhos.
Guard Rails em processamento batch
O universo COBOL vive cercado de batches.
Folha de pagamento.
Compensação bancária.
Fechamento contábil.
Liquidação financeira.
Imagine um programa que processa:
10.000 registros
Normal.
Agora imagine:
100 milhões de registros
Algo está errado.
Sem Guard Rails o programa continua.
Com Guard Rails ele interrompe:
IF QTDE-REGISTROS > LIMITE-MAXIMO
DISPLAY "PROCESSAMENTO ANORMAL"
ABEND
END-IF.
Esse simples teste pode evitar horas de caos operacional.
O conceito de Fail Fast
Existe um princípio muito importante:
Fail Fast.
Falhe rapidamente.
Muitos sistemas tentam continuar funcionando mesmo após identificar inconsistências.
Isso parece inteligente.
Na prática costuma piorar tudo.
Se um dado crítico estiver errado, o melhor comportamento é parar imediatamente.
Exemplo:
IF CODIGO-CLIENTE = SPACES
ABEND
END-IF.
Parar cedo é melhor do que produzir milhões de registros incorretos.
Guard Rails contra desenvolvedores
Esse é um tema que incomoda iniciantes.
Ninguém gosta de ouvir:
"O sistema precisa proteger a empresa de você."
Mas essa é a realidade.
Um Guard Rail existe justamente porque até profissionais excelentes erram.
Imagine um comando SQL.
Sem proteção:
DELETE FROM CLIENTES;
Com proteção:
DELETE FROM CLIENTES
WHERE ID = :CLIENTE;
Ou ainda melhor.
Permissão somente leitura em produção.
O desenvolvedor continua competente.
O ambiente apenas se torna mais seguro.
O incidente do Nubank e os Guard Rails
O caso do falso aviso de liquidação tornou-se um exemplo interessante.
Independentemente dos detalhes internos, uma pergunta surgiu:
Como uma comunicação tão crítica chegou aos clientes?
A resposta provavelmente envolve ausência ou falha de Guard Rails.
Por exemplo:
validação insuficiente;
aprovação inadequada;
rollout inexistente;
testes incompletos.
Nenhum sistema deveria conseguir informar a liquidação de um banco sem múltiplas camadas de proteção.
Rollout gradual
Imagine um envio para:
50 milhões de clientes
Sem Guard Rail:
envio imediato.
Com Guard Rail:
1% da base.
Validação.
5%.
Validação.
10%.
Validação.
100%.
Empresas como Google, Amazon e Netflix utilizam esse modelo constantemente.
O objetivo é reduzir o raio da explosão.
Blast Radius
Todo arquiteto experiente faz uma pergunta.
Se isso falhar, quantas pessoas serão afetadas?
Chamamos isso de Blast Radius.
Raio de explosão.
Exemplo.
Erro em um batch:
Impacto:
500 clientes.
Blast Radius pequeno.
Erro em compensação nacional:
Impacto:
50 milhões de clientes.
Blast Radius enorme.
Guard Rails existem para reduzir esse raio.
Observabilidade também é Guard Rail
Muitos desenvolvedores acreditam que Guard Rails são apenas validações.
Não.
Monitoramento também é proteção.
Imagine:
Processamento esperado:
1000 transações por minuto
Sistema detecta:
500.000 transações por minuto
Algo claramente está errado.
Um bom sistema dispara alarmes.
Isso também é Guard Rail.
O conceito de Circuit Breaker
Em sistemas distribuídos modernos existe outro Guard Rail famoso.
Circuit Breaker.
Inspirado nos disjuntores elétricos.
Se uma dependência começa a falhar:
o sistema corta a conexão.
Em vez de derrubar tudo.
No mundo mainframe encontramos equivalentes há décadas:
limites operacionais;
interrupções controladas;
filas protegidas;
rejeições automáticas.
A ideia é a mesma.
Conter danos.
O erro mais caro é o silencioso
Existe uma frase conhecida entre engenheiros de confiabilidade:
Sistemas barulhentos são irritantes.
Sistemas silenciosamente errados são perigosos.
Um programa que falha imediatamente chama atenção.
Um programa que produz dados incorretos durante três dias pode gerar prejuízos gigantescos.
Por isso Guard Rails modernos privilegiam transparência.
Tudo deve ser:
registrado;
monitorado;
auditado;
rastreável.
A maturidade profissional
Existe um momento na carreira em que o desenvolvedor deixa de pensar:
"Meu código funciona."
E começa a pensar:
"O que acontece quando ele falhar?"
Essa mudança separa programadores iniciantes de engenheiros experientes.
O foco deixa de ser funcionalidade.
Passa a ser confiabilidade.
O que um desenvolvedor COBOL Jr deve fazer
Sempre pergunte:
O que pode dar errado?
Quem será impactado?
Existe limite operacional?
Existe validação?
Existe rollback?
Existe auditoria?
Existe monitoramento?
Existe aprovação?
Existe segregação?
Existe plano de contingência?
Se alguma resposta for "não sei", continue investigando.
A grande lição
Guard Rails não existem porque desenvolvedores são ruins.
Eles existem porque sistemas são complexos.
Quanto maior a empresa, mais perigoso se torna assumir que ninguém cometerá erros.
O verdadeiro papel da engenharia não é criar sistemas perfeitos.
É criar sistemas resilientes.
Sistemas que sobrevivam a erros humanos.
Sistemas que sobrevivam a falhas operacionais.
Sistemas que sobrevivam a decisões equivocadas.
No universo bancário, onde bilhões de reais transitam diariamente por programas COBOL escritos ao longo de décadas, essa diferença não é apenas uma questão técnica.
É uma questão de sobrevivência operacional.
E talvez a principal lição para qualquer desenvolvedor COBOL Jr seja esta:
Seu trabalho não é apenas fazer o programa funcionar.
Seu trabalho é impedir que ele cause danos quando inevitavelmente algo der errado.
Esse é o verdadeiro significado de Guard Rails.
Sem comentários:
Enviar um comentário