Revisão de código exige leitura
(hauleth.dev)- Revisão de código não é uma etapa formal antes do deploy, mas um processo de transferir a responsabilidade por falhas, problemas de segurança e exclusão de dados de uma pessoa para a responsabilidade da equipe
- Melhores evals, testes, feature flags, guardrails e observabilidade podem ser respostas para reduzir a ansiedade de colocar em produção código que ninguém leu, mas a crítica é que essa abordagem perde o objetivo de distribuição de responsabilidade da revisão
- Exigir aprovação sem leitura é como pedir que alguém aperte um botão sem pensar, o que leva à sátira da button roulette, em que se faz merge de um PR aleatório com todo o CI verde
- A revisão de código faz com que membros da equipe vejam diferentes partes de uma base grande de código, reduzindo o bus factor e funcionando como um mecanismo de aprendizado para que novos membros entendam o código e a cultura de código
- Para forçar o deploy em produção de código não lido, seria necessária uma isenção formal de responsabilidade por bugs, problemas de segurança, downtime etc., e a conclusão é que conseguir essa isenção seria difícil
O objetivo da revisão é distribuir responsabilidade, não apenas aprovar
- O ponto de partida é a pergunta “o que seria necessário para ficar confortável em colocar em produção código que não foi lido”, apresentada no texto de Charity Majors “AI enthusiasts are in a race against time, AI skeptics are in a race against entropy”
- Respostas como melhores evals, testes, feature flags, guardrails, observabilidade, separação de dependências, redução do raio de impacto e começar por pequenas mudanças fora do caminho crítico são tratadas como algo que desvia do ponto central da revisão
- O objetivo da revisão é não deixar o peso de falhas, problemas de segurança e exclusão acidental de dados sobre uma única pessoa, mas dividi-lo como responsabilidade da equipe entre autor e revisores
- Se a exigência for “aprovar sem ler”, enfraquece-se o motivo para fazer uma pessoa apertar o botão manualmente, e surge a sátira chamada
button roulette, em que um dos PRs atribuídos com todo o CI verde é mesclado aleatoriamente
O que se perde em uma revisão sem leitura
- A revisão de código força membros da equipe a olhar para outras partes da base de código, compensando a limitação de que ninguém consegue conhecer sempre todas as partes de um sistema grande demais
- O processo de revisão ajuda a reduzir o bus factor e faz com que vários integrantes da equipe se familiarizem mais com a base de código e com a cultura de código do time
- Se todos passarem a aprovar sem ler, perde-se esse efeito de aprendizado, e o bus factor não só sobe para 1 como também surge o problema de externalização para terceiros
- A resposta final é que, para aceitar a exigência de colocar em produção código não lido, a pessoa que deu essa ordem precisaria oferecer uma isenção formal de responsabilidade por bugs, problemas de segurança, downtime etc.
1 comentários
Opiniões no Lobste.rs
Sinto uma forte rejeição à ideia de que o objetivo do review é distribuir responsabilidade
Se um código mesclado na main quebrar a produção, a responsabilidade é do autor, não minha nem da equipe inteira
Como profissional, é um trabalho com a sua assinatura, e se o projeto de uma ponte carimbado com uma licença P.E. de engenharia civil matar alguém, isso também é trabalho e responsabilidade da própria pessoa
A responsabilidade da equipe, como desenvolvedores e mantenedores da base de código, é garantir que o código de qualquer pessoa não possa quebrar a produção
Mesclar na main significa que alguém revisou, examinou as mudanças, discutiu o design, pediu várias revisões e aprovou
Ninguém constrói a Torre Eiffel sozinho, e culpar indivíduos no trabalho só gera ressentimento e uma cultura tóxica
Se for um padrão de comportamento repetitivo, isso é algo para o RH tratar
Se a responsabilidade é zero, o revisor é inútil e não há motivo para fazer review
Distribuir responsabilidade é mais uma consequência; o objetivo central é encontrar erros que sozinho é fácil deixar passar, mas com duas ou mais pessoas é mais difícil
Ainda assim, acho que review é usado em excesso no software, e review não pode ser substituto de engenharia
Não acho preciso tratar “aprovar sem ler o código” como equivalente a “aprovar sem pensar”
Por exemplo, e se o programa vier com uma prova de correção, as definições e os teoremas puderem ser lidos no PR, o CI verificar com uma ferramenta determinística que o programa e a prova batem, também checar requisitos não funcionais como taxa de contraste, benchmark de desempenho e latência de cauda, e mudanças de UI puderem ser testadas facilmente em um protótipo?
Mesmo nesse mundo, é questionável se ainda haveria necessidade de tanta obsessão em ler o código linha por linha como hoje
Mesmo hoje, a maioria das pessoas escreve SQL sem verificar uma por uma se o plano de consulta corresponde exatamente ao que queria
O texto original me parece mais próximo de “vamos definir um mundo ideal em que possamos sentir que tudo bem implantar sem literalmente ler o código” e depois perguntar “como podemos nos mover de forma suave do presente para esse mundo?”
Dá para discutir o quão longe a indústria, ou uma empresa/base de código específica, está desse ponto, mas se imaginarmos esse mundo ideal com seriedade, a maioria das pessoas provavelmente vai pensar em alguns critérios
Entendo por que, com a direção atual da indústria, isso pode soar como “sem pensar”, mas não acho que seja isso que o texto da Charity quer dizer
Isso exige ler o código, não importa quão bons sejam os testes
Se Alice coloca o código, Bob revisa e depois Alice sai de férias, Bob precisa conhecer suficientemente aquela parte e sentir responsabilidade para poder corrigir ou adicionar novos recursos
Se Bob apenas carimba a prova de correção, depois ele não estará preparado para lidar com aquela base de código
Mesmo tendo participado do processo de commit, se não aumentaram seu conhecimento nem seu senso de pertencimento, na prática é como se não tivesse participado
A diferença é que compiladores são determinísticos, enquanto LLMs são ferramentas não determinísticas que potencialmente geram testes duvidosos
Já temos programas que transformam instruções ou código escritos por humanos em código legível por máquina ou em representações intermediárias, e podemos confiar no resultado gerado sem inspecionar a saída porque há garantias sobre a relação entre entrada e saída
Às vezes lemos a saída do compilador com ferramentas como o Godbolt para otimização, mas fora isso em geral não é necessário
Tentar isso em outro nível de abstração não determinístico pode parecer plausível, mas é só uma imitação das garantias de correção fornecidas por compiladores e no fim vai dar problema
Vejo o debate sobre LLMs, mais fundamentalmente, como um sintoma do fato de que as linguagens de programação determinísticas existentes não são expressivas o bastante e as ferramentas não são eficazes o suficiente
Pode parecer que LLMs resolvem esse problema, mas não são a solução real; é só colocar mais uma camada indireta e mais custo de desempenho sobre uma base já limitada demais
Parece mais um pseudo-compilador caro e cheio de bugs rodando em cima de um interpretador e, por sua vez, sobre código de máquina compilado
Por isso considero um beco sem saída técnico
Para empresas, pode ser um caminho de lucro no curto prazo, mas não acredito que vá melhorar o software nem a relação dos humanos com o uso e a criação de software
Software é mais do que apenas uma tecnologia para lançar produtos
Ajuda pensar nisso dividido por caso de uso
Se for apenas subir um novo JavaScript para a UI de uma aplicação interna, acho aceitável não precisar examinar até o CSS