La communication avec l'utilisateur et le rapport d'examen se font en français (langue cible).
Réalise un examen biaxial du diff entre HEAD et le point fixe fourni par l'utilisateur :
- Standards : Le code respecte-t-il les normes documentées de ce dépôt ?
- Spec : Le code implémente-t-il fidèlement le ticket/la spec d'origine ?
Les deux axes sont exécutés par des sous-agents parallèles pour éviter toute contamination de leur contexte, puis leurs conclusions sont synthétisées par cette compétence.
Le gestionnaire de tickets devrait déjà vous être fourni. Sinon, dites à l'utilisateur d'exécuter /setup-matt-pocock-skills d'abord.
Procédure
1. Déterminer le point fixe
Le point fixe est celui donné par l'utilisateur (SHA de commit, nom de branche, tag, main, HEAD~5, etc.). S'il n'en spécifie pas, demandez-le.
Notez immédiatement la commande diff : git diff <point-fixe>...HEAD (trois points, donc comparaison avec la base de fusion). Enregistrez également la liste des commits avec git log <point-fixe>..HEAD --oneline.
Avant de continuer, vérifiez que le point fixe peut être résolu (git rev-parse <point-fixe>) et que le diff n'est pas vide. Une référence erronée ou un diff vide doivent échouer ici, pas dans les deux sous-agents.
2. Trouver la source de la spécification
Recherchez la spec d'origine dans l'ordre suivant :
- Références aux tickets dans les messages de commit (
#123,Closes #45, GitLab!67, etc.), en utilisant la procédure du fichier tracker. - Chemin passé en paramètre par l'utilisateur.
- Fichiers de spec dans
docs/,specs/ou.scratch/correspondant au nom de la branche ou à la fonctionnalité. - Si rien n'est trouvé, demandez à l'utilisateur où se trouve la spec. S'il dit qu'il n'y en a pas, le sous-agent Spec est ignoré, et il est rapporté « Aucune spécification disponible ».
3. Trouver les sources des normes
Recherchez dans le dépôt tous les fichiers qui décrivent comment le code doit être écrit. Si CODING_STANDARDS.md ou CONTRIBUTING.md existe, incluez-les impérativement. Pour les projets Python, regardez aussi les configurations des linters/formateurs (ruff, black, mypy, etc.) dans pyproject.toml, mais ne vérifiez pas les règles déjà imposées par les outils.
En plus du contenu documenté du dépôt, l'axe Standards intègre en permanence la base des mauvaises odeurs ci-dessous : un ensemble fixe de mauvaises odeurs de code de Fowler (chapitre 3 du livre « Refactoring »), applicable même si le dépôt n'a rien documenté. Deux règles la contraignent :
- priorité au dépôt. Les normes documentées du dépôt l'emportent toujours ; lorsqu'elles approuvent un élément que la base signalerait, ne signalez pas cette mauvaise odeur.
- toujours un jugement. Chaque mauvaise odeur est une heuristique étiquetée (« il pourrait y avoir un Feature Envy »), jamais une violation stricte. Comme pour toute norme ici, sautez ce qui est déjà imposé par les outils.
Chaque mauvaise odeur est écrite sous la forme « Ce que c'est → Comment corriger » ; confrontez-la au diff :
- Nom mystérieux (Mysterious Name) : Le nom d'une fonction, variable ou type n'indique pas ce qu'elle fait ou contient. → Renommez ; si vous ne trouvez pas de nom honnête, c'est que le design est flou.
- Code dupliqué (Duplicated Code) : La même forme logique apparaît dans plusieurs blocs ou fichiers de cette modification. → Extrayez la forme commune et appelez-la des deux côtés.
- Envie de fonctionnalité (Feature Envy) : Une méthode accède plus aux données d'un autre objet qu'aux siennes. → Déplacez la méthode vers les données qu'elle convoite.
- Agglomérats de données (Data Clumps) : Les mêmes champs ou paramètres apparaissent toujours ensemble (un type qui cherche à naître). → Regroupez-les dans un type et passez ce type.
- Obsession des primitifs (Primitive Obsession) : Utiliser un type primitif ou une chaîne pour représenter un concept métier qui mériterait un type propre (ex.
strpour un code produit,floatpour montant et devise). → Donnez à ce concept un petit type dédié (ex.dataclass). - Branches conditionnelles répétées (Repeated Switches) : Les mêmes séquences
match/ifsur le même type apparaissent de manière répétée dans cette modification. → Remplacez par du polymorphisme ou une table de correspondance partagée. - Modification par fusillade (Shotgun Surgery) : Un changement logique oblige des modifications disparates dans de nombreux fichiers du diff. → Rassemblez ce qui change ensemble dans un module.
- Divergence de modifications (Divergent Change) : Un fichier ou module est modifié pour plusieurs raisons non liées. → Séparez-le pour que chaque module ne soit modifié que pour une seule raison.
- Généralité spéculative (Speculative Generality) : Abstraction, paramètre ou accroche ajouté pour un besoin qui n'est pas dans la spec. → Supprimez-le ; refactorisez en ligne et attendez un vrai besoin.
- Chaînes de messages (Message Chains) : Longues navigations
a.b().c().d()dont le code appelant ne devrait pas dépendre. → Cachez cette exploration derrière une méthode du premier objet. - Intercesseur (Middle Man) : Une classe ou fonction qui ne fait que déléguer vers autre chose. → Supprimez-la et appelez directement la cible réelle.
- Héritage refusé (Refused Bequest) : Une sous-classe ou un implémenteur ignore ou remplace la plupart de ce qu'il hérite. → Abandonnez l'héritage et utilisez la composition.
4. Lancer les deux sous-agents en parallèle
Lancez deux appels sous-agents en même temps (au premier plan) et synthétisez les rapports qu'ils renvoient.
Invite du sous-agent Standards doit inclure :
- La commande diff complète et la liste des commits.
- Les fichiers sources de normes trouvés à l'étape 3, plus le texte complet de la base des mauvaises odeurs de l'étape 3 (le sous-agent n'a pas d'autre moyen d'y accéder).
- La consigne : « Rapportez en français et identifiez les fichiers/blocs concernés : (a) chaque endroit où le diff viole les normes documentées : citez la norme (fichier + règle) ; et (b) toute mauvaise odeur de la base que vous détectez : nommez-la et citez le bloc. Distinguez les violations strictes des jugements : les violations de normes documentées peuvent être strictes, mais les mauvaises odeurs de la base sont toujours des jugements, et les normes documentées du dépôt priment sur la base. Sautez ce qui est déjà imposé par les outils. Limitez-vous à 400 mots. »
Invite du sous-agent Spec doit inclure :
- La commande diff et la liste des commits.
- Le chemin vers la spec ou son contenu déjà récupéré.
- La consigne : « Rapportez en français : (a) les exigences de la spec qui manquent ou ne sont qu'en partie implémentées ; (b) les comportements non demandés (dépassement de périmètre) apparaissant dans le diff ; (c) les exigences qui semblent implémentées mais de manière incorrecte. Pour chaque constat, citez le texte correspondant de la spec. Limitez-vous à 400 mots. »
S'il n'y a pas de spec, ignorez le sous-agent Spec et notez-le dans le rapport final.
5. Synthèse
Placez les deux rapports sous les titres ## Standards et ## Spec, soit textuellement, soit en les organisant légèrement. Ne fusionnez ni ne réordonnez les constats, car les deux axes sont délibérément séparés (voir la section « Pourquoi deux axes »).
Terminez par un résumé d'une ligne : le nombre total de constats pour chaque axe, et au sein de chaque axe le problème le plus grave (s'il y en a). Ne sélectionnez pas un gagnant entre les axes : c'est exactement ce que la séparation en deux axes vise à empêcher.
Pourquoi deux axes
Une modification peut passer un axe mais pas l'autre :
- Respecte toutes les normes mais implémente la mauvaise chose → Standards OK, Spec en échec.
- Fait exactement ce que demande le ticket mais casse les conventions du projet → Spec OK, Standards en échec.
Les rapports séparés évitent qu'un axe masque l'autre.