CommunityProgramación y desarrollogithub.com

JoshuaKGoldberg/lint-rule-review-skill

Revisa una regla de lint personalizada como lo haría un mantenedor experimentado de ESLint, typescript-eslint y Flint, encontrando bugs mutando la regla y ejecutando casos de prueba adversariales.

¿Qué es lint-rule-review-skill?

Este skill simula la revisión profunda de reglas de lint que realizaría un mantenedor con gran experiencia, enfocándose en un enfoque empírico: no solo leer la regla, sino tratar de romperla. Funciona verificando condiciones, mutándolas para encontrar supervivientes (código no cubierto por pruebas), y generando casos de prueba adversariales. El skill analiza el diseño de la regla, revisa cada línea añadida, y aplica una batería de comprobaciones sobre nombres, condiciones, rendimiento, simplificaciones y documentación. Está diseñado para repositorios de plugins de ESLint, typescript-eslint, Flint y otros linters. Al final, genera un archivo de revisión detallado con el veredicto y comentarios prioritizados, listo para ser compartido con el usuario. Su principal ventaja es reducir el ruido en las revisiones automatizadas, enfocándose en hallazgos respaldados por pruebas reales o mutaciones.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/JoshuaKGoldberg/lint-rule-review-skill/tree/HEAD/skills/lint-rule-review-skill

Installed? Explore more Programación y desarrollo skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Habilidad de Revisión de Reglas de ESLint

Revisa una regla de lint como lo haría un mantenedor con miles de comentarios de revisión pasados. El hábito definitorio de ese mantenedor es empírico: no solo leen una regla, intentan romperla. Eliminan una condición y ven si falla una prueba, e inventan la sintaxis en la que nadie pensó. Sigue ese hábito aquí. Un hallazgo respaldado por una prueba fallida o un mutante sobreviviente vale mucho más que uno que suene plausible, y el ruido que suena plausible es lo que hace que las revisiones automatizadas sean ignoradas.

Los hallazgos van al usuario, quien decide qué hacer con ellos. Escribir la revisión en un archivo local es todo el trabajo: publicar en GitHub, o enviar cualquier cosa, solo ocurre si el usuario lo solicita por separado.

1. Comprender el cambio

Determina qué está bajo revisión: un PR, una rama o un archivo de regla. Para un PR, revisa su commit head si puedes, porque los pasos posteriores ejecutan el código.

Lee esto antes de formarte opiniones:

  • La regla, sus pruebas y su página de documentación
  • La descripción del PR y el issue vinculado, porque una regla se juzga contra su propósito, no contra su propio algoritmo
  • Dos o tres reglas hermanas en el mismo repositorio, además de la documentación CONTRIBUTING

Anota cualquier pregunta que el autor haga en la descripción. La revisión debe responderla.

Las convenciones del repositorio prevalecen sobre las referencias de esta habilidad. Las referencias provienen de varios proyectos, así que si un patrón contradice lo que el repositorio claramente hace, sigue el repositorio.

Las referencias son grandes, así que no las leas de principio a fin. Comienza desde references/index.md, que enumera cada patrón, y extrae solo las secciones que se ajustan a este cambio. También lee references/extra-checks.md, que es corta y cubre las trampas de herramientas más las comprobaciones para fixers, reglas de importación y Flint.

2. Verificar el diseño de la regla

Elige de la lista design.md en el índice según el tipo de cambio:

  • Regla nueva: si pertenece, su alcance, superposición con otras reglas, información de tipo, opciones y colocación en presets.
  • Cambio a una regla establecida: impacto semver, reglas hermanas que necesitan el mismo cambio, y si el cambio sirve al issue. Omite el resto.

Si el PR está en bruto, como que aún no tiene pruebas o un diseño que necesita replanteamiento, detente en una revisión de alto nivel y dilo, y omite la mutación, que no puede decirte nada sin pruebas. Aún así prueba la regla en algunos casos, ya que un error real vale la pena reportarlo en cualquier etapa. Los comentarios detallados sobre código que está a punto de cambiar pierden el tiempo de todos.

3. Leer cada línea añadida

Usa el índice para extraer las secciones que coinciden con lo que cambió:

CambiadoBuscar en
Lógica de la reglabugs.md, simplification.md, performance.md
Fixers o sugerenciasfixes.md
Mensajesmessages.md
Pruebastest-method.md
Páginas de documentacióndocs.md
Nuevos nombres, opciones o reglasnaming.md

Haz esto antes de intentar romper nada, porque la caza de errores se apodera una vez que comienza. Toma notas mientras avanzas, y ordénalas en el paso 5.

Revisa el diff una línea añadida a la vez y pregúntate esto de cada una:

  • Nombres: ¿podrías saber qué contiene o hace este identificador sin leer más? Presta atención a los nombres que describen un tipo en lugar de un propósito, y a los nombres que reclaman la acción incorrecta. Si te tomó una segunda lectura entenderlo, dilo y sugiere un mejor nombre.
  • Locales: ¿esta variable se usa una vez, justo después de establecerse? Sugiere inlinearla.
  • Condiciones: ¿colapsa? !x || x.kind !== y se convierte en x?.kind !== y. Los if anidados o adyacentes a menudo se fusionan, y un if booleano a menudo devuelve directamente.
  • Guardias: ¿realmente puede ocurrir este estado, dado el AST y el código anterior?
  • Reutilización: ¿una utilidad compartida ya hace esto? Verifica antes de aceptar cualquier helper. ¿Un helper necesitaría menos parámetros si viviera dentro de create?
  • Longitud: ¿hay menos código que haga lo mismo? La simplificación es la categoría más grande en revisiones pasadas.
  • Vale la pena hacerlo: ¿este código o TODO planifica algo que nadie necesita? Di que puede irse.

Si el código parece asistido por IA, léelo con un ojo más crítico, porque ahí es donde tiende a acumularse el relleno.

Revisa cada comentario y cada frase de documentación. La caza de errores desplaza esto, sin embargo es una fuente regular de comentarios de revisión reales, así que hazlo como un pase separado sobre cada comentario añadido y cada línea de documentación añadida. No preguntes si es correcto, pregúntate si debería estar ahí tal como está escrito:

  • ¿Este comentario se volverá obsoleto? Las notas sobre cobertura de pruebas, historial o lo que cubre una prueba sí lo hacen, así que sugiere eliminarlas.
  • ¿Replantea el código? Sugiere eliminarlo.
  • ¿Es un atajo significativo conocido, como un fork de código ascendente? Pide un TODO, con un enlace al issue si existe, y sugiere el comentario exacto.
  • ¿A un usuario final le importaría esta frase de documentación? Los detalles de implementación no pertenecen a la página.
  • ¿Este ejemplo de documentación lleva código que no necesita? Sugiere recortar cualquier cosa más allá de lo que muestra el comportamiento.
  • ¿La frase es precisa? Presta atención a las redacciones que suenan universales o siempre verdaderas cuando no lo son, y sugiere una reescritura.

Da estos como bloques ```suggestion. Son rápidos para que el autor los acepte.

Nota lo que está bien. Anota cualquier cosa que te haya ayudado a revisar o que maneje algo complicado, y menciónalo específicamente, en el cuerpo de la revisión o como un comentario [Praise].

4. Intentar romperlo

Este paso produce los hallazgos de mayor valor, así que no lo omitas. Comienza por hacer que las pruebas existentes de la regla pasen, para tener un comando funcional que ejecute solo las pruebas de esta regla.

Muta las condiciones. Ejecuta el script incluido desde la raíz del repositorio. Necesita Node 22.18 o más reciente, que puede diferir de la versión que el repositorio fija. Cada mutante es una ejecución de prueba, así que ejecútalo en segundo plano. Edita la regla en su lugar, así que cualquier otra cosa que ejecutes mientras tanto debe usar una copia de la regla guardada bajo un nombre temporal:

node <skill-dir>/scripts/mutate-conditions.ts --file <rule> --test "<test command>" --base <base ref>

--base limita los mutantes a las líneas que el PR cambió, y --diff <file> hace lo mismo desde un diff. Omite ambos para mutar una regla nueva completa. Los mutantes se ejecutan en orden de fuente hasta --max, 60 por defecto, así que auméntalo si el resumen muestra alguno no probado. Si las pruebas se ejecutan desde una carpeta de paquete, ejecuta el script desde allí. --out <file> guarda los resultados completos, y una lista corta de supervivientes siempre se imprime al final. Primero verifica que las pruebas fallan cuando la regla lanza una excepción, y se detiene si no lo hacen, porque entonces no están ejercitando la regla. El script restaura el archivo cuando termina o se detiene. Si se mata directamente, la siguiente ejecución se niega a comenzar e imprime dónde se guardó el original, así que compara los dos antes de cambiar la regla, porque es posible que la hayas editado desde entonces. Si el comando de prueba construye la regla, reconstruye después, porque el resultado de la compilación aún tiene el último mutante. Analiza con el typescript del repositorio, y en TypeScript 7 o posterior imprime cómo pasar una copia anterior con --typescript.

Los mutantes que las pruebas no notan son supervivientes: cada uno significa que falta una prueba o el código está muerto, y debes determinar cuál. Elimina la condición y piensa qué entrada la necesitaría. Si no puedes construir una, recomienda eliminar el código. Si puedes, agrégalo al siguiente paso. Los supervivientes marcados como likelyTypeOnly son salidas de verificación nula simples que a menudo existen solo para el compilador, así que míralos al final, pero verifica que la rama no simplemente no esté probada. Si el ejecutor de pruebas verifica tipos, un mutante también puede "fallar" solo porque no compila, así que usa un comando de solo transpilación cuando puedas.

El script solo cubre mutaciones comunes. También prueba manualmente cualquier cosa que no pueda alcanzar y de la que dependa el PR, como intercambiar un argumento por una variable similar ya en el ámbito.

Compara head y base. Para un cambio en una regla existente, esta es la verificación más importante. Una regresión en código que solía funcionar importa mucho más que una brecha que ya estaba allí, y no puedes distinguirlas sin ejecutar ambas versiones. Guarda la versión base junto a la regla, por ejemplo con git show <base>:./<rule> > <rule-dir>/<name>.base-tmp.ts, o aplicando inversamente el diff. Luego copia assets/compare-rule.test.ts junto a las pruebas de la regla y ajusta sus líneas marcadas. Ordena cada caso comparando los recuentos de informes, y también registra mensajes, rangos, salida de fix, sugerencias, fallos y errores de compilación en cada fixture. Lee los resultados de CHANGED OUTPUT tú mismo, porque un mensaje o fix cambiado puede ser el error, e ignora cualquier caso con fixtureErrors hasta que su fixture compile. Para un PR que añade un fixer, la salida del fix y la sugerencia es lo principal a leer, así que establece expectedOutput en esos casos. Si el PR añade una opción, establece baseOptions para que el esquema de la versión base acepte el caso. Sin ello, el caso se juzga solo en head.

Para una regla nueva, impórtala como head y base, para que el arnés informe ok o WRONG en lugar de comparar versiones. Si el arnés no se ajusta al plugin, usa un archivo de prueba temporal en el arnés de pruebas del propio repositorio.

Escribe casos adversariales. Elige las categorías de references/test-cases.md que se ajusten a la sintaxis y tipos que esta regla toca, y escribe casos literales. Decide el comportamiento correcto antes de ejecutar cada caso, porque te impide racionalizar lo que sea que vuelva. Imprime también los datos del mensaje además de los recuentos de informes, ya que un nombre de tipo incorrecto en un mensaje también es un error. Empareja un caso en sintaxis nueva con un control en sintaxis antigua, como una clave de símbolo con el mismo caso usando una clave de cadena. Busca:

  • Fallos
  • Falsos positivos, donde se reporta código válido
  • Falsos negativos, donde no se reporta código inválido
  • Fixes que producen código inválido, cambian el comportamiento o eliminan comentarios
  • Rangos de reporte que son más amplios que el código infractor

Guarda los casos que expusieron algo para que puedan ir en la revisión como casos de prueba literales. Literal importa: este mantenedor pide casos escritos a mano y rechaza .map, fábricas y pruebas generadas.

Prueba sugerencias grandes. Si crees que un rediseño eliminaría varios errores, prototípalo y ejecuta las pruebas existentes. "267 de 268 pruebas pasan, y aquí está por qué falla la otra" es mucho más útil que una corazonada.

Limpia. Ejecuta git status y elimina cada archivo temporal antes de continuar, para que el repositorio vuelva a estar como lo encontraste.

5. Filtrar los hallazgos

Antes de escribir nada, revisa cada hallazgo:

  • Errores: incluye el caso y lo que realmente sucedió. Si no pudiste reproducirlo, elimínalo, o degradalo a un [Pregunta] si aún tienes una razón específica para sospecharlo.
  • Orden: las regresiones primero, luego los errores en código nuevo, luego los errores existentes que el PR toca.
  • Una causa raíz: si un rediseño solucionaría varios errores, haz un comentario y enumera los casos en él. Mantén un comentario separado solo cuando un error necesite su propia solución de cualquier manera, como una regresión.
  • Posiciones en disputa: trátalas como preguntas no bloqueantes: comprobaciones in en nodos, uso de esquery, forma del esquema de opciones y estilo import ts. Otros mantenedores han diferido razonablemente sobre ellos.
  • Ampliar o aplazar: si una brecha es el mismo concepto que la regla y los usuarios reales se encontrarían con ella, pídela en este PR. De lo contrario, sugiere un issue de seguimiento.
  • Añadir o eliminar una opción: pide una opción solo donde la regla de lo contrario prohibiría código válido, o donde un usuario real pidió una.
  • Código existente: omite los problemas que el PR no tocó a menos que sean graves, y márcalos como [No Accionable].
  • Duplicados: fusiona las repeticiones en un comentario que diga "aquí y en otros lugares".

El ruido cuesta más que un error: un autor que pasa por alto tres comentarios débiles también pasará por alto el real. Los comentarios bloqueantes deben ser solo lo que debe cambiar antes de fusionar. Mantén como máximo unos ocho comentarios no bloqueantes, eligiendo los que más mejoren el código, con una sugerencia lista para aplicar donde el comentario solicite un cambio. Elimina estos primero:

  • Cuestiones de gusto sin una ganancia real en claridad, como reformular un mensaje o colapsar un condicional que se lee bien
  • Cualquier cosa que la descripción diga que es deliberada, como andamios para trabajo planificado
  • Errores que intentaste y no pudiste encontrar un caso real, sin una razón específica restante para sospecharlos
  • Espacios en blanco y estilo de comillas
  • Solicitudes de proceso que no añaden nada, como un issue de seguimiento para cada pequeño TODO

No tener nada que reportar es un resultado perfectamente válido, así que no inventes hallazgos para parecer exhaustivo.

Haz coincidir el veredicto con los comentarios bloqueantes. Si nada bloquea, aprueba y deja el resto como sugerencias. Muchas revisiones de este mantenedor en PRs sólidos son una aprobación cálida con una o dos pequeñas solicitudes.

6. Escribir la revisión

Lee references/review-voice.md, luego escribe lint-rule-review-skill-<pr-or-rule>.md en el directorio actual, sin hacer commit. Mantén el cuerpo de la revisión en pocas frases, alargándolo solo para responder a las preguntas del autor o explicar una decisión de diseño. Usa esta estructura:

# Revisión de <PR o regla>

**Veredicto:** aprobar | solicitar cambios | solo alto nivel

<Cuerpo de la revisión, siguiendo el orden en review-voice.md>

## Comentarios en línea

### `path/to/file.ts:42` · bloqueante

[Error] <Comentario tal como se publicaría>

```ts
<Caso fallido literal o sugerencia>

Evidencia: <Lo que ejecutaste y lo que sucedió, o "no reproducido">

No verificado

<Cualquier cosa que no pudiste ejecutar o verificar, y por qué>


Marca cada comentario como `bloqueante` o `no bloqueante`, ordenando los bloqueantes primero. "Evidencia" es para el usuario y no se publicaría...

Skills relacionados