De-slop: hacer que el código generado sea indistinguible del de un humano cuidadoso
El slop no es un problema de estilo, es un problema de confianza. Los revisores que detectan un slop dejan de leer el código y empiezan a buscar más. La solución nunca es solo cosmética: cada paso a continuación verifica la necesidad, no solo la apariencia.
Trabaja a partir del diff real, nunca de la memoria de lo que escribiste. Si el trabajo abarca ramas, audita el diff de cada rama contra su base de fusión.
Paso 0 — escribe poco, justifica cada línea (la prevención es mejor que la limpieza)
El slop es más barato de eliminar antes de que exista. Al construir:
- Construye pieza por pieza. Comienza con el cambio más pequeño que haga una sola cosa; hazlo correcto e idiomático antes de agregar la siguiente pieza. Un diff grande escrito de una sola vez siempre acumula slop; N pequeños incrementos, cada uno revisado según esta habilidad, no lo hacen. Esto también produce PRs pequeños, que los revisadores confían y aprueban consistentemente más rápido que uno grande.
- Interroga cada línea en el momento de creación: ¿por qué existe esta línea? ¿Por qué es una nueva función en lugar de una llamada a una existente? ¿Por qué un nuevo archivo? Si la respuesta es "la generación fluyó así", elimínala o intégrala. Cada adición necesita una razón que puedas expresar en voz alta durante la revisión.
- No compliques. La versión obvia de 5 líneas es mejor que la versión abstracta de 25 líneas hasta que exista un segundo llamador. Sin parámetros especulativos, sin "flexibilidad para el futuro", sin tipos envolventes para un solo valor.
- No reinventes la rueda — en el momento de la autoría, no solo en la limpieza: antes de escribir cualquier utilidad, busca en el repositorio un helper existente y verifica el árbol de dependencias para ver si algún paquete ya maneja el problema (ver Paso 2).
- Iguala el vecindario antes de escribir. Lee primero los archivos adyacentes; adopta sus nombres, manejo de errores y configuración de pruebas para que el nuevo código parezca que siempre estuvo allí.
Si la tarea no se puede construir pieza por pieza (un port grande, un contrato vendido), dilo y compensa con una auditoría más estricta de los Pasos 1–5 antes de que alguien más lo vea.
Paso 1 — comentarios
El indicio más grande. Aplica una regla: un comentario debe expresar una restricción que el código no puede mostrar. Todo lo demás se elimina.
Eliminar a la vista:
- Narración:
// iterar sobre las entradas,// llamar al helper,// devolver el resultado - Repetir el código o su propio encabezado de documentación una segunda vez en el cuerpo
- Charla de revisor:
// esto es seguro porque verificamos arriba,// nota que...— eso eres tú defendiendo el diff, no informando al próximo lector - Referencias al PR, la revisión, la conversación o "cambiado recientemente"
- Comentarios que explican por qué el cambio es correcto (pertenecen al cuerpo del PR)
- Banners de sección (
// ---- helpers ----) en archivos de menos de ~300 líneas
Mantener (estos son críticos):
- Restricciones de formato de conexión o protocolo, especialmente las de ingeniería inversa sin especificación pública: el campo X debe estar presente incluso cuando es nulo; el cliente Y rechaza todo el payload si falta Z; cita el archivo fuente ascendente
- Comentarios de por qué no: por qué se rechazó el enfoque obvio, qué rompe
- Hechos de plataforma en los que el lector tropezará: esta variable de entorno es una convención de Unix; esta API se silencia en Windows
- Invariantes de seguridad/protección de datos: nunca almacenar en caché el registro sin procesar, incrusta secretos
- Anclajes de política deliberados que contradicen los valores predeterminados aguas arriba, con la condición de elevación
Heurística de densidad, no una regla: para código de pegamento/CRUD, más de ~1 línea de comentario por cada 15 líneas agregadas merece una segunda mirada. Para código de protocolo no documentado, la alta densidad puede ser correcta: los comentarios SON la especificación. Juzga cada comentario por las listas de mantener/eliminar, nunca solo por el conteo.
Encabezados de documentación: 4–8 líneas de restricciones puras. Si un encabezado es un párrafo que narra paso a paso lo que hace el módulo, redúcelo a lo que el nombre del archivo y las exportaciones no pueden decir ya.
Paso 2 — código hecho a mano que ya existe como dependencia o en la biblioteca estándar
El segundo indicio más grande: reimplementar uuid, hash, análisis semver, coincidencia de glob, matemáticas de fechas, fusión profunda.
Procedimiento:
- Revisa de qué depende ya el paquete (lee package.json, no la memoria). Prefiere una dependencia existente o la biblioteca estándar del runtime sobre agregar algo nuevo.
- Si una nueva dependencia está justificada, elige la aburrida y probada en batalla.
- Antes de reemplazar una implementación hecha a mano existente, demuestra la equivalencia empíricamente — ejecuta ambas contra las mismas entradas y compara las salidas. El código de ID determinista y hash especialmente: un intercambio que cambia las salidas rompe silenciosamente la idempotencia para los usuarios existentes.
- Si mantener la versión hecha a mano es genuinamente correcto (evita una dependencia para 10 líneas), espera la pregunta del revisor y decide si el argumento vale más que la dependencia. Generalmente no lo es: lo aburrido gana en la revisión.
- Excepción: el código que ya es composición de la biblioteca estándar (createHash + pipeline) no es hecho a mano. Dilo si te preguntan; no lo envuelvas más.
Paso 3 — cohesión y necesidad
El slop se acumula: cada edición añade sin consolidar. Busca:
- Expresiones de condición repetidas → extrae una vez, nombra por significado
(
noHayCambiosDeConfig, nocheck1) - El mismo literal en N archivos → una constante compartida en el módulo que posee el concepto; los adoptantes la importan
- Reimplementaciones locales de ayudantes del repositorio → busca un helper existente antes de mantener una copia privada (
existeRuta, utilidades de salida/formato, ayudantes de error). Elimina la copia local, importa la compartida. - Código muerto: para cada helper/tipo/exportación en el diff, encuentra un consumidor. Sin consumidor → elimina ahora, no "para más tarde".
- Sitios de llamada que hacen a mano lo que posee un helper (espaciado, comillas, generación de ID) → mueve el comportamiento al helper, adelgaza los sitios de llamada
- El mismo hecho expresado dos veces (encabezado de documentación + comentario en línea) → mantén uno
- Funciones que devuelven tuplas de valores débilmente relacionados → a menudo señal de que dos responsabilidades se fusionaron; divide o documenta el contrato
Luego verifica el ajuste al repositorio: lee archivos vecinos y empareja su modismo, nombres, estilo de errores y patrones de prueba. El código que ignora el estilo de la casa parece generado incluso cuando es correcto.
Paso 4 — pruebas
- Las pruebas deben fijar el comportamiento, no el error. Si una aserción codifica el valor incorrecto "porque eso es lo que hace el código", corrige ambos.
- Refleja el harness y los helpers existentes del conjunto de pruebas; no inventes un estilo de simulación paralelo en el mismo archivo.
- Cada salto específico de plataforma lleva una razón de una línea.
- Los nombres de las pruebas describen el escenario, no la implementación.
- Cuando cambies la forma de la salida, añade una aserción negativa para la forma eliminada.
Paso 5 — paridad de herramientas, luego verifica
- Usa la versión fijada del formateador/linter del repositorio (lee package.json — ejecutar una versión principal diferente localmente deja pasar fallos que solo aparecen en CI).
- Ejecuta las pruebas que toca el diff en cada capa de un cambio apilado, no solo en la punta.
- Reaudita el diff final una vez más después de todas las ediciones:
git diffy lee en voz alta cada línea de comentario restante contra el Paso 1. Verificación de densidad:git diff | grep -cE '^\+\s*(//|\*)'contra el total de líneas añadidas. - Mensajes de commit: explica por qué, en prosa, como una persona. Sin listas de cambios con viñetas para un commit de 3 líneas, sin "mejorado/mejorado/robusto".
Reporte
Cuando se pregunte "¿esto está deslopado?": audita el diff en vivo y responde con evidencia (números de densidad, qué se eliminó, qué se mantuvo deliberadamente y por qué), nunca "sí" de memoria. Si se mantuvo algo que un revisor podría señalar —como un archivo de protocolo de alta densidad— nómbralo proactivamente y da la defensa en una oración.
Cuando un revisor llama algo slop: concede el patrón antes de defender cualquier instancia. Corrige la categoría en todas partes, incluidos archivos que no señalaron (y los que elogiaron). Aplicar el estándar como disciplina, no como control de daños en líneas señaladas, es lo que reconstruye la confianza.