Un graphe plutôt qu’une supposition : AI Architect Codebase, suivi dans son code
Un agent à qui l’on demande qui appelle cette fonction a deux options : grep et espérer, ou lire un graphe. Ce serveur construit le graphe. Il analyse un dépôt avec tree-sitter, résout les relations entre fichiers, et répond aux questions de structure depuis un store de propriétés en processus, sans jamais écrire de code, ouvrir une pull request ni appeler un modèle de langage.231 Il est en version 0.11.1, sous licence MIT, épinglé à une chaîne d’outils Rust.1 Ce qui suit est son architecture, les constantes avec lesquelles il calcule, et les endroits où sa propre documentation et son propre code se contredisent.
Un processus, une boucle, et deux produits différents
Il n’y a ni démon, ni port, ni SDK. L’hôte écrit une ligne JSON sur l’entrée standard, un seul fil la dispatche contre une courte liste de méthodes implémentées, et la réponse repart sur la sortie standard.345 La couche protocole est écrite à la main à dessein, et le fichier dit pourquoi : pour que les agents sachent exactement ce qui se passe.3 Deux points d’entrée répondent poliment pour des capacités que le serveur ne déclare pas, parce que certains clients les sondent à la connexion et lisent l’erreur comme une connexion cassée.6
La décision la plus lourde de conséquences est le profil d’outils. Résolu une fois au démarrage, il décide si l’hôte voit vingt-six outils ou huit.789 Le même binaire est donc deux produits différents selon qui l’a lancé, et les lanceurs ne s’accordent pas : Codex et Gemini démarrent avec le profil core, Claude Code et le bundle desktop ne passent aucun drapeau et obtiennent tout, tandis que les trois skills livrées disent toutes à l’agent d’utiliser le profil à huit outils.12
D’un arbre source à quelque chose d’interrogeable
Le parcours est borné avant toute analyse : cent mille fichiers, dix mébioctets chacun, deux gibioctets au total, soixante-quatre niveaux de profondeur, cinq secondes d’analyse par fichier.1314 Ce ne sont pas des chiffres ronds choisis par confort ; le premier consigne les arbres contre lesquels il a été dimensionné.13 Onze langages sont reconnus, dix avec une spécification profonde et Ruby avec une spécification de surface, et les extensions ambiguës sont tranchées par une table fixe pour qu’une erreur de détection soit observable plutôt que silencieuse.1516
Il en sort un graphe de propriétés de vingt-quatre étiquettes de nœuds et quatre-vingt-dix-huit tables de relations, écrit comme un répertoire et non comme un fichier, avec un index de recherche et quatre fichiers annexes à côté.1719 La recherche fusionne un classement lexical et un classement vectoriel par rang réciproque à K = 60.20 Les communautés viennent de Louvain, suivi d’une passe de réparation, parce que la phase un seule laisse le graphe sur-fragmenté — et le fichier consigne la mesure qui l’a montré.21 L’impact parcourt le graphe jusqu’à la profondeur vingt.22
Ce que chaque réponse avoue d’elle-même
La plupart des outils répondent à une question. Celui-ci répond aussi de la part de la question qu’il a réellement pu trancher. Un marqueur de complétude valant exact ou lower-bound accompagne quatre réponses.27 Un bloc de fraîcheur, disant si le graphe correspond encore à votre copie de travail, accompagne exactement trois outils, et pas un de plus.28
L’intéressant est la façon dont ce bloc est attaché. Une révision antérieure le posait à chaque return nommé, ce qui couvrait les sorties que son auteur voyait et ratait en silence tout échec précoce propagé avant elles ; il est désormais attaché à la sortie unique, et le fichier explique cette histoire plutôt que de la masquer.28 Le même instinct traverse le rapport de couverture, qui porte une réserve disant qu’il est un signal au mieux et non une garantie,29 et l’indexeur, où un fichier dont l’analyseur panique est mis en quarantaine et compté plutôt qu’abandonné.30
Mesuré, choisi, ou simplement affirmé
Le dépôt se donne une règle : une constante nommée consigne sa source ou sa justification mesurée, et là où une valeur a été choisie au jugé, le commentaire le dit.44 Il la tient largement. Le score de risque de changement est étiqueté dans son propre fichier comme heuristique et non adossé à un article, avec des poids arbitraires.43 Le budget de réponse est le cas inverse, dérivé pas à pas du plafond de l’hôte, extrait du binaire et vérifié contre une vraie réponse rejetée.42
La colonne mesurée l’est vraiment : un face-à-face pré-enregistré sur vingt questions, un index incrémental chronométré contre un index complet, une couverture avec son outil et sa date.363738 Le face-à-face énonce même sa propre faiblesse : le corpus a informé les correctifs qu’il mesure, c’est donc un bench de régression et non un test de généralisation.36 La colonne affirmée est celle où il faut ralentir. « 1500+ tests » figure sur le badge et trois fois ailleurs ; le comptage des attributs de test dans l’arbre donne 1 127, et le vrai chiffre ne peut pas être tranché sans exécuter la suite.39 Le badge de couverture à 91 % n’a aucun rapport commité derrière lui.40 Une accélération de 38× siège dans le même document qu’un 76× mesuré, sans réconciliation.41 Et la ligne du README sur le schéma du graphe sous-compte le code d’un facteur un et demi à près de trois.18
Le verdict que le projet se donne à lui-même
Le dépôt livre son propre harnais d’évaluation, et garde ses runs. Le plus récent, daté du 2026-08-08, donne 0,694 contre une cible de 0,85 et un plancher par langage de 0,75, et imprime le verdict NOT PRODUCTION-GRADE.34 Les questions les plus faibles sont précisément celles pour lesquelles un outil d’intelligence de code existe : quelles classes implémentent une interface, à 0,250, et ce qu’une fonction appelle, à 0,451. Un second run est commité à côté et concorde à la troisième décimale.35 Rien de tout cela n’apparaît dans le README. C’est dans le dépôt parce que les runs ont été gardés plutôt que supprimés, et c’est la raison pour laquelle ce paragraphe peut être écrit.