De-slop: tornar código gerado indistinguível do de um humano cuidadoso
Slop não é um problema de estilo, é um problema de confiança. Revisores que identificam um ponto de slop param de ler o código e começam a caçar mais. A correção nunca é apenas cosmética: cada passagem abaixo verifica necessidade, não apenas aparência.
Trabalhe a partir do diff real, nunca da memória do que você escreveu. Se o trabalho abranger múltiplos branches, audite o diff de cada branch contra sua base de merge.
Passo 0 — faça pequeno, justifique cada linha (prevenção é melhor que correção)
Slop é mais barato de remover antes de existir. Ao construir:
- Construa peça por peça. Comece com a menor mudança que faça uma coisa; deixe-a correta e idiomática antes de adicionar a próxima peça. Um diff grande escrito de uma vez sempre acumula slop; N pequenos incrementos, cada um revisado contra este skill, não. Isso também produz PRs pequenos, que revisadores consistentemente confiam e aprovam mais rápido do que um grande.
- Interrogue cada linha no momento da criação: por que essa linha existe? Por que isso é uma nova função em vez de uma chamada a uma existente? Por que um novo arquivo? Se a resposta for "o fluxo da geração foi assim", delete ou incorpore. Cada adição precisa de uma razão que você possa declarar em voz alta na revisão.
- Não complique demais. A versão óbvia de 5 linhas vence a versão abstraída de 25 linhas até que exista um segundo chamador. Sem parâmetros especulativos, sem "para flexibilidade futura", sem tipos wrapper em torno de um único valor.
- Não recrie a roda — no momento da autoria, não apenas na limpeza: antes de escrever qualquer utilitário, faça grep no repositório por um helper existente e verifique a árvore de dependências por um pacote que seja dono do problema (veja Passo 2).
- Combine com a vizinhança antes de escrever. Leia os arquivos adjacentes primeiro; adote sua nomenclatura, tratamento de erros e harness de teste para que o novo código pareça que sempre esteve lá.
Se a tarefa não puder ser construída peça por peça (uma grande migração, um contrato de fornecedor), diga isso e compense com uma auditoria Passo 1–5 mais rigorosa antes que qualquer outra pessoa veja.
Passo 1 — comentários
O maior indicador isolado. Aplique uma regra: um comentário deve declarar uma restrição que o código não pode mostrar. Todo o resto é deletado.
Delete sem hesitação:
- Narração:
// itera sobre as entradas,// chama o helper,// retorna o resultado - Repetição do código ou de seu próprio cabeçalho de doc uma segunda vez no corpo
- Conversa de revisor:
// isso é seguro porque verificamos acima,// note que...— isso é você defendendo o diff, não informando o próximo leitor - Referências ao PR, à revisão, à conversa, ou a "mudou recentemente"
- Comentários explicando por que a mudança está correta (pertence ao corpo do PR)
- Banners de seção (
// ---- helpers ----) em arquivos com menos de ~300 linhas
Mantenha (estes são estruturais):
- Restrições de formato de transmissão ou protocolo, especialmente aquelas engenheiradas reversamente sem especificação pública: campo X deve estar presente mesmo quando nulo; cliente Y rejeita todo o payload se Z estiver faltando; cite o arquivo fonte upstream
- Comentários de por que não: por que a abordagem óbvia foi rejeitada, o que quebra
- Fatos de plataforma com que um leitor vai tropeçar: esta variável de ambiente é uma convenção Unix; esta API silenciosamente não faz nada no Windows
- Invariantes de segurança/proteção de dados: nunca armazene em cache o registro bruto, ele contém segredos
- Fixações deliberadas de política que contradizem padrões upstream, com a condição de elevação
Heurística de densidade, não uma regra: para código de cola/CRUD, mais de ~1 linha de comentário por 15 linhas adicionadas merece uma segunda olhada. Para código de protocolo não documentado, alta densidade pode ser correta — os comentários SÃO a especificação. Julgue cada comentário pelas listas de manter/deletar, nunca apenas pela contagem.
Cabeçalhos de doc: 4–8 linhas de restrições puras. Se um cabeçalho é um parágrafo narrando o que o módulo faz passo a passo, reduza-o ao que o nome do arquivo e as exportações já não dizem.
Passo 2 — código artesanal que uma dependência ou stdlib já fornece
O segundo maior indicador: reimplementar uuid, hashing, análise de semver, correspondência de glob, cálculos de data, merge profundo.
Procedimento:
- Verifique do que o pacote já depende (leia package.json, não a memória). Prefira uma dependência existente ou a stdlib do runtime a adicionar algo novo.
- Se uma nova dependência for justificada, escolha a mais testada e entediante.
- Antes de substituir uma implementação artesanal existente, prove equivalência empiricamente — execute ambas com as mesmas entradas e compare saídas. Código de ID determinístico e hashing especialmente: uma troca que altera saídas quebra silenciosamente a idempotência para usuários existentes.
- Se manter a versão artesanal for genuinamente correto (evita uma dependência para 10 linhas), espere a pergunta do revisor e decida se o argumento vale mais do que a dependência. Geralmente não vale: o entediante ganha na revisão.
- Exceção: código que já é composição de stdlib (createHash + pipeline) não é artesanal. Diga isso se perguntado; não o envolva mais.
Passo 3 — coesão e necessidade
Slop se acumula: cada edição adiciona sem consolidar. Caçe:
- Expressões de condição repetidas → extraia uma vez, nomeie pelo significado (
noConfigChanges, nãocheck1) - O mesmo literal em N arquivos → uma constante compartilhada no módulo que é dono do conceito; adotantes importam-na
- Reimplementações locais de helpers do repositório → faça grep por um helper existente antes de manter uma cópia privada (
pathExists, utilitários de saída/formatação, helpers de erro). Delete a cópia local, importe a compartilhada. - Código morto: para cada helper/tipo/export no diff, encontre um consumidor. Nenhum consumidor → delete agora, não "para depois".
- Locais de chamada fazendo manualmente o que um helper já faz (espaçamento, citação, geração de ID) → mova o comportamento para o helper, afine os locais de chamada
- Mesmo fato declarado duas vezes (cabeçalho de doc + comentário inline) → mantenha um
- Funções que retornam tuplas de valores fracamente relacionados → muitas vezes é sinal de que duas responsabilidades foram fundidas; divida ou documente o contrato
Em seguida, verifique o ajuste ao repositório: leia arquivos vizinhos e combine seu idioma, nomenclatura, estilo de erro e padrões de teste. Código que ignora o estilo da casa parece gerado mesmo quando correto.
Passo 4 — testes
- Testes devem fixar comportamento, não o bug. Se uma asserção codifica o valor errado "porque é o que o código faz", corrija ambos.
- Espelhe o harness e helpers existentes da suíte; não invente um estilo de mock paralelo no mesmo arquivo.
- Cada pulo específico de plataforma carrega uma razão de uma linha.
- Nomes de teste descrevem o cenário, não a implementação.
- Quando você altera a forma da saída, adicione uma asserção negativa para a forma removida.
Passo 5 — paridade de ferramentas, depois verifique
- Use a versão fixada do formatador/linter do repositório (leia package.json — executar uma versão major diferente localmente permite que falhas de CI passem despercebidas).
- Execute os testes que o diff toca em cada camada de uma mudança empilhada, não apenas no topo.
- Re-audite o diff final mais uma vez após todas as edições:
git diffe leia cada linha de comentário restante em voz alta contra o Passo 1. Verificação de densidade:git diff | grep -cE '^\+\s*(//|\*)'versus total de linhas adicionadas. - Mensagens de commit: explique porquê, em prosa, como uma pessoa. Sem changelogs em lista de marcadores para um commit de 3 linhas, sem "melhorado/otimizado/robusto".
Reportando
Quando perguntado "isto está de-slopped?": audite o diff ao vivo e responda com evidência (números de densidade, o que foi deletado, o que foi deliberadamente mantido e por quê), nunca "sim" de memória. Se algo foi mantido que um revisor possa sinalizar — como um arquivo de protocolo de alta densidade — nomeie-o proativamente e dê a defesa em uma frase.
Quando um revisor chama algo de slop: conceda o padrão antes de defender qualquer instância. Corrija a categoria em todos os lugares, incluindo arquivos que eles não sinalizaram (e os que eles elogiaram). Aplicar o padrão como disciplina, não como controle de danos em linhas sinalizadas, é o que reconstrói a confiança.