CRAFTOMANCER ~/parcours/aiguiser-le-craft/coherence-et-architecture
Sommaire

AIGUISER LE CRAFT · GUIDE 05 · LECTURE ~7 MIN · WILLIAM LEEMANS

Cohérence et architecture

En chantier Cette section est en cours d'écriture : ce guide est lisible mais pas encore finalisé, son contenu peut évoluer.

Le guide précédent s’arrêtait à la limite du remboursement local : consolider module par module ne sert à rien si la structure d’ensemble dérive. Reste donc la question d’échelle supérieure. Quelle cohérence défendre, et comment la faire tenir ?

L’architecture a toujours été un acte de communication entre développeurs à travers le temps. Or votre nouveau coéquipier n’a pas de mémoire : il arrive à chaque session comme au premier jour. La thèse de ce guide : les propriétés qui rendent une codebase navigable par un humain qui débarque sont exactement celles qui la rendent navigable par un agent. Et l’agent, lui, débarque tous les jours.


L’architecture est ce qui survit aux sessions

Dans une équipe humaine, l’architecture vit pour l’essentiel hors du code : dans les têtes, les conversations d’onboarding, le wiki, la mémoire de celui qui était là quand on a décidé. Ce capital ne sert à rien à un agent. Les Fondamentaux l’ont posé : le modèle ne connaît de votre projet que ce que son contexte contient. Chaque session reconstruit sa carte du système depuis ce qu’elle lit, puis la jette (Le contexte).

Le critère qui en découle est brutal : une décision d’architecture n’existe que si elle est lisible depuis le dépôt. Dans les noms, dans la structure des fichiers, dans les règles qui s’exécutent, dans les documents versionnés à côté du code. Tout le reste (la frontière « connue de tous », la convention orale, le schéma sur le tableau blanc) n’existe pour l’agent à aucun moment, et n’existera bientôt plus pour vos collègues non plus.

Le vieux test du nouvel arrivant (« un nouveau comprendrait-il où ranger ce code ? ») était un exercice de pensée annuel. C’est devenu votre régime permanent. L’agent est un nouvel arrivant perpétuel, rapide, sans complexes, et sans personne à qui poser la question. Une codebase se juge désormais à ce qu’elle explique d’elle-même.

Le langage du domaine est une interface

La première chose qu’un dépôt explique (ou pas), c’est de quoi il parle. Un concept, un nom, le même partout : code, schéma, tests, documentation, et désormais prompts. Ce vieux précepte de conception avait un bénéfice humain, la navigation. Il a gagné un bénéfice mécanique : vos demandes en langage naturel se branchent directement sur le code. « Ajoute une règle d’annulation aux réservations » est une instruction précise si Reservation et CancellationPolicy existent sous ces noms. Si le code dit BookingItem ici et Order là pour le même concept, chaque prompt embarque une traduction implicite. Et chaque traduction est une occasion de viser à côté.

Les synonymes font pire que ralentir : ils dupliquent. Un agent qui trouve Customer, Client et Account pour la même notion les traite comme trois concepts. Il choisira le mauvais, ou en inventera un quatrième, parfaitement vraisemblable. C’est la duplication paraphrasée du guide précédent, montée au niveau conceptuel. Plus chère, parce qu’elle s’incruste dans les schémas et les API.

L’excuse historique (« renommer coûte trop cher ») est tombée. Un renommage est la transformation mécanique par excellence, à comportement constant, jugée par la suite et le compilateur. Tenir le glossaire du domaine est redevenu bon marché ; ne pas le tenir ne l’a jamais été.

Une seule façon de faire chaque chose

Le guide précédent montrait comment encoder le canon : lint, fichier d’instructions, fichier exemplaire. La même logique monte d’un cran. Le canon ne couvre pas que l’idiome, il couvre la place des choses. Une arborescence régulière, où chaque type de code a un emplacement prévisible, est une interface de navigation : l’agent trouve en devinant les chemins, range au bon endroit sans qu’on le lui dise, et son inventaire de l’existant (le préalable anti-duplication) devient court et fiable. Dans un dépôt où chaque feature est organisée différemment, la recherche rate. Et ce que la recherche rate, la génération le réinvente.

D’où la règle artisanale, plus rentable que jamais : une seule façon de faire chaque chose. Le coût d’un second idiome n’est pas un doublement. Chaque lecteur, humain ou machine, doit apprendre les deux et deviner lequel s’applique où. Un second idiome n’est tolérable que comme migration : datée, documentée, avec une direction (tout nouveau code dans le nouveau, l’ancien converti au passage) et une fin. Deux idiomes sans direction, ce n’est pas une transition. C’est la divergence du guide précédent en régime permanent.

Des frontières qui s’exécutent

Reste la structure elle-même : couches, modules, sens des dépendances. Une frontière d’architecture qui ne vit que dans la convention ne survit pas à la génération. L’agent traverse tout ce qui est techniquement accessible dès que la traversée est vraisemblable. L’import du repository depuis la vue compile ? Il sera échantillonné un jour, relu un jour de fatigue, et mergé. La parade est la même que pour le style, un cran plus haut : mécanisez la frontière. Règles d’imports interdits dans le lint, visibilités restreintes, paquets séparés aux dépendances déclarées. Une frontière qui ne peut pas casser un build est une opinion.

Les frontières mécanisées ont un second rendement, propre au développement assisté : une frontière d’architecture est une frontière de contexte. La fenêtre est bornée et l’attention se dilue avec elle. Un module à surface publique étroite, compréhensible isolément, est un module sur lequel l’agent peut travailler avec un contexte petit et juste : le module, ses contrats, rien d’autre. Ce qu’un module cache à ses voisins, c’est du contexte que personne n’a besoin de charger. L’architecture cesse d’être une affaire d’esthétique structurelle : c’est l’instrument qui découpe votre système en tâches déléguables.

Décider, et consigner le pourquoi

Une structure lisible dit comment le système est fait ; elle ne dit pas pourquoi. Or le pourquoi est ce qui protège les décisions. Sans lui, toute contrainte volontaire ressemble à une erreur. Le découplage que vous avez payé cher a l’air d’une indirection inutile ; la dénormalisation choisie a l’air d’un oubli. Et l’agent, optimiseur de vraisemblance, « corrigera » l’un et l’autre avec les meilleures intentions du monde. Un relecteur pressé le suivra.

D’où la pratique : les décisions d’architecture se consignent dans le dépôt. Courtes, datées, avec leurs raisons et les options rejetées. Des ADR de quelques paragraphes suffisent. Pas pour la bureaucratie : parce qu’un document versionné à côté du code entre dans le contexte de qui travaille là. La décision prise dans un fil de discussion n’y entrera jamais. Un agent qui lit « nous avons choisi X malgré Y, pour Z » cesse de réparer X. Un humain aussi.

Le tips Craftomancer

Ne déléguez pas la décision d’architecture. « Propose une architecture pour ce système » produit la médiane du corpus : générique, plausible, découpée selon les habitudes de l’entraînement et pas selon vos contraintes. L’agent est un excellent exécutant d’architecture et un critique utile (faites-lui explorer des options, attaquer la vôtre), mais la décision engage le futur du système, et le guide 03 l’a posé : ce qui s’engage ne se délègue pas. Sachez-le : ne pas décider ne vous donne pas une absence d’architecture, mais celle qui émerge de la somme des diffs acceptés. La plus banale possible, par construction.

En pratique

  • L’agent est un nouvel arrivant perpétuel : une décision d’architecture n’existe que lisible depuis le dépôt. Noms, structure, règles exécutables, décisions versionnées.
  • Un concept, un nom, partout : le langage du domaine branche vos prompts directement sur le code. Chaque synonyme est une traduction à la charge de chaque session, et une duplication en attente.
  • Une seule façon de faire chaque chose, une seule place pour chaque chose. Un second idiome n’est tolérable que comme migration datée, avec une direction et une fin.
  • Mécanisez les frontières : l’agent traverse tout ce qui compile, et une frontière qui ne peut pas casser un build est une opinion.
  • Découpez pour le contexte : un module compréhensible isolément est une tâche déléguable avec une fenêtre petite et juste.
  • Consignez le pourquoi à côté du code : sans lui, toute contrainte volontaire ressemble à une erreur que la prochaine session voudra corriger.

Une codebase cohérente, bornée, qui s’explique elle-même : il reste le risque qui ne pardonne pas. Ce que le code généré introduit de vulnérable, des failles classiques réintroduites aux secrets exposés et aux dépendances hallucinées. C’est l’objet du dernier guide de la Section : la sécurité du code généré.