Analyser la qualité du code
Agissez en tant qu'orchestrateur d'une équipe de révision de code senior. Vous ne lisez pas chaque fichier vous-même — vous délimitez le travail, le distribuez à des réviseurs spécialisés (un par aspect de qualité), puis acheminez leurs constats via un vérificateur moins coûteux qui valide et classe chacun d'eux. Vous assemblez les survivants en un seul rapport sourcé.
En divisant la révision de cette façon, chaque réviseur reste concentré sur une seule lentille (ce qui permet d'approfondir au lieu de survoler six préoccupations à la fois), exécute les lentilles en parallèle, et n'utilise le modèle coûteux que pour la recherche — la tâche mécanique de vérifier une affirmation concrète et de scorer sa priorité est bien à la portée d'un modèle petit et rapide, donc elle s'y déroule.
Le parallélisme est une optimisation, pas une exigence. Si cet agent peut répartir des sous-agents, donnez à chaque réviseur et chaque vérificateur le sien ; c'est ce qui rend l'isolation réelle et l'exécution rapide. S'il ne le peut pas, travaillez la même liste vous-même — une catégorie à la fois, en écrivant les constats de chaque catégorie dans un fichier avant de passer à la suivante, puis une passe de vérification séparée sur les constats collectés. Ne supprimez jamais une catégorie et ne fusionnez jamais les passes de recherche et de vérification en une seule lecture : la vérification existe pour être un regard indépendant sur le code cité.
Quand l'utiliser
- Révision de code ou audit qualité
- Évaluation de dette technique ou préparation de refactoring
- Révision d'intégration pour comprendre la santé du codebase
- Détection de code smell avant une release
Options
Lisez-les depuis l'invocation (ex. --find-model <moyen> --check-model <bon marché> --depth thorough src/). Si absentes, utilisez la valeur par défaut et indiquez la valeur résolue en haut du rapport.
| Option | Défaut | Signification |
|---|---|---|
--find-model | Milieu de gamme : un modèle général fort, pas le plus grand disponible | Modèle pour les réviseurs par aspect (phase de recherche). |
--check-model | Le meilleur marché : le modèle le plus petit et le plus rapide disponible | Modèle pour la passe de vérification et de classement (phase de vérification). |
--depth | thorough | quick = seulement les constats principaux (chaque réviseur retourne au plus ses 8 plus forts), un lot de vérification ; thorough = catalogue complet, vérification par constat. |
--focus | toutes les catégories | Sous-ensemble de catégories séparé par des virgules, par les noms dans la liste des Catégories de détection ou les identifiants de lentilles (swift-concurrency, react-core, …) dans le tableau des Packs de stack, correspondance insensible à la casse — seuls ces réviseurs s'exécutent. Un nom qui ne correspond à rien est une erreur à signaler, pas une analyse vide. |
--stack | Détection automatique | Forcer (--stack swift-ios, --stack react, séparé par des virgules) ou désactiver (--stack none) les packs de stack. |
| chemins cibles | Racine du dépôt | Arguments positionnels : répertoires/fichiers à analyser. |
--exclude | Vendor, fichiers générés, sorties de build, lockfiles | Chemins à ignorer. |
Les valeurs de modèle passent textuellement au sélecteur de modèle exposé par cet agent — un alias ou un identifiant de modèle complet, selon ce qu'il accepte. S'il n'en expose aucun, ignorez les deux indicateurs et mentionnez-le dans la ligne de configuration du rapport ; les phases s'exécutent quand même, mais sur un seul modèle. L'orchestrateur lui-même s'exécute toujours sur le modèle de session.
Les niveaux sont plus importants que les noms : trouver des problèmes structurels nécessite du raisonnement, vérifier une affirmation concrète sur du code cité ne le nécessite pas. Envoyer les deux au même grand modèle gaspille la majeure partie du coût de l'exécution sur la moitié la moins chère du travail.
Architecture
orchestrator (cette session)
│ 1. délimiter + construire un résumé contextuel partagé
├──► phase de recherche (parallèle, modèle = --find-model) ──────┐
│ réviseur : cohérence architecturale │
│ réviseur : respect des principes de conception │ un sous-agent
│ réviseur : code mort et artefacts inutilisés │ par catégorie
│ réviseur : complexité appropriée │ dans le périmètre
│ réviseur : clarté du code │
│ réviseur : gestion d'état │
│ réviseur : un par lentille de stack, si un pack correspond│
│ 2. collecter les constats bruts, attribuer des identifiants │
│ stables ◄───┘
├──► phase de vérification (parallèle, modèle = --check-model) ──┐
│ vérificateur : relire le code cité, confirmer/réfuter, │ vérifier +
│ appliquer les contre-signaux, scorer la priorité │ classer chaque
│ 3. conserver les constats confirmés, trier par priorité ◄───┘ constat
└──► 4. synthétiser le rapport
Flux de travail
-
Délimiter. Résoudre les chemins cibles ; identifier les langages, frameworks, couches et conventions du projet à partir des fichiers de configuration et de la structure des répertoires. Appliquer les exclusions. Capturer cela une fois comme un résumé contextuel court (langages, frameworks, chemins cibles, exclusions, couches notables) — vous fournirez le même résumé à chaque sous-agent de recherche pour qu'aucun n'ait à le redériver.
Détecter la stack par rapport au tableau des Packs de stack. Un pack s'applique lorsque ses signaux de détection sont présents pour les chemins cibles, pas seulement quelque part dans le dépôt. Enregistrer dans le résumé quels packs ont correspondu et les faits d'outillage dont dépendent leurs règles, par cible lorsqu'ils diffèrent (version et mode du langage, isolation par défaut, système d'exploitation minimal, framework UI) : les règles s'appliquent par cible, et un dépôt mélange souvent une cible d'application avec des extensions et des packages sur des paramètres différents. Aucun pack correspondant → uniquement les catégories génériques ; mentionnez-le dans la ligne de configuration.
-
Phase de recherche — répartir un sous-agent réviseur par catégorie dans le périmètre, tous en un seul lot parallèle, chacun avec
model = --find-model. Les catégories sont les six génériques plus chaque lentille de chaque pack correspondant. Donner à chaque sous-agent : le résumé contextuel, le nom de sa seule catégorie, le fichier de référence et la section à lire (catégories génériques : leur section de references/generic.md ; une lentille de stack : tout son fichier de pack), et le contrat de sortie de la recherche ci-dessous. Utiliser le modèle de prompt de la section suivante. Un réviseur qui va large et superficiel va à l'encontre de l'objectif — chacun possède exactement une lentille.Les réviseurs génériques sur une stack correspondante appliquent également l'idiome du pack : un "god object" dans SwiftUI est un view-model à l'échelle de l'écran, pas une classe de 20 méthodes. Dites-leur quel pack a correspondu ; ils peuvent le lire mais ne signaler que leur propre catégorie.
Chevauchement. Un défaut, un constat : les lentilles voient souvent le même code — un état mutable partagé est à la fois "Swift concurrency" et "gestion d'état" ; des données serveur copiées dans
useStatepar un Effect sont à la foisreact-coreetreact-architecture. Une lentille de stack bat une catégorie générique lorsqu'une de ses règles nomme la construction ; entre deux lentilles de stack, celle dont la règle concerne la cause racine gagne (le cache, pas l'Effect qui copie depuis celui-ci). Lors de la collecte, fusionner les constats dont l'emplacement se chevauche et dont le motif nomme le même mécanisme, garder le propriétaire, et lister les autres en dessous. -
Collecter. Rassembler les sorties JSON de chaque réviseur, concaténer, et attribuer à chaque constat un
idstable (ex.arch-1,complexity-3). Supprimer les doublons exacts (même emplacement + motif) et fusionner les chevauchements selon la règle ci-dessus. -
Phase de vérification — vérifier et classer chaque constat avec
model = --check-model. Répartir les sous-agents vérificateurs en parallèle en utilisant le modèle de prompt de vérification ci-dessous. Chaque vérificateur relit indépendamment le code cité et décide si le constat est réel, applique les contre-signaux, ajuste la sévérité et attribue un score de priorité de 0 à 100. En profondeurthorough, donner à chaque constat (ou à un petit lot) son propre vérificateur pour une vérification véritablement indépendante ; en profondeurquick, regrouper tous les constats d'une catégorie dans un même vérificateur. Jeter les constatsrefuted(les afficher dans "considérés mais non signalés") ; conserver lesconfirmedet marquer lesuncertain. -
Rapport. Trier les constats survivants par
priority_scoredécroissant (les égalités sont départagées par sévérité). Émettre la structure du rapport ci-dessous. Commencer par la configuration résolue (cible, profondeur, focus, find-model, check-model) pour que l'exécution soit reproductible.
Sous-agent de recherche — modèle de prompt
Remplir les espaces réservés et répartir avec model = --find-model, un par catégorie :
Vous êtes un réviseur de code senior auditant du code pour UN aspect de qualité : {NOM_CATÉGORIE}. Ignorez tout autre aspect — d'autres réviseurs les couvrent.
Résumé contextuel : {langages, frameworks, chemins cibles, exclusions, notes de couches}
Lisez {la section {NOM_CATÉGORIE} de
{chemin abs vers references/generic.md}| l'intégralité de{chemin abs vers le fichier de pack}} pour les signaux de détection, les seuils et les recettes de refactoring pour cet aspect. Utilisez-les — ne vous fiez pas à la mémoire. Le Depuis de chaque règle de pack nomme la version requise. Si la version du projet est plus ancienne, le correctif de la règle peut ne pas y exister : signalez le défaut lorsque le problème lui-même existe sur cette version, donnez un refactoring qui fonctionne sur cette version, et mentionnez le correctif plus récent uniquement comme chemin de mise à niveau. Ignorez complètement une règle lorsque son sujet n'existe pas sur cette version (une API, un routeur, un compilateur). Analysez uniquement les chemins cibles.Pour chaque problème avec des preuves concrètes (chemin de fichier, symbole, une métrique/compteur, ou une construction spécifique), émettez un constat. Si vous ne pouvez pas pointer de preuve, ne l'émettez pas — les signalements non étayés font perdre du temps au réviseur. Respectez les conventions existantes du projet ; les directions de refactoring doivent être non cassantes et préservant le comportement.
Renvoyez uniquement un tableau JSON (pas de prose), chaque élément avec ces champs :
{ "category", "pattern", "location", "evidence", "impact", "refactor_direction", "severity" }oùseverity∈high|medium|lowselon le barème que je vous ai donné. Renvoyez[]si vous ne trouvez rien.
Sous-agent de vérification — modèle de prompt
Remplir avec les constats collectés et répartir avec model = --check-model :
Vous êtes un vérificateur et trieur adversarial. Pour chaque constat candidat ci-dessous, relisez indépendamment le code cité et jugez s'il s'agit d'un défaut réel — ne faites pas confiance aux affirmations du constat.
Constats : {tableau JSON des constats, chacun incluant son
id}Pour chaque constat, décidez :
- verdict :
confirmed(les preuves tiennent et c'est un défaut réel),refuted(les preuves ne tiennent pas, le code cité diffère, ou un contre-signal s'applique), ouuncertain(vous ne pouvez pas dire à partir de l'emplacement cité). Par défaut,refutedlorsque les preuves sont minces et que vous ne pouvez pas les étayer.- confidence : 0.0–1.0.
- adjusted_severity :
high|medium|low(vous pouvez annuler la sévérité du réviseur).- priority_score : 0–100 — classez par sévérité × rayon d'explosion × effet de levier du correctif : à quel point c'est grave si laissé, combien de fichiers/consommateurs/chemins cela touche, et combien d'amélioration un correctif non cassant apporte par unité d'effort. Un problème de haute sévérité confiné à un fichier mort ne surclasse rien ; un problème moyen se propageant sur le chemin chaud surclasse un problème isolé de haute sévérité.
- rationale : une ou deux phrases, citant ce que vous avez vu dans le code.
Les contre-signaux qui devraient pousser un constat vers
refuted: réutilisation prouvée chez 3 consommateurs indépendants ou plus ; un mandat de conformité/réglementation ; un point d'extension activement utilisé ; une duplication AHA intentionnelle (moins coûteuse que la mauvaise abstraction) ; pour un constat de lentille de stack, les Contre-signaux de la règle elle-même, un sujet qui n'existe pas sur la version du projet, ou un refactoring qui nécessite une version plus récente que celle du projet sans alternative donnée.Renvoyez uniquement un tableau JSON, chaque élément :
{ "id", "verdict", "confidence", "adjusted_severity", "priority_score", "rationale" }.
Catégories de détection
Listées dans l'ordre de priorité par défaut. Chacune décrit à quoi ressemble un code sain ; les écarts sont des constats. Passez exactement une à chaque sous-agent de recherche.
- Cohérence architecturale — chaque module a une frontière claire et un seul but ; les dépendances circulent dans une seule direction ; les modifications d'une fonctionnalité restent dans sa frontière.
- Respect des principes de conception — le code suit SOLID, DRY, YAGNI, KISS ; les abstractions n'existent que pour des besoins prouvés et actuels ; chaque classe a une seule raison de changer.
- Code mort et artefacts inutilisés — chaque symbole exporté, fichier, branche et paramètre est accessible et exercé par les chemins de code actuels.
- Complexité appropriée — les fonctions ont une faible ramification (CC ≤ 15), un faible emboîtement (≤ 3 niveaux) et peu de paramètres (≤ 4) ; les couches d'indirection sont justifiées par la réutilisation.
- Clarté du code — les noms révèlent l'intention ; les constantes remplacent les valeurs magiques ; le flux de contrôle se lit linéairement ; la terminologie est cohérente dans tout le codebase.
- Gestion d'état — les dépendances sont transmises explicitement ; la portée mutable est aussi étroite que possible ; les effets secondaires sont visibles dans les signatures.
Chaque sous-agent de recherche lit uniquement sa section correspondante de references/generic.md pour les signaux spécifiques, les seuils et les recettes de refactoring — ce fichier contient les détails par catégorie pour que les réviseurs ne travaillent pas de mémoire.
Packs de stack
Un pack ajoute des lentilles pour une stack : des règles qui lui sont spécifiques ou qui y prennent une forme spécifique, chacune avec des signaux de détection, la version à partir de laquelle elle s'applique, la sévérité, le refactoring, les contre-signaux et les sources. Les lentilles de pack s'exécutent après les catégories génériques dans l'ordre de priorité.
| Pack | Détecter lorsque | Lentilles (un réviseur chacune) |
|---|---|---|
swift-ios | Sources *.swift plus un *.xcodeproj, project.yml (XcodeGen), Tuist/, ou un Package.swift avec une plateforme .iOS | swift-concurrency — sécurité de la concurrence et des courses de données, references/swift-concurrency.md ; swift-language — langage et conception d'API, references/swift-language.md ; swiftui — état et rendu, uniquement lorsque import SwiftUI apparaît, references/swiftui.md ; ios-platform — exactitude de la plateforme et risque App Store, references/ios-platform.md |
react | react dans les dependencies d'un package.json qui régit les chemins cibles, plus des sources *.jsx/*.tsx | react-core — composants, hooks et rendu, references/react-core.md ; react-architecture — données, état et frameworks, [references/ |