Aller au contenu

Révision par IA

Une révision par IA est une exécution du pipeline préconfiguré pr_review contre une demande de tirage ouverte. Le pipeline ouvre l’espace de révision de la PR, déploie des agents relecteurs pour lire le diff dans l’extraction isolée de cet espace, chacun consigne ses constats sous forme de nœuds de révision structurés, un agent principal les consolide en une visite guidée, et un finaliseur calcule un seul verdict : Ship, Hold ou Block. Ce que le pipeline ne fait jamais, c’est publier — la publication dans GitHub est une étape distincte et délibérée qu’une personne accomplit.

Le reste de cette page explique les pièces et pourquoi elles ont cette forme.

Le contexte de révision d’une PR est un espace de messagerie — mode review, type pr — relié à la demande de tirage par une association d’espace de révision. Il est créé de façon idempotente : la page de la PR, le pipeline de révision et les surfaces de clavardage résolvent tous le seul espace sous-jacent de la PR par le même chemin de code, de sorte qu’un modèle qui révise une PR et une personne qui l’ouvre ne peuvent jamais se retrouver dans deux salles différentes à regarder deux extractions différentes.

L’arbre de travail isolé de l’espace contient la PR extraite à sa référence de tête. Une seule salle signifie aussi une seule extraction : chaque relecteur travaille dans le même espace plutôt que d’obtenir son propre clone de l’espace de travail.

Chaque relecteur publie dans son propre flux nommé à l’intérieur de cet espace unique, et les constats sont des messages review_node plutôt que de la prose brute. Le rassemblement à l’échelle de l’espace à la fin est délibéré — un verdict calculé à partir des constats d’un seul fil serait silencieusement un verdict sur un seul relecteur.

L’association porte une échelle de statuts — requested → in progress → awaiting approval → completed — et c’est elle qui sert de verrou à Publier sur GitHub dans l’onglet Revue de la PR.

La profondeur d’une révision est une règle d’espace de travail comportant trois niveaux, définie dans Paramètres → Espace de travail → Général, sur la carte Règles de l’espace de travail :

Niveau Relecteurs déployés Signalement
light Implémentation seulement Seulement ce qui compte vraiment
balanced Implémentation, qualité et architecture (par défaut) La passe habituelle
thorough Les cinq, y compris sécurité et performance Rien n’est rétrogradé

Le niveau actionne deux réglages à la fois : quels relecteurs sont déployés, ce qu’imposent les verrous d’état runWhen du modèle de pipeline plutôt que le libellé du prompt — un libellé de prompt peut être ignoré, un verrou non —, et où les constats sous le seuil sont rendus. Aucun des deux réglages ne supprime jamais un constat : un niveau qui signale moins consigne exactement autant et regroupe le reste.

Les passes de sécurité et de performance réutilisent les agents préconfigurés d’architecture et d’implémentation plutôt que d’en introduire de nouveaux. La spécialisation tient à la consigne avec laquelle le relecteur est lancé, et non à un agent distinct par axe — un agent par axe ajouterait cinq lignes de plus dans chaque espace de travail sans capacité supplémentaire. La sélection des relecteurs n’inspecte jamais le diff pour en déduire un langage ou un domaine.

Nœuds de révision : des constats comme données, pas comme prose

Section intitulée “Nœuds de révision : des constats comme données, pas comme prose”

Un constat consigné avec add_review_node devient un nœud de révision sur la PR — c’est ce que rend l’onglet Revue, ce à partir de quoi le verdict est calculé, et ce que « Publier sur GitHub » transforme en commentaire en ligne. Un relecteur qui ne renvoie que de la prose produit une exécution de pipeline qui semble réussie et une surface de révision vide ; c’est la consignation qui porte tout le poids.

Chaque nœud porte :

Champ Valeurs
Type bug, suggestion, recommendation, question, ticket
Priorité P0 (critique) → P3 (détail)
Triple de triage catégorie (security, stability, …), gravité, effort
Ancrage Chemin de fichier, début et fin de ligne
Transport du correctif Lignes de remplacement suggérées, un diff facultatif, une consigne de correction facultative
Confiance Une note dans [0, 1]
Raisonnement L’analyse, rédigée avant le constat

Deux détails sont délibérés. Une suggestion GitHub en un clic n’est proposée que lorsque le relecteur a fourni des lignes de remplacement exactes — les déduire d’un diff unifié échoue silencieusement, et valider en un clic une déduction erronée est pire que l’absence de bouton. Et le schéma add_review_node présente reasoning avant le constat, de sorte qu’un modèle qui remplit l’objet dans l’ordre du schéma rédige d’abord l’analyse. Le champ est facultatif : l’omettre ne fait pas rejeter le nœud. Un nœud dont la charge utile est mal formée disparaît plutôt que de polluer la révision.

Un nœud passe par open → consensus-ready → resolved ou dismissed. L’étape intermédiaire est le cœur du modèle : un constat n’est promu que lorsqu’un pair relecteur le confirme, et un agent ne peut jamais confirmer son propre constat. L’outil MCP publish_review_to_github et l’appel RPC par défaut ne publient toujours que les constats confirmés par un pair. Le bouton Publier sur GitHub de l’onglet Revue envoie plutôt chaque constat ouvert restant.

La règle est appliquée à trois endroits indépendants — l’outil de confirmation, le finaliseur et le composant de publication —, de sorte qu’elle survit à un appelant défectueux dans l’un d’eux. Tous les changements de statut passent par un seul service, et c’est ce qui donne un sens à un statut : avant cela, deux demi-chemins pouvaient ne pas s’entendre sur le fait qu’un même constat était résolu.

Quand les relecteurs ne sont pas d’accord — même fichier et même ligne, priorités séparées par deux niveaux ou plus, ou l’un le qualifiant de bug alors que l’autre le qualifie de suggestion —, la divergence est mise en évidence au-dessus de la liste des constats. C’est là que les avis des relecteurs divergent et que le jugement d’une personne vaut le plus cher.

Écarter un constat écrit aussi un fait de suppression non contraignant dans le domaine de mémoire, à faible confiance — un rejet est une préférence, pas une règle.

Cohortes : ce autour de quoi la révision est regroupée

Section intitulée “Cohortes : ce autour de quoi la révision est regroupée”

La passe de calcul de révision regroupe les fichiers modifiés d’une PR en cohortes dérivées du graphe de code : les fichiers modifiés correspondent aux symboles qu’ils touchent, les symboles aux composants connexes, et les cohortes sont classées par rayon d’impact. Une cohorte porte un ordre de lecture guidé, des diagrammes et des aperçus plutôt que d’être une simple liste de fichiers.

Deux règles d’honnêteté façonnent cela. Les clés de cohorte sont dérivées du contenu et stables d’un push à l’autre, de sorte que les constats et la progression de la révision survivent à un rebase ou à un force-push au lieu de devenir orphelins. Et quand le dépôt n’a pas d’index de code, le regroupement se rabat sur les chemins simples et le dit — le repli ne simule jamais une confiance sémantique.

En plus des constats des relecteurs, une révision accumule des résultats d’axe : six axes, de deux types.

Axe Type Source
correctness, security Piloté par jetons Les constats des relecteurs eux-mêmes
testGap Piloté par jetons Les constats des relecteurs
visual, apiContract Déterministe Calculé sans dépenser de jetons
performance Déterministe Énumération seulement — rien dans le produit ne calcule de résultat

Le verdict d’un axe est pass, warn, fail, partial ou unavailable — et seuls pass ou warn franchissent un verrou. La distinction entre fail, partial et unavailable est déterminante : un axe verrouillé qui n’a pas pu se terminer ou qui n’a pas pu s’exécuter du tout retient le verdict global au lieu de le laisser passer. L’absence de preuve ne se transforme jamais en verrou au vert.

Certains axes sont consultatifs à dessein. L’axe des lacunes de tests dérivé des cohortes ne peut pas voir la couverture de l’injection de dépendances ni celle des fabriques — un dépôt non indexé doté d’une suite approfondie et un dépôt sans aucun test sont identiques vus de là, alors prétendre l’un ou l’autre serait un mensonge ; il apparaît dans le tableau de bord sans verrouiller. Les axes à jetons sont consultatifs parce que les priorités des constats déterminent déjà le verdict, et les verrouiller de nouveau reviendrait à compter deux fois.

Le finaliseur calcule le verdict sur les constats dont le statut est open ou consensus-ready :

  • tout constat P0 dont la confiance est ≥ 0,7 → Block
  • sinon, tout P0 (à faible confiance) ou tout P1 → Hold
  • sinon → Ship

Le verdict porte une confiance globale dérivée de l’écart entre les confiances contributrices — l’accord l’augmente, la divergence la diminue.

La consolidation de l’agent principal (CEO) est une passe éditoriale, et non une nouvelle énumération : une deuxième copie des constats rédigée à la main est exactement ce qui finit par s’écarter de la vraie. Les constats en double sont rétrogradés plutôt que répétés — plusieurs relecteurs sont pointés vers un même diff avec des mandats délibérément chevauchants, de sorte que le même défaut atteignant trois fois le finaliseur signifie que le système fonctionne ; le publier trois fois, c’est le système qui laisse fuiter sa propre architecture dans la boîte de réception du lecteur. Lors d’une nouvelle révision, les constats reçoivent une empreinte et sont comparés à la ronde précédente, de sorte que c’est l’écart qui ressort.

Enfin, les axes s’intègrent, et ils ne peuvent que rendre le verdict plus sévère : un axe verrouillé en échec force Block — les constats ne peuvent pas le mettre en minorité —, et un axe verrouillé qui n’a pas pu se terminer force au moins Hold.

Le pipeline s’abstient délibérément de publier dans GitHub ; la publication est conditionnée à l’action de l’utilisateur, de sorte qu’une révision ne peut jamais être publiée deux fois. Quand vous appuyez sur Publier sur GitHub :

  • Une seule revue GitHub est soumise. Les constats déjà résolus ou écartés sont ignorés. Le bouton publie chaque constat ouvert restant (selection: all_open). L’outil MCP publish_review_to_github conserve par défaut les seuls constats confirmés par un pair (consensus).
  • Les constats ancrés à un fichier et à une ligne deviennent des commentaires en ligne ; tout le reste est replié dans le corps du résumé, chacun portant un pied de page « — Control Center AI review » afin que la source soit sans ambiguïté.
  • Les ancres sont revérifiées contre le diff actuel de la PR au moment de la publication. Un commentaire sur du code déjà réécrit est ce qui détruit le plus la confiance qu’un relecteur puisse laisser ; si GitHub rejette malgré tout une ancre en ligne, la révision entière est renvoyée avec chaque constat replié dans le corps, de sorte que rien n’est abandonné en silence.
  • Un verdict Block est soumis comme REQUEST_CHANGES ; Hold comme COMMENT ; Ship comme APPROVE à partir du bouton (approve_on_ship: true). L’outil MCP laisse Ship en COMMENT à moins que vous ne passiez approve_on_ship.
  • La révision est publiée sous l’identité d’application du serveur. La personne qui a appuyé sur Publier est consignée pour le verrou de rôle et le journal d’audit ; ce n’est pas l’auteur GitHub.

La publication déclare la classe d’action prPublish, de sorte que le point de contrôle des garde-fous la soumet à un verrou comme toute action mutante — elle demande une approbation par défaut et échoue en mode fermé quand aucun approbateur n’est connecté. Voir Garde-fous.

Les agents relecteurs s’exécutent en mode review : un bac à sable en lecture seule et une liste d’autorisation d’outils choisie avec soin couvrant les constats, les commentaires, les tickets et la révision par les pairs — mais aucune mutation. Un relecteur ne peut pas corriger le code qu’il critique ; il peut joindre un correctif suggéré qu’une personne applique. Le message de refus du mode indique à un agent qui tente quand même d’agir de terminer la révision et de laisser l’utilisateur agir à partir du résumé publié.