Revisión de neural-slop
Neural-slop no es un estilo, sino afirmaciones que no se respaldan y código que no tiene razón de existir. Cada hallazgo a continuación se verifica con un hecho: una línea de código, la salida de un comando, la ausencia de un consumidor. Las observaciones de gusto y lo que atrapa un linter no entran aquí.
Principios.
- Eliminar es mejor que añadir. Una opción muerta se elimina, no se documenta; una frase de marketing se reemplaza por un hecho o se quita.
- La afirmación se verifica con el código, no de memoria. Antes de calificar una línea del README como falsa o verdadera, abre el archivo del que habla.
- Un hallazgo sin prueba no es un hallazgo. Si no puedes mostrar
file:lineo la salida de un comando, no escribas. - Las correcciones solo a petición. Por defecto, el resultado de la revisión es una lista.
1. Flujo de trabajo
- Define el alcance: diff (
git diff main...HEAD), archivos concretos o todo el repositorio antes de publicación. - Ejecuta las búsquedas de la sección 3: dan candidatos, no hallazgos.
- Verifica cada candidato leyendo el código y descarta los falsos positivos.
- Aplica la lista de verificación de la sección 2 sobre lo que la búsqueda no atrapa: README contra código, estados de UI, abstracciones.
- Si es posible ejecutar la aplicación, mira las páginas: las pantallas de plantilla y los componentes sin estilo se ven de inmediato.
- Emite un informe en el formato de la sección 4.
2. Lista de verificación
2.1. Restos de generadores y plantillas
- Páginas de inicio y bloques de generadores: «Get started by editing», enlaces a la documentación del framework y herramientas,
utm_source=…-project, «Give us a star», bloques sobre servicios en la nube de la herramienta. - Archivos de plantilla:
example.spec.ts, pruebas que solo verifican el título de la plantilla; SVG e imágenes de la plantilla enpublic/; README del generador. - Stubs vacíos:
.gitkeepen carpetas que ya tienen archivos;index.tsvacíos; carpetas de capas sin código.
2.2. Código muerto e incompleto
- Valores de configuración o ramas
switchque lanzan «not implemented» / «pending». - Enumeraciones con un solo valor que parecen puntos de extensión (
type: "graphql" | "msw", dondemswno está implementado). - Código comentado,
TODOsin motivo ni enlace, exportaciones no utilizadas, dependencias enpackage.jsonque no se importan en ningún sitio. - Scripts en
package.jsonque no se ejecutan (referencian archivos eliminados, objetivos inexistentes).
2.3. Documentación contra código
Cada afirmación del README, ADR, comentarios y descripciones de commits se verifica:
- Nombres y rutas: los archivos, comandos, variables de entorno mencionados existen (
next.config.tsen el texto ynext.config.jsen el repositorio es un hallazgo). - Comportamiento: «las solicitudes van directamente», «los tokens no están accesibles para JS», «protegido contra open redirect»: encuentra el código que lo hace y verifica los casos límite.
- Versiones y números: versiones de librerías, tiempos de vida de tokens, cobertura.
- Futuro en presente: lo que está planificado se describe como hecho.
- Los enlaces y anclajes en Markdown llevan a donde deben (los anclajes se rompen al modificar encabezados).
2.4. Tono
- Palabras valorativas en lugar de hechos: premium, state-of-the-art, cutting-edge, blazing/lightning-fast, seamless, robust, powerful, modern, production-ready, enterprise-grade, «más que solo», «premium», «moderno», «potente».
- Emojis en encabezados de documentación, en la UI, en logs y mensajes de commit.
- «Designed with ❤️», «Carefully crafted», insignias por las insignias.
- Comentarios que parafrasean («// Obtener usuario» sobre
getUser()), comentarios-historial («// Corregido», «// Actualizado a X»), comentarios en mayúsculas, marcas «IMPORTANT» sin explicación. - Encabezados y comentarios estilo «🚀 Production Roadmap» y «(Premium Aesthetic)».
Sustitución: un hecho (qué hace, por qué es así, qué limitación tiene).
2.5. Abstracciones innecesarias
- Una interfaz o fábrica con una sola implementación y sin un mock en las pruebas.
- Una capa, zona, paquete de monorepo, gestor de estado, Storybook sin consumidor o sin una razón documentada (ADR, sección del README).
- Envoltorios que solo renombran (
useAuthApi = () => useStrictContext(Ctx)sin lógica es aceptable; un envoltorio sobre otro envoltorio no). - «Para el futuro»: parámetros que nadie pasa, opciones de configuración con un solo valor.
2.6. Errores y asincronía
- El tipo de error se determina por el texto del mensaje (
message === "unauthorized",includes("invalid password")) sin comentario de motivo ni pruebas. - Solo se verifica el primer elemento del array de errores (
errors[0]). throw { status, ... }— un objeto en lugar deError.catchvacío,catchque devuelve datos vacíos,.catch(() => {}).- Una promesa compartida en vuelo cuyo resultado los que esperan no leen (refresh de token «esperamos, luego reintentamos» sin verificar si tuvo éxito).
error.messagedel servidor se muestra al usuario tal cual.- Faltan estados de carga, error, lista vacía.
2.7. Seguridad y privacidad
- Datos personales en logs: email, teléfono, nombre; tokens; cuerpos de solicitudes.
- Secretos en el repositorio o en el historial (
git log -p),.enven el índice, secretos con prefijoNEXT_PUBLIC_. - Redirecciones por parámetro (
callbackUrl,next,returnTo) sin verificación, o con verificación solo destartsWith("/")/!startsWith("//")— permite/\evil.comy caracteres de control. - Tokens en
localStorage/sessionStorage; token en la URL que no se elimina de la barra de direcciones después de leerlo. dangerouslySetInnerHTMLsin sanitizador.
2.8. UI
- Clases que no existen en el tema: tokens copiados de shadcn/ui (
bg-card,text-muted-foreground,bg-primary) en un proyecto sin esos tokens: el componente queda sin estilos silenciosamente. - Valores HEX crudos y valores arbitrarios en componentes cuando existen tokens.
- Estado «campo lleno» establecido en
onChange: se rompe con autocompletado yreset(). key={index}en listas mutables; botones sintypedentro de formularios; botones de icono sinaria-label.- SVG del diseño con filtros (sombras, resplandor) recortados por
viewBox: un rectángulo visible alrededor del logotipo.
2.9. Pruebas
- Pruebas que verifican mocks, no comportamiento; snapshots de árboles grandes.
- e2e contra un backend general o de producción, que modifican datos.
- Pruebas que solo pasan porque jsdom no aplica CSS (un elemento «oculto» por una clase, y la prueba lo encuentra), y selectores amplios (
/password/i, que también coincide con «Show password»).
2.10. Git
- Cambios no relacionados en un mismo commit; commit «fix stuff».
- Archivos generados y artefactos de compilación en el índice (excepto un cliente API generado comprometido deliberadamente).
- El mensaje del commit describe algo que no está en el diff.
3. Búsqueda de candidatos
Los comandos dan candidatos. Cada coincidencia se verifica leyendo el código.
# Plantillas de generadores y marketing
rg -n -i "utm_source|get started by editing|give us a star|nx cloud|welcome to|carefully crafted|designed with" \
--glob '!**/node_modules/**' --glob '!*.lock' --glob '!pnpm-lock.yaml'
rg -n -i "premium|state-of-the-art|cutting-edge|blazing|lightning|seamless|robust|enterprise-grade|production-ready|премиальн|современн|мощн" \
--glob '!**/node_modules/**'
# Emojis en código, UI y documentación
rg -n --pcre2 '[\x{1F300}-\x{1FAFF}\x{2600}-\x{27BF}]' --glob '!**/node_modules/**' --glob '!*.lock'
# Código incompleto
rg -n -i "not implemented|pending implementation|todo|fixme|hack" --glob '!**/node_modules/**'
# Errores frágiles
rg -n "errors\?\.\[0\]|errors\[0\]|message ===|message\.includes|\.includes\(['\"][a-z ]+['\"]\)" src app
rg -n "throw \{" src app
rg -n "catch \{\s*\}|catch \(\w*\) \{\s*\}|\.catch\(\(\) => \{\s*\}\)" src app
# Logs con datos personales
rg -n "(logger|console)\.\w+\(.*(email|phone|password|token)" src app
# Redirecciones y tokens
rg -n "callbackUrl|returnTo|redirectTo|searchParams.get\(['\"]next" src app
rg -n "localStorage|sessionStorage" src app
# Clases shadcn sin tokens: encuentra clases y compáralas con @theme / configuración de tailwind
rg -n -o "\b(bg|text|border)-(card|muted|popover|accent|primary|secondary|destructive)(-foreground)?\b" src app | sort -u
# Dependencias y exportaciones no utilizadas (si knip está instalado)
pnpm dlx knip
# Secretos en el historial
git log -p --all | rg -n -i "(api[_-]?key|secret|password|token)\s*[:=]\s*['\"][A-Za-z0-9_\-]{16,}"
git ls-files | rg -n "(^|/)\.env($|\.)" | rg -v "\.env\.example$"
4. Formato del informe
Los hallazgos se ordenan por importancia descendente: seguridad y privacidad → afirmaciones falsas en la documentación → errores de manejo de errores → código muerto e incompleto → plantillas → tono.
<archivo>:<línea> — <categoría>
Qué: <una frase: qué está mal, con el hecho>
Por qué es importante: <consecuencia para el usuario, revisor o soporte>
Corrección: <concreta; la mayoría de las veces «eliminar» o «reemplazar por un hecho: …»>
Al final: qué se verificó y no dio hallazgos, y qué no se verificó (por ejemplo, la aplicación no se ejecutó). Si no hay hallazgos, dilo claramente, sin observaciones forzadas.