Compétence de Révision de Règle ESLint

Réviser une règle de lint personnalisée comme le ferait un mainteneur expérimenté d'ESLint, typescript-eslint et Flint, en prouvant les bugs par mutation de la règle et en exécutant des cas de test adverses.

Qu'est-ce que Compétence de Révision de Règle ESLint ?

Cette compétence permet à un agent IA de réviser en profondeur une règle de lint ESLint, à la manière d'un mainteneur expérimenté. Elle va au-delà d'une simple lecture de code en adoptant une approche empirique : mutation des conditions pour trouver des survivants (tests manquants ou code mort), comparaison des versions head et base pour détecter les régressions, et rédaction de cas adverses pour trouver des faux positifs/négatifs, des crashs ou des correctifs invalides. La compétence guide l'agent à travers six étapes : comprendre le changement, vérifier la conception de la règle, lire chaque ligne ajoutée, essayer de casser la règle, filtrer les résultats et rédiger la révision. Elle est conçue pour les dépôts ESLint, typescript-eslint et Flint, et s'appuie sur des références détaillées (bugs, simplification, performance, correctifs, messages, méthodes de test, documentation, nommage, voix de révision, cas de test et contrôles supplémentaires). L'objectif est de produire des commentaires de haute qualité, étayés par des preuves expérimentales, et d'éviter le bruit qui rend les révisions automatisées inutiles.

Compatible avec~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 Développement et programmation skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Que fait Compétence de Révision de Règle ESLint ?

Révisez une règle de lint comme le ferait un mainteneur avec des milliers de commentaires de révision passés. L'habitude déterminante de ce mainteneur est empirique : il ne se contente pas de lire une règle, il essaie de la casser. Il supprime une condition et vérifie si un test échoue, et il invente la syntaxe à laquelle personne n'a pensé. Suivez cette habitude ici. Une conclusion étayée par un test qui échoue ou un mutant qui survit vaut bien plus qu'une conclusion qui semble plausible, et le bruit plausible est ce qui fait que les révisions automatisées sont ignorées.

Les conclusions sont transmises à l'utilisateur, qui décide quoi en faire. Écrire la révision dans un fichier local est l'ensemble du travail : publier sur GitHub, ou pousser quoi que ce soit, ne se produit que si l'utilisateur le demande séparément.

1. Comprendre le changement

Déterminez ce qui est en cours de révision : une PR, une branche ou un fichier de règle. Pour une PR, extrayez son commit head si possible, car les étapes suivantes exécutent le code.

Lisez ceci avant de vous faire une opinion :

  • La règle, ses tests et sa page de documentation
  • La description de la PR et le problème lié, car une règle est jugée par rapport à son objectif, pas par rapport à son propre algorithme
  • Deux ou trois règles apparentées dans le même dépôt, ainsi que les documents CONTRIBUTING

Notez toute question que l'auteur pose dans la description. La révision doit y répondre.

Les conventions du dépôt priment sur les références de cette compétence. Les références proviennent de plusieurs projets, donc si un modèle contredit ce que le dépôt fait clairement, suivez le dépôt.

Les références sont volumineuses, ne les lisez donc pas de bout en bout. Commencez par references/index.md, qui liste chaque modèle, et ne tirez que les sections qui correspondent à ce changement. Lisez également references/extra-checks.md, qui est court et couvre les pièges des outils ainsi que les vérifications pour les correctifs, les règles d'importation et Flint.

2. Vérifier la conception de la règle

Choisissez dans la liste design.md de l'index en fonction du type de changement :

  • Nouvelle règle : si elle a sa place, sa portée, le chevauchement avec d'autres règles, les informations de type, les options et le placement dans le préréglage.
  • Modification d'une règle établie : impact semver, règles apparentées qui nécessitent la même modification, et si la modification sert le problème. Ignorez le reste.

Si la PR est grossière, par exemple sans tests encore ou avec une conception qui nécessite une refonte, arrêtez-vous à une révision de haut niveau et dites-le, et sautez la mutation, qui ne peut rien vous apprendre sans tests. Essayez quand même la règle sur quelques cas, car un vrai bug mérite d'être signalé à n'importe quelle étape. Des commentaires détaillés sur du code qui est sur le point de changer font perdre du temps à tout le monde.

3. Lire chaque ligne ajoutée

Utilisez l'index pour tirer les sections qui correspondent à ce qui a changé :

ChangéRegarder dans
Logique de la règlebugs.md, simplification.md, performance.md
Correctifs ou suggestionsfixes.md
Messagesmessages.md
Teststest-method.md
Pages de documentationdocs.md
Nouveaux noms, options ou règlesnaming.md

Faites cela avant d'essayer de casser quoi que ce soit, car la chasse aux bugs prend le dessus une fois qu'elle commence. Prenez des notes au fur et à mesure, et triez-les à l'étape 5.

Passez en revue le diff ligne ajoutée par ligne ajoutée, et posez ces questions pour chacune :

  • Noms : pourriez-vous dire ce que cet identifiant contient ou fait sans lire plus loin ? Surveillez les noms qui décrivent un type plutôt qu'un objectif, et les noms qui revendiquent la mauvaise action. S'il a fallu une deuxième lecture pour comprendre, dites-le et suggérez un meilleur nom.
  • Variables locales : cette variable est-elle utilisée une fois, juste après avoir été définie ? Suggérez de l'inliner.
  • Conditions : est-ce qu'elle se réduit ? !x || x.kind !== y devient x?.kind !== y. Les if imbriqués ou adjacents se fusionnent souvent, et un if booléen renvoie souvent directement.
  • Gardes : cet état peut-il vraiment arriver, compte tenu de l'AST et du code ci-dessus ?
  • Réutilisation : existe-t-il déjà un utilitaire partagé qui fait cela ? Vérifiez avant d'accepter une aide. Un helper aurait-il besoin de moins de paramètres s'il vivait à l'intérieur de create ?
  • Longueur : y a-t-il moins de code qui fait la même chose ? La simplification est la plus grande catégorie dans les révisions passées.
  • Utilité : ce code ou TODO planifie-t-il quelque chose dont personne n'a besoin ? Dites qu'il peut disparaître.

Si le code semble assisté par IA, lisez-le avec un œil plus critique, car c'est là que le remplissage a tendance à s'accumuler.

Passez en revue chaque commentaire et chaque phrase de documentation. La chasse aux bugs éclipse cela, pourtant c'est une source régulière de véritables commentaires de révision, alors faites-le comme un passage séparé sur chaque commentaire ajouté et chaque ligne de documentation ajoutée. Ne demandez pas si c'est correct, demandez si cela devrait être là tel quel :

  • Ce commentaire deviendra-t-il obsolète ? Les notes sur la couverture de test, l'historique ou ce qu'un test couvre le deviennent, alors suggérez de les supprimer.
  • Reformule-t-il le code ? Suggérez de le supprimer.
  • S'agit-il d'un raccourci important connu, comme un fork de code amont ? Demandez un TODO, avec un lien vers le problème s'il en existe un, et suggérez le commentaire exact.
  • Un utilisateur final se soucierait-il de cette phrase de documentation ? Les détails d'implémentation n'ont pas leur place sur la page.
  • Cet exemple de documentation contient-il du code dont il n'a pas besoin ? Suggérez de supprimer tout ce qui dépasse ce qui montre le comportement.
  • La phrase est-elle précise ? Surveillez les formulations qui semblent universelles ou toujours vraies quand elles ne le sont pas, et suggérez une réécriture.

Donnez-les sous forme de blocs ```suggestion. Ils sont rapides à accepter pour l'auteur.

Remarquez ce qui est bon. Notez tout ce qui vous a aidé à réviser ou qui gère quelque chose de délicat, et mentionnez-le spécifiquement, dans le corps de la révision ou sous forme de commentaire [Praise].

4. Essayer de le casser

Cette étape produit les résultats de la plus haute valeur, ne la sautez donc pas. Commencez par faire passer les tests existants de la règle, afin d'avoir une commande fonctionnelle qui exécute uniquement les tests de cette règle.

Mutez les conditions. Exécutez le script fourni depuis la racine du dépôt. Il nécessite Node 22.18 ou plus récent, ce qui peut différer de la version épinglée par le dépôt. Chaque mutant est une exécution de test, alors exécutez-le en arrière-plan. Il modifie la règle sur place, donc tout ce que vous exécutez entre-temps doit utiliser une copie de la règle sauvegardée sous un nom temporaire :

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

--base limite les mutants aux lignes que la PR a modifiées, et --diff <file> fait de même à partir d'un diff. Omettez les deux pour muter une toute nouvelle règle. Les mutants s'exécutent dans l'ordre source jusqu'à --max, 60 par défaut, alors augmentez-le si le résumé montre des mutants non testés. Si les tests s'exécutent à partir d'un dossier de package, exécutez le script à partir de là. --out <file> sauvegarde les résultats complets, et une courte liste des survivants s'imprime toujours en dernier. Il vérifie d'abord que les tests échouent lorsque la règle lève une exception, et s'arrête si ce n'est pas le cas, car alors ils n'exercent pas la règle. Le script restaure le fichier lorsqu'il se termine ou est arrêté. S'il est tué directement, l'exécution suivante refuse de démarrer et imprime où l'original est sauvegardé, donc comparez les deux avant de modifier la règle, car vous avez peut-être modifié la règle entre-temps. Si la commande de test compile la règle, reconstruisez-la après, car la sortie de compilation contient encore le dernier mutant. Il analyse avec le typescript du dépôt, et sur TypeScript 7 ou version ultérieure, il imprime comment passer une copie plus ancienne avec --typescript.

Les mutants que les tests ne détectent pas sont des survivants : chacun signifie qu'un test manque ou que le code est mort, et vous devez déterminer lequel. Supprimez la condition et réfléchissez à l'entrée qui en aurait besoin. Si vous ne pouvez pas en construire une, recommandez de supprimer le code. Si vous le pouvez, ajoutez-la à l'étape suivante. Les survivants marqués likelyTypeOnly sont des sorties de vérification null nues qui existent souvent uniquement pour le compilateur, alors regardez-les en dernier, mais vérifiez que la branche n'est pas simplement non testée. Si le lanceur de test vérifie les types, un mutant peut aussi "échouer" simplement parce qu'il ne compile pas, alors utilisez une commande de transpilation uniquement quand vous le pouvez.

Le script ne couvre que les mutations courantes. Essayez également manuellement tout ce qu'il ne peut pas atteindre et dont la PR dépend, comme échanger un argument pour une variable similaire déjà dans la portée.

Comparez head et base. Pour une modification d'une règle existante, c'est la vérification la plus importante. Une régression dans du code qui fonctionnait auparavant est bien plus importante qu'une lacune qui était déjà là, et vous ne pouvez pas les distinguer sans exécuter les deux versions. Sauvegardez la version base à côté de la règle, par exemple avec git show <base>:./<rule> > <rule-dir>/<name>.base-tmp.ts, ou en appliquant le diff en sens inverse. Ensuite, copiez assets/compare-rule.test.ts à côté des tests de la règle et ajustez ses lignes marquées. Il trie chaque cas en comparant les décomptes de rapports, et il enregistre également les messages, les plages, la sortie de correctif, les suggestions, les crashs et les erreurs de compilation dans chaque fixture. Lisez vous-même les résultats CHANGED OUTPUT, car un message ou un correctif modifié peut être le bug, et ignorez tout cas avec fixtureErrors jusqu'à ce que sa fixture compile. Pour une PR qui ajoute un correctif, la sortie du correctif et de la suggestion est l'essentiel à lire, alors définissez expectedOutput sur ces cas. Si la PR ajoute une option, définissez baseOptions pour que le schéma de la version base accepte le cas. Sans cela, le cas est jugé sur la tête seule.

Pour une nouvelle règle, importez-la à la fois comme head et base, afin que le harnais rapporte ok ou WRONG au lieu de comparer les versions. Si le harnais ne correspond pas au plugin, utilisez plutôt un fichier de test temporaire dans le propre harnais de test du dépôt.

Écrivez des cas adverses. Choisissez les catégories parmi references/test-cases.md qui correspondent à la syntaxe et aux types que cette règle touche, et écrivez des cas littéraux. Décidez du comportement correct avant d'exécuter chaque cas, car cela vous empêche de rationaliser tout ce qui revient. Imprimez également les données du message ainsi que les décomptes de rapports, car un mauvais nom de type dans un message est aussi un bug. Associez un cas dans une nouvelle syntaxe avec un contrôle dans une ancienne syntaxe, comme une clé de symbole avec le même cas utilisant une clé de chaîne. Cherchez :

  • Crashs
  • Faux positifs, où un code valide est signalé
  • Faux négatifs, où un code invalide n'est pas signalé
  • Correctifs qui produisent du code invalide, changent le comportement ou suppriment des commentaires
  • Plages de rapports plus larges que le code incriminé

Conservez les cas qui ont exposé quelque chose afin qu'ils puissent aller dans la révision en tant que cas de test littéraux. Le caractère littéral est important : ce mainteneur demande des cas écrits à la main et s'oppose aux .map, aux fabriques et aux tests générés.

Prouvez les grandes suggestions. Si vous pensez qu'une refonte supprimerait plusieurs bugs, prototypagez-la et exécutez les tests existants. "267 tests sur 268 passent, et voici pourquoi l'autre échoue" est bien plus utile qu'une intuition.

Nettoyez. Exécutez git status et supprimez chaque fichier temporaire avant de continuer, afin que le dépôt soit revenu à l'état où vous l'avez trouvé.

5. Filtrer les résultats

Avant d'écrire quoi que ce soit, passez en revue chaque résultat :

  • Bugs : incluez le cas et ce qui s'est réellement passé. Si vous n'avez pas pu le reproduire, supprimez-le, ou rétrogradez-le en [Question] si vous avez encore une raison spécifique de le soupçonner.
  • Ordre : les régressions viennent en premier, puis les bugs dans le nouveau code, puis les bugs existants que la PR touche.
  • Une cause racine : si une refonte corrigerait plusieurs bugs, faites un seul commentaire et listez les cas dedans. Ne gardez un commentaire séparé que lorsqu'un bug a besoin de son propre correctif de toute façon, comme une régression.
  • Positions contestées : traitez-les comme des questions non bloquantes : les vérifications in sur les nœuds, l'utilisation d'esquery, la forme du schéma d'option et le style import ts. D'autres mainteneurs ont raisonnablement exprimé leur désaccord à leur sujet.
  • Élargir ou reporter : si une lacune est le même concept que la règle et que les vrais utilisateurs la rencontreraient, demandez-la dans cette PR. Sinon, suggérez un problème de suivi.
  • Ajouter ou supprimer une option : ne demandez une option que lorsque la règle interdirait sinon du code valide, ou lorsqu'un véritable utilisateur en a demandé une.
  • Code existant : laissez de côté les problèmes que la PR n'a pas touchés sauf s'ils sont graves, et marquez-les [Non-Actionable].
  • Doublons : fusionnez les répétitions en un seul commentaire qui dit "ici et ailleurs".

Le bruit coûte plus cher qu'un oubli : un auteur qui survole trois commentaires faibles survolera aussi le vrai. Les commentaires bloquants ne devraient être que ce qui doit changer avant la fusion. Gardez au maximum environ huit commentaires non bloquants, en choisissant ceux qui améliorent le plus le code, avec une suggestion prête à appliquer chaque fois que le commentaire demande une modification. Coupez d'abord ceux-ci :

  • Les questions de goût sans réel gain de clarté, comme reformuler un message ou simplifier une condition qui se lit bien
  • Tout ce que la description dit être délibéré, comme l'échafaudage pour un travail prévu
  • Les bugs que vous avez essayé et pour lesquels vous n'avez pas trouvé de cas réel, sans raison spécifique restante de les soupçonner
  • Les espaces blancs et le style de guillemets
  • Les demandes de processus qui n'ajoutent rien, comme un problème de suivi pour chaque petit TODO

N'avoir rien à signaler est un bon résultat, donc n'inventez pas de résultats pour paraître minutieux.

Faites correspondre le verdict aux commentaires bloquants. Si rien ne bloque, approuvez et laissez le reste comme suggestions. De nombreuses révisions de ce mainteneur sur des PR solides sont une approbation chaleureuse avec une ou deux petites demandes.

6. Rédiger la révision

Lisez references/review-voice.md, puis écrivez lint-rule-review-skill-<pr-or-rule>.md dans le répertoire courant, sans le valider. Limitez le corps de la révision à quelques phrases, en allant plus loin uniquement pour répondre aux questions de l'auteur ou expliquer une décision de conception. Utilisez cette structure :

# Révision de <PR or rule>

**Verdict :** approuver | demander des modifications | haut niveau uniquement

<Corps de la révision, en suivant l'ordre dans review-voice.md>

## Commentaires en ligne

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

[Bug] <Commentaire tel qu'il serait posté>

```ts
<Cas littéral qui échoue ou suggestion>
```

Preuve : <Ce que vous avez exécuté et ce qui s'est passé, ou "non reproduit">

## Non vérifié

<Tout ce que vous n'avez pas pu exécuter ou vérifier, et pourquoi>

Marquez chaque commentaire bloquant ou non-bloquant, en ordonnant d'abord les bloquants. "Preuve" est pour l'utilisateur et ne serait pas posté...

[La suite a été tronquée pour la traduction]

Skills associés