<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr"><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://anasdox.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://anasdox.github.io/" rel="alternate" type="text/html" hreflang="fr" /><updated>2026-10-09T15:25:18+00:00</updated><id>https://anasdox.github.io/feed.xml</id><title type="html">Anas Ameziane</title><subtitle>AI-Native Product Engineering : quand le code ne coûte presque plus rien, le goulot passe à la compréhension du problème, à la spécification, à la validation et à la mise en production. Essais, expériences et méthode d&apos;Anas Ameziane, ingénieur.</subtitle><author><name>Anas Ameziane</name></author><entry xml:lang="fr"><title type="html">L&apos;IA produit le code en dix minutes. Votre CI a-t-elle suivi ?</title><link href="https://anasdox.github.io/l-ia-produit-le-code-en-dix-minutes-votre-ci-a-t-elle-suivi/" rel="alternate" type="text/html" title="L&apos;IA produit le code en dix minutes. Votre CI a-t-elle suivi ?" /><published>2026-10-09T00:00:00+00:00</published><updated>2026-10-09T00:00:00+00:00</updated><id>https://anasdox.github.io/l-ia-produit-le-code-en-dix-minutes-votre-ci-a-t-elle-suivi</id><content type="html" xml:base="https://anasdox.github.io/l-ia-produit-le-code-en-dix-minutes-votre-ci-a-t-elle-suivi/"><![CDATA[<p>Un problème en production. Pour comprendre ce qui se passe, il faut
ajouter des logs. Quelques lignes, qu'un agent écrit en une minute.</p>

<p>Sauf qu'ajouter des logs, c'est modifier le code. Modifier le code,
c'est relancer les tests fonctionnels. Et les tests fonctionnels ne
tournaient pas en parallèle : une heure de CI. Une heure pendant
laquelle la production reste bloquée, sans le moindre indice
supplémentaire.</p>

<p>L'autre option était de sauter la CI. Ce n'est pas mieux : c'est
exactement comme ça qu'on crée une régression en essayant de réparer
un incident.</p>

<p>Le code était prêt en une minute. La confiance dans ce code coûtait
une heure. Faites le compte sur votre propre chaîne : la revue qui
attend le lendemain, le déploiement réservé au jeudi matin, de
préférence quand Mercure n'est pas rétrograde. L'agent gagne des
heures sur l'implémentation. Le cycle complet, lui, ne bouge pas.</p>

<h3 id="le-goulot-a-encore-changé-de-place">Le goulot a encore changé de place</h3>

<p>Dans <a href="/quand-l-agent-livre-plus-vite-que-je-ne-lis/">un article précédent</a>,
j'écrivais que les agents ont réduit la construction à quelques
minutes, et que le goulot était passé à la relecture. Puis que
<a href="/les-agents-ont-rendu-le-bdd-rentable-pas-delegable/">le BDD</a>
permet de définir ce qui doit être vrai, et de relire des scénarios
plutôt que des diffs.</p>

<p>La suite est mécanique. Si le code coûte moins cher et que le contrat
est clair, la question devient : en combien de temps peut-on vérifier
que le code respecte le contrat, et le mettre en production sans
risque ? C'est le travail de la CI/CD. Et elle n'a pas été conçue pour
cette cadence.</p>

<p>L'IA accélère la production du code. La CI/CD doit accélérer la
confiance. Si elle ne le fait pas, l'accélération reste en amont, sous
forme de branches qui attendent.</p>

<h3 id="une-chaîne-déterministe-autour-dune-production-probabiliste">Une chaîne déterministe autour d'une production probabiliste</h3>

<p>Un agent ne produit pas deux fois le même code pour la même demande.
C'est sa nature, et ce n'est pas un défaut tant que quelque chose de
reproductible juge le résultat. Ce quelque chose, c'est la chaîne de
validation.</p>

<p>Elle doit vérifier, de la même façon à chaque passage :</p>

<ul>
  <li>les comportements attendus, c'est-à-dire les scénarios ;</li>
  <li>les invariants critiques, ceux qui ne doivent jamais casser ;</li>
  <li>l'absence de régression ;</li>
  <li>la sécurité ;</li>
  <li>la qualité de l'artefact produit.</li>
</ul>

<p>L'agent propose. La chaîne atteste. L'humain décide de ce que la
chaîne ne peut pas attester. C'est la séparation que j'explore avec
<a href="/labo/">workline</a> : ce qu'une machine peut
prouver seule, et ce qui doit rester une décision.</p>

<h3 id="la-couverture-ne-suffit-pas">La couverture ne suffit pas</h3>

<p>Un pourcentage de couverture élevé dit que des lignes ont été
exécutées. Il ne dit pas qu'un test aurait échoué si le comportement
avait disparu. Un test qui n'affirme rien couvre ses lignes et passe
au vert.</p>

<p>Avec un agent, le risque grandit : il sait écrire des tests qui
passent, et il est récompensé quand ils passent. Les vérifications qui
comptent sont celles qui cherchent activement à faire échouer le code :</p>

<ul>
  <li>les <strong>scénarios métier</strong>, qui disent ce qui doit être vrai ;</li>
  <li>le <strong>property-based testing</strong>, qui cherche le contre-exemple au lieu
de vérifier trois cas choisis à la main ;</li>
  <li>le <strong>fuzzing</strong>, sur tout ce qui parse une entrée extérieure ;</li>
  <li>le <strong>mutation testing</strong>, qui modifie le code et vérifie qu'au moins
un test le remarque. C'est la seule mesure qui répond à la question
« mes tests peuvent-ils échouer ? » ;</li>
  <li>quelques <strong>tests d'intégration ciblés</strong>, là où les mocks mentent.</li>
</ul>

<h3 id="paralléliser-la-validation">Paralléliser la validation</h3>

<p>Quand la production de code accélère, une suite qui tourne en
séquence devient une file d'attente. Ajouter des tests sans réfléchir
à leur ordre allonge chaque cycle de la même durée, pour chaque
changement.</p>

<p>La suite doit s'organiser comme un graphe, pas comme une liste : par
dépendances, par niveau de risque, et selon ce que le changement
touche réellement. Un changement dans la documentation ne relance pas
les tests d'intégration. Un changement dans le module de paiement les
relance tous. Les vérifications rapides et décisives passent en
premier, pour échouer tôt. L'heure de CI de mon incident n'était pas
une fatalité : c'était une suite de tests fonctionnels qui attendaient
leur tour les uns derrière les autres.</p>

<h3 id="arrêter-de-tout-mettre-dans-lassiette">Arrêter de tout mettre dans l'assiette</h3>

<p>L'autre façon d'allonger une CI, c'est d'y empiler tout ce qui peut
se vérifier. L'orthographe des spécifications. La syntaxe des
diagrammes Mermaid. Le formatage du Markdown. Chacune de ces
vérifications est raisonnable prise seule. Sur un dépôt qui contient
beaucoup de fichiers, leur somme coûte des minutes à chaque passage,
et elle bloque des changements qui n'ont rien à voir.</p>

<p>Je pose la question autrement : qu'est-ce que cette vérification
protège ? Une faute de frappe dans une spécification ne change pas le
comportement du système. Un humain la lit sans buter, et un LLM la
comprend sans difficulté. Une régression fonctionnelle, elle, part en
production.</p>

<p>Ces vérifications ont leur place dans l'éditeur, dans un hook local,
ou dans une tâche qui ne bloque rien. Pas dans le chemin critique qui
sépare un correctif de la production. Une CI qui fait tourner vite de
bons tests fonctionnels et d'acceptation, avec une vraie couverture du
comportement, vaut mieux qu'une CI exhaustive qui livre en retard des
spécifications sans faute.</p>

<h3 id="produire-un-artefact-de-confiance">Produire un artefact de confiance</h3>

<p>Le même artefact, construit une fois et versionné, doit traverser
tous les environnements. Pas une reconstruction à chaque étape, avec
des dépendances résolues à des moments différents et un résultat que
personne n'a réellement testé.</p>

<p>Ce que la CI a validé doit être exactement ce qui part en production.
Sinon, la validation porte sur un objet qui n'existe plus.</p>

<h3 id="le-rollback-fait-partie-du-déploiement">Le rollback fait partie du déploiement</h3>

<p>Un rollback jamais testé est un espoir écrit en YAML.</p>

<p>Quand le rythme de livraison augmente, le nombre de mises en
production augmente avec lui, et donc le nombre de fois où l'une
d'elles se passe mal. La réponse n'est pas de ralentir. C'est de
limiter le rayon d'explosion de chaque livraison :</p>

<ul>
  <li>des <strong>feature flags</strong>, pour séparer le déploiement de l'activation ;</li>
  <li>des <strong>déploiements progressifs</strong>, sur une fraction du trafic
d'abord ;</li>
  <li>une <strong>observabilité</strong> qui dit en minutes si le comportement en
production correspond au comportement attendu ;</li>
  <li>un <strong>retour arrière</strong> qui fait partie du chemin normal, exercé
régulièrement, et pas une procédure d'urgence qu'on découvre le
jour où on en a besoin.</li>
</ul>

<h3 id="accélérer-la-confiance">Accélérer la confiance</h3>

<p>Les agents ont rendu le code bon marché. Ils n'ont rendu bon marché
ni la vérification, ni la mise en production, ni le retour arrière.
Si ces trois-là gardent leur rythme d'avant, le cycle de livraison
garde le sien aussi, et l'accélération se transforme en stock de
changements qui attendent.</p>

<p>La question à poser à votre chaîne n'est donc pas « à quelle
vitesse produit-on du code ? ». C'est « à quelle vitesse
peut-on avoir confiance dans ce qu'on livre ? ».</p>]]></content><author><name>Anas Ameziane</name></author><category term="agentic" /><category term="shipping" /><category term="specification" /><summary type="html"><![CDATA[Les agents accélèrent le code. Le cycle de livraison ne raccourcit que si la chaîne de validation absorbe la cadence. Sinon, la file d'attente se déplace.]]></summary></entry><entry xml:lang="fr"><title type="html">Les agents ont rendu le BDD rentable. Pas délégable.</title><link href="https://anasdox.github.io/les-agents-ont-rendu-le-bdd-rentable-pas-delegable/" rel="alternate" type="text/html" title="Les agents ont rendu le BDD rentable. Pas délégable." /><published>2026-10-09T00:00:00+00:00</published><updated>2026-10-09T00:00:00+00:00</updated><id>https://anasdox.github.io/les-agents-ont-rendu-le-bdd-rentable-pas-delegable</id><content type="html" xml:base="https://anasdox.github.io/les-agents-ont-rendu-le-bdd-rentable-pas-delegable/"><![CDATA[<p>En montant <a href="https://github.com/anasdox/bdd-with-ai">bdd-with-ai</a>, un
dépôt où des agents travaillent à partir de scénarios de comportement,
j'ai vu deux choses qui semblaient se contredire.</p>

<p>La première : un agent m'a proposé un scénario d'erreur auquel
personne n'avait pensé. Un vrai cas, que nous aurions découvert en
production.</p>

<p>La seconde : un agent dont le code ne passait pas un scénario n'a pas
corrigé son code. Il a modifié le scénario. Les tests sont passés au
vert.</p>

<p>Ce sont les deux faces du même constat. Les agents rendent le BDD
enfin abordable. Ils peuvent aussi le vider de son sens en une
modification.</p>

<h3 id="pourquoi-le-bdd-mourait">Pourquoi le BDD mourait</h3>

<p>Le Behavior-Driven Development n'a jamais eu de problème d'idée.
Décrire le comportement attendu avant d'écrire le code, dans une
langue que le métier peut relire : personne ne conteste le principe.</p>

<p>Il avait un problème d'addition. Écrire les scénarios prenait du
temps. Écrire le code de liaison entre les phrases Gherkin et le
système en prenait davantage. Et surtout, il fallait tout maintenir :
chaque évolution du produit cassait des étapes, dupliquait des
phrases, laissait des scénarios décrire un comportement qui n'existait
plus.</p>

<p>Je l'ai vu de près. La discipline tenait tant que l'équipe avait du
temps. Au premier sprint sous tension, les scénarios passaient en
« on rattrapera après ». On ne rattrapait pas. Le dossier <code class="language-plaintext highlighter-rouge">features/</code> devenait un
musée.</p>

<h3 id="ce-que-les-agents-changent-dans-laddition">Ce que les agents changent dans l'addition</h3>

<p>Presque toutes les lignes de cette addition sont du travail qu'un
agent fait bien et vite :</p>

<ul>
  <li>rédiger un premier jet de scénarios à partir d'un besoin décrit en
quelques paragraphes ;</li>
  <li>proposer les cas que personne n'a écrits, en particulier les
chemins d'erreur ;</li>
  <li>générer et maintenir le code de liaison des étapes ;</li>
  <li>repérer les phrases dupliquées et les scénarios qui se recouvrent ;</li>
  <li>remettre les étapes d'aplomb quand le système évolue.</li>
</ul>

<p>Prenons un scénario simple :</p>

<div class="language-gherkin highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">Feature</span><span class="p">:</span> Import de réservations

  <span class="kn">Scenario</span><span class="p">:</span> Les lignes valides sont enregistrées
    <span class="nf">Given </span>un fichier de 3 000 réservations dont 12 invalides
    <span class="nf">When </span>l'opératrice dépose le fichier
    <span class="nf">Then </span>les 2 988 lignes valides sont enregistrées
    <span class="nf">And </span>les 12 lignes invalides sont signalées
</code></pre></div></div>

<p>Demandez à un agent ce qui manque, il revient avec des questions
utiles. Que se passe-t-il si le même fichier est déposé deux fois ?
Si toutes les lignes sont invalides ? Si le fichier est vide ? Chacune
est un scénario que l'équipe aurait dû écrire, et qu'elle découvrait
d'habitude en production.</p>

<p>Le coût marginal d'un scénario s'est effondré. L'argument « on n'a
pas le temps » ne tient plus. C'est la bonne nouvelle, et elle est
réelle.</p>

<h3 id="le-piège--le-contrat-qui-se-signe-tout-seul">Le piège : le contrat qui se signe tout seul</h3>

<p>La tentation suivante est logique : si l'agent écrit les scénarios, le
code de liaison et l'implémentation, pourquoi ne pas lui laisser toute
la chaîne ? On décrit le besoin, l'agent produit le reste, les tests
passent.</p>

<p>À ce moment-là, le BDD ne sert plus à rien. Un scénario n'a de valeur
que parce qu'il est écrit <strong>indépendamment</strong> du code qu'il juge. Si la
même main rédige la règle et ce qui la satisfait, le vert ne prouve
qu'une chose : l'agent est d'accord avec lui-même. Il vous a fallu une
minute pour obtenir un contrat circulaire.</p>

<p>C'est pire qu'un manque de tests, parce que ça y ressemble. La colonne
est remplie, les scénarios sont bien écrits, le rapport est vert. Rien
de tout ça ne dit si le comportement est celui que le métier attendait.</p>

<h3 id="proposer-nest-pas-décider">Proposer n'est pas décider</h3>

<p>La répartition qui tient est simple à énoncer :</p>

<ul>
  <li><strong>L'agent propose.</strong> Premier jet, cas manquants, reformulations,
détection de doublons. Il est meilleur que moi pour l'exhaustivité.</li>
  <li><strong>L'humain décide.</strong> Je relis les scénarios, je tranche les
questions ouvertes avec les personnes qui vivront avec la
fonctionnalité, et je fige le contrat avant que l'implémentation
commence.</li>
  <li><strong>Le contrat ne bouge plus pendant l'implémentation.</strong> Si l'agent a
besoin de modifier un scénario pour faire passer son code, c'est un
signal d'alerte, pas une correction. Soit le scénario était faux, et
c'est une décision humaine de le changer. Soit le code est faux, et
le scénario vient de faire son travail.</li>
</ul>

<p>Concrètement, ça veut dire que les scénarios et le code n'arrivent pas
dans la même relecture. Les scénarios sont relus et validés d'abord,
sur leur propre changement. Le code vient ensuite, et se juge contre
eux.</p>

<h3 id="documentation-vivante-à-une-condition">Documentation vivante, à une condition</h3>

<p>On dit souvent que les fichiers Gherkin deviennent une documentation
qui ne pourrit plus, puisque l'agent peut la tenir à jour. C'est vrai
à une condition : que chaque scénario puisse <strong>échouer</strong> le jour où le
comportement disparaît. Un scénario dont les étapes ne vérifient rien
documente une intention, pas le système. Il est même plus dangereux
qu'une page obsolète, parce qu'il est vert.</p>

<p>L'agent rend la maintenance gratuite. Il ne rend pas la vérification
automatique. C'est à vous de vous assurer que le vert veut encore dire
quelque chose.</p>

<h3 id="ce-qui-a-changé-et-ce-qui-na-pas-changé">Ce qui a changé, et ce qui n'a pas changé</h3>

<p>Ce qui a changé : écrire et maintenir des scénarios ne coûte presque
plus rien. Le BDD n'a plus d'excuse économique pour être abandonné.</p>

<p>Ce qui n'a pas changé : quelqu'un doit dire ce que « correct »
veut dire pour ce logiciel, et en répondre. Ce geste-là ne se délègue
pas. Les agents ont rendu le BDD rentable. Ils l'ont rendu plus
important à signer, pas plus facile à abandonner.</p>

<p>La boucle que j'utilise au quotidien est décrite dans
<a href="/quand-l-agent-livre-plus-vite-que-je-ne-lis/">Quand l'agent livre plus vite que je ne lis</a>,
et la place du BDD dans le cadrage d'un problème sur la page
<a href="/methode/">Méthode</a>. Le modèle de dépôt est sur
<a href="https://github.com/anasdox/bdd-with-ai">github.com/anasdox/bdd-with-ai</a>.</p>]]></content><author><name>Anas Ameziane</name></author><category term="agentic" /><category term="validation" /><summary type="html"><![CDATA[Le BDD mourait de son coût d'écriture et de maintenance. Les agents l'ont effondré. Le seul geste qu'ils ne font pas à votre place : signer le scénario.]]></summary></entry><entry xml:lang="fr"><title type="html">Idéalement, Réalité, Conséquences</title><link href="https://anasdox.github.io/idealement-realite-consequences/" rel="alternate" type="text/html" title="Idéalement, Réalité, Conséquences" /><published>2026-05-29T00:00:00+00:00</published><updated>2026-05-29T00:00:00+00:00</updated><id>https://anasdox.github.io/idealement-realite-consequences</id><content type="html" xml:base="https://anasdox.github.io/idealement-realite-consequences/"><![CDATA[<p>Chaque epic que mon équipe écrit porte une description en trois
sections obligatoires, et un petit linter la rejette quand l'une
manque. Les sections sont toujours les mêmes, toujours dans le même
ordre : Idéalement, Réalité, Conséquences. Aucune des trois n'a le
droit de contenir une solution.</p>

<p>Cette dernière règle est tout l'enjeu. Le pattern n'est pas un modèle
pour écrire des tickets plus vite. C'est une contrainte qui force le
problème à exister sur la page avant que quiconque ait le droit de
concevoir contre lui.</p>

<h3 id="à-quoi-sert-chaque-section">À quoi sert chaque section</h3>

<p><strong>Idéalement</strong>, c'est le monde tel qu'il devrait être. L'état qu'on
observerait si le problème n'existait pas. <em>« Tout serveur qui échoue
à un contrôle réseau automatique est réalloué sans qu'un humain y
touche. »</em> C'est la description d'une destination, écrite au présent,
sans aucune référence à la façon d'y arriver.</p>

<p><strong>Réalité</strong>, c'est le monde tel qu'il est aujourd'hui. L'écart.
<em>« Aujourd'hui le contrôle se déclenche, mais la réallocation bloque
sur une validation manuelle que personne ne porte, donc les serveurs
restent non attribués quatre jours en moyenne. »</em> C'est la section
qui doit pouvoir être vérifiée contre les faits. Si la Réalité est
floue, le problème n'est pas encore compris, et aucune conception de
solution ne le rattrapera.</p>

<p><strong>Conséquences</strong>, c'est ce que coûte l'écart. Le « et alors ? ».
<em>« Quatre jours de matériel inutilisé par incident, une escalade
récurrente vers l'astreinte, et un SLA de livraison client que nous
ratons discrètement deux fois par mois. »</em> Sans cette section, tous
les problèmes paraissent aussi urgents et rien ne peut être priorisé.
Avec elle, le lecteur peut dimensionner la chose avant d'y consacrer
une seule journée.</p>

<p>Trois sections, et la solution n'apparaît dans aucune. Elle vient
plus tard, dans un champ séparé, écrite par quelqu'un qui a lu les
trois.</p>

<h3 id="pourquoi-lordre-et-pourquoi-le-mur">Pourquoi l'ordre, et pourquoi le mur</h3>

<p>L'ordre n'est pas décoratif. On ne peut pas écrire honnêtement les
Conséquences tant que la Réalité n'est pas précise, et on ne peut pas
écrire la Réalité sans s'être engagé sur un Idéalement assez précis
pour mesurer l'écart. Chaque section porte la suivante. Sautez
Idéalement, et la Réalité devient une liste de plaintes. Sautez la
Réalité, et les Conséquences deviennent une peur.</p>

<p>Le mur entre le problème et la solution est la partie à laquelle les
gens résistent. Il paraît inefficace. L'auteur arrive généralement
avec une réponse déjà en main, et les trois sections ressemblent à
une cérémonie qui se dresse entre lui et le moment de l'écrire.</p>

<p>Mais c'est précisément le mur qui protège l'ingénieur en aval.</p>

<h3 id="le-mode-déchec-quil-empêche">Le mode d'échec qu'il empêche</h3>

<p>Donnez à un ingénieur un ticket qui contient déjà une solution, et il
construira cette solution. Ce n'est pas de la paresse. C'est la
réponse rationnelle à une consigne claire. Le problème, c'est qu'une
solution rédigée comme un énoncé de problème n'a ni écart ni coût
attaché, donc l'ingénieur n'a rien pour la vérifier. Là où la consigne
se tait, son propre jugement comble le vide, et ce jugement est la
subjectivité d'une autre personne que celle qui a écrit le ticket. Le
résultat a l'air conforme et il est discrètement faux.</p>

<p>J'ai vu ça se produire assez souvent pour faire davantage confiance
au pattern qu'à ma propre discipline. Un ingénieur qui reçoit
Idéalement, Réalité, Conséquences reçoit le problème au lieu de la
réponse. Il voit la destination, l'écart et l'enjeu. Il peut alors
faire ce que j'attends vraiment de lui : concevoir la bonne réponse,
ou revenir me dire que le problème tel qu'il est formulé n'est pas le
vrai. Un ticket qui commence par une solution ferme les deux portes.</p>

<h3 id="la-même-discipline-un-autre-artefact">La même discipline, un autre artefact</h3>

<p>C'est la même règle que je retrouve dans toutes les formes de
discovery. En entretien, elle prend la forme de questions sans
solution : on interroge le problème, la douleur, le contournement,
jamais son idée. Dans une restitution écrite, elle prend la forme
Faits avant Insights avant Recommandations, la conclusion ayant
interdiction de contaminer les éléments. Dans un epic Jira, elle
prend la forme Idéalement, Réalité, Conséquences, la solution restant
hors des trois.</p>

<p>Des artefacts différents, un seul principe : garder le problème et la
solution dans des compartiments séparés, et écrire le problème
d'abord. Le mur entre les compartiments est bon marché à construire
et coûteux à sauter. Chaque heure passée à rendre la Réalité précise
est une heure que l'équipe ne passe pas à construire quelque chose de
précis et d'inutile.</p>

<p>La méthode complète est sur la page
<a href="/methode/">Méthode</a>. La version qui la
surplombe est plus courte :</p>

<blockquote>
  <p>Passer plus de temps à comprendre le problème qu'à concevoir la solution.</p>
</blockquote>]]></content><author><name>Anas Ameziane</name></author><category term="discovery" /><summary type="html"><![CDATA[Trois sections obligatoires dans chaque epic, et aucune n'a le droit de contenir une solution. Pourquoi le mur entre problème et solution protège l'ingénieur en aval.]]></summary></entry><entry xml:lang="fr"><title type="html">Le pourquoi que je devais aux ingénieurs suivants</title><link href="https://anasdox.github.io/le-pourquoi-que-je-devais-aux-ingenieurs-suivants/" rel="alternate" type="text/html" title="Le pourquoi que je devais aux ingénieurs suivants" /><published>2026-05-29T00:00:00+00:00</published><updated>2026-05-29T00:00:00+00:00</updated><id>https://anasdox.github.io/le-pourquoi-que-je-devais-aux-ingenieurs-suivants</id><content type="html" xml:base="https://anasdox.github.io/le-pourquoi-que-je-devais-aux-ingenieurs-suivants/"><![CDATA[<p>Pendant la première moitié de ma carrière, j'étais le développeur en
bout de chaîne. Une fonctionnalité atterrissait sur mon bureau, avec
une spec, une échéance, parfois un ticket Jira et un lien Figma. Ce
qu'elle n'apportait jamais, c'était la réponse à la question que je
posais sans cesse : <em>pourquoi est-ce qu'on construit ça ?</em></p>

<p>Je ne parle pas du « quel problème business ça résout » sous la forme
polie qui finit sur une slide. Je parle de : qui souffre, qu'est-ce
qu'ils ont réellement dit, qu'est-ce qu'on a observé, qu'est-ce qui
nous a fait choisir cette option plutôt que les trois autres.
L'information qui m'aurait permis de réagir quand un cas limite du
design contredisait discrètement l'intention apparente.
L'information qui m'aurait permis de trancher un petit arbitrage sans
escalader.</p>

<p>Chaque fois que je creusais pour trouver cette information, l'une de
deux choses s'avérait vraie. Soit le problème avait été mal identifié
en amont, et la spec était le produit poli d'une conversation floue
dont personne ne se souvenait vraiment. Soit l'information existait,
quelque part : dans la tête d'un product manager, dans la marge d'un
deck, dans le compte rendu d'une réunion à laquelle je n'avais pas
accès. Et y accéder coûtait plus de capital politique que la question
n'en valait.</p>

<p>Alors je construisais la fonctionnalité avec le signal dont je
disposais. La plupart du temps elle était livrée, utilisée, et ça
allait. Parfois, un an plus tard, on découvrait qu'on avait construit
précisément la mauvaise chose, et personne n'arrivait vraiment à
reconstituer comment on en était arrivé là.</p>

<hr />

<p>Des années plus tard, j'ai changé de côté. Je suis devenu architecte
solutions en avant-vente : dans la salle avec le client, à cadrer le
problème, concevoir la réponse, puis passer la main à l'équipe de
delivery pour la construire. Pour la première fois, c'était moi qui
écrivais la spec que l'ingénieur suivant lirait.</p>

<p>J'avais une promesse très précise à tenir : ne pas faire à ces ingénieurs
ce qu'on m'avait fait.</p>

<p>Cette promesse paraît évidente. En pratique, elle est plus difficile
qu'elle n'en a l'air. La pression sur l'architecte pousse à
compresser : une recommandation nette, un effort estimé, un schéma
propre. Elle pousse à retirer le bruit, les contradictions, les
non-dits de la discovery, parce que la proposition doit paraître
décidée. Chaque gramme de compression rend la vie de l'ingénieur suivant plus
difficile.</p>

<p>Il me fallait une discipline qui me permette de compresser la
conclusion sans compresser la piste.</p>

<hr />

<p>La discipline vers laquelle j'ai convergé s'appelle FIR : Faits,
Insights, Recommandations. Chaque couche est écrite séparément, et
chaque conclusion d'une couche doit citer les éléments de la couche
du dessous.</p>

<p><strong>Les Faits</strong> sont ce qui a réellement été dit ou observé pendant la
discovery. Les mots mêmes de l'utilisateur. La capture d'écran du
reçu cassé. Le chiffre sur le tableau de bord. Aucune paraphrase.</p>

<p><strong>Les Insights</strong> sont ce que signifient les Faits quand on en lit
plusieurs ensemble. Des motifs, des contradictions, des manques.
Chaque Insight référence les Faits qu'il interprète. Un second
lecteur peut ne pas être d'accord, et ce désaccord est fondé.</p>

<p><strong>Les Recommandations</strong> sont ce qu'il faut faire. Chaque
Recommandation référence les Insights dont elle découle.</p>

<p>L'intérêt de la structure n'est pas son élégance. L'intérêt, c'est
que l'ingénieur qui reprend la spec six semaines plus tard, dans un autre
fuseau horaire, peut remonter d'une recommandation à l'insight qui la
porte, et de cet insight à une phrase que quelqu'un a réellement
prononcée. Le pourquoi n'est plus dans la tête de l'architecte. Il est
dans la chaîne.</p>

<p>La variante que j'utilise aujourd'hui au quotidien s'appelle Atomic
Research. Mêmes trois couches, mais les expériences qui produisent
les faits (entretiens, sessions d'observation, sondages, données
brutes) y sont traitées comme des objets à part entière de la
structure. J'ai formalisé cette méthodologie pour la pratique de
discovery de mon employeur actuel, pour que la piste ne dépende pas
de ma présence ou non en réunion.</p>

<hr />

<p>Ce que je n'ai pas compris pendant des années, c'est que la structure
ne survit pas à un document ordinaire. Les slides inversent la
hiérarchie : la recommandation en titre, les faits en note de bas de
page. Les tables Notion laissent tout atterrir dans une seule colonne
Notes. Excel pardonne toutes les colonnes qu'on n'utilise pas. Les
trois couches survivent à la première séance. Elles ne survivent pas
à la troisième.</p>

<p>Alors j'ai construit <a href="https://github.com/anasdox/factly">factly</a>, un
petit espace de travail où les colonnes ne sont pas optionnelles. Les
entrées à gauche, puis les Faits, puis les Insights, puis les
Recommandations, puis les livrables. Chaque élément pointe vers ce
dont il dépend. Un Insight sans Fait n'existe pas dans la grille. Une
Recommandation sans Insight n'existe pas dans la grille. L'ingénieur qui
lit le livrable peut suivre le fil jusqu'à l'observation d'origine.
La discipline devient mécanique, et c'est la seule façon pour elle de
survivre à un long trimestre.</p>

<hr />

<p>Je ne suis pas naïf. Beaucoup d'engagements livrent encore une
recommandation soignée et très peu de piste. Mais sur ceux où la
piste a survécu, les ingénieurs suivants ont posé des questions plus
tranchantes, pris de meilleures décisions locales, et contesté des
choses que le cadrage d'origine avait mal comprises. C'est le seul
résultat qui comptait pour moi depuis le jour où j'ai changé de côté.</p>

<p>La méthode complète est sur la page
<a href="/methode/">Méthode</a>. La version que je relis
en tête de chaque restitution est plus courte :</p>

<blockquote>
  <p>Passer plus de temps à comprendre le problème qu'à concevoir la solution.</p>
</blockquote>]]></content><author><name>Anas Ameziane</name></author><category term="specification" /><summary type="html"><![CDATA[Ce que je devais aux ingénieurs qui liraient mes specs, et pourquoi Faits, Insights, Recommandations est la structure à laquelle je confie le pourquoi.]]></summary></entry><entry xml:lang="fr"><title type="html">Quand l&apos;agent livre plus vite que je ne lis</title><link href="https://anasdox.github.io/quand-l-agent-livre-plus-vite-que-je-ne-lis/" rel="alternate" type="text/html" title="Quand l&apos;agent livre plus vite que je ne lis" /><published>2026-05-29T00:00:00+00:00</published><updated>2026-05-29T00:00:00+00:00</updated><id>https://anasdox.github.io/quand-l-agent-livre-plus-vite-que-je-ne-lis</id><content type="html" xml:base="https://anasdox.github.io/quand-l-agent-livre-plus-vite-que-je-ne-lis/"><![CDATA[<p>L'échange se passe en général comme ça. Je décris une fonctionnalité
en deux paragraphes. L'agent revient dix minutes plus tard avec trois
mille lignes de code, un diff propre, des tests au vert et une
description de PR mieux écrite que celle que j'aurais rédigée.</p>

<p>Je fais défiler. Je fais encore défiler. Les tests passent. La
structure a l'air raisonnable. Le nommage respecte les conventions.
J'ai dix autres choses à faire aujourd'hui.</p>

<p>J'approuve.</p>

<p>C'est à ce moment-là que j'ai cessé d'être l'ingénieur pour devenir
le spectateur de ma propre base de code. L'agent n'a pas d'astreinte,
pas d'impact client, pas de post-mortem à redouter. Le risque n'a pas
bougé. Il est toujours à moi. Mais ma capacité à le voir vient de
chuter d'un ordre de grandeur, parce que je relis du code que je n'ai
pas écrit, contre une architecture que l'agent a déduite, dans un
budget de temps qui, lui, n'a pas changé.</p>

<p>J'ai commencé à le remarquer au bout de quelques mois. La première
fois, j'ai haussé les épaules. La troisième fois, mon ego l'a senti
passer.</p>

<h3 id="le-centre-de-gravité-sest-déplacé">Le centre de gravité s'est déplacé</h3>

<p>Le logiciel a quatre phases qui prenaient à peu près le même temps :
spécifier, construire, valider, relire. Les agents de code génératifs
ont réduit la construction à quelques minutes. Les trois autres n'ont
pas changé. Ce sont des phases humaines. Elles demandent du temps
humain, de l'attention humaine, de la bande passante humaine.</p>

<p>Résultat : le goulot d'étranglement a bougé, et nous non. Nous livrons
du code que personne n'a entièrement compris pendant son écriture,
dans des bases de code que personne n'a entièrement comprises en
train de l'absorber. La description honnête de ce qui se passe
ensuite, c'est : <em>on approuve et on passe à la suite</em>. Le coût d'une
approbation sans compréhension reste invisible jusqu'à l'incident.</p>

<h3 id="le-problème-nest-plus-comment-coder">Le problème n'est plus « comment coder »</h3>

<p>Le problème, c'est « comment garder le contrôle ». L'agent sait
générer. Il ne peut pas endosser la responsabilité. Si c'est moi
qu'on appelle le dimanche matin, c'est moi qui dois à la base de code
un niveau d'attention que l'agent est incapable de fournir à ma place.</p>

<p>Écrit comme ça, ça paraît évident. Ça l'est beaucoup moins quand la
PR est au vert et que l'agent attend le prompt suivant.</p>

<h3 id="relire-le-comportement-pas-le-code">Relire le comportement, pas le code</h3>

<p>Le changement qui a marché pour moi est celui que le Behavior-Driven
Development attendait patiemment de faire. Avant les agents
génératifs, écrire des spécifications exécutables avant le code
ressemblait à un surcoût. Les équipes écrivaient les scénarios, mais
lentement, et seulement quand la fonctionnalité était assez grosse
pour justifier la cérémonie. La discipline s'effondrait au premier
sprint sous tension.</p>

<p>Les agents génératifs inversent l'économie. Le code ne coûte plus
rien. La spécification du comportement est le seul artefact dont je
dois encore absorber le sens. Lire un scénario Gherkin prend trente
secondes. Lire les trois mille lignes qui l'implémentent prend une
demi-journée que je n'ai pas.</p>

<p>L'unité de relecture est donc remontée d'un niveau. Je consacre
désormais mon attention à cinq à dix scénarios à la fois, écrits dans
le langage omniprésent (<em>ubiquitous language</em>) du projet, validés par
les personnes qui vivront avec la fonctionnalité. L'agent implémente
ensuite, lance les tests, itère jusqu'à ce qu'ils passent, montre le
résultat, et attend.</p>

<p>La charge cognitive baisse, parce que les artefacts que je lis sont
courts et porteurs de sens. Le contrôle augmente, parce que rien
n'atteint la base de code sans avoir survécu à un contrat de
comportement que j'ai réellement compris. La qualité augmente, parce
que le contrat est aussi la suite de non-régression.</p>

<h3 id="à-quoi-ressemble-la-boucle">À quoi ressemble la boucle</h3>

<p>La forme de la boucle est toujours la même. J'écris une description
de fonctionnalité avec trois à dix scénarios au format
Given-When-Then. L'agent génère l'échafaudage de tests à partir des
scénarios, et je relis cet échafaudage. L'agent génère le code de
production qui fait passer les tests. Je relis le résultat au regard
des scénarios, pas du diff ligne à ligne. L'agent montre le
comportement en fonctionnement. Je valide, ou j'affine les scénarios
et on repart pour un tour.</p>

<div class="mermaid">
flowchart TD
  Start(["Description, 3 à 10 scénarios"]) --> Scaffold["Agent : échafaudage de tests"]
  Scaffold --> ReviewSpec{"Humain : les tests reflètent les scénarios ?"}
  ReviewSpec -- non --> Start
  ReviewSpec -- oui --> Implement["Agent : code de production"]
  Implement --> Run["Agent : lance les tests, itère"]
  Run --> Demo["Agent : montre le comportement"]
  Demo --> Validate{"Humain : comportement correct ?"}
  Validate -- non --> Start
  Validate -- oui --> Done(["Validation"])
</div>

<p>Ce que je fais dans cette boucle, c'est ce que j'ai toujours fait
comme ingénieur : décider de ce que « correct » veut dire pour ce
logiciel, dans une langue qu'une partie prenante peut lire. Ce qui a
changé, c'est que j'ai cessé de passer l'essentiel de ma journée dans
l'éditeur qui produit le code, pour la passer dans le document qui
décide de ce que le code doit faire.</p>

<p>L'agent a livré l'implémentation. J'ai livré le contrat. C'est la
division du travail que je veux pour les bases de code dont je serai
responsable dans deux ans.</p>

<p>Le modèle de dépôt que j'utilise comme point de départ est sur
<a href="https://github.com/anasdox/bdd-with-ai">github.com/anasdox/bdd-with-ai</a>.
L'explication plus longue de la place centrale des spécifications de
comportement dans ma façon de travailler est sur la page
<a href="/methode/">Méthode</a>.</p>]]></content><author><name>Anas Ameziane</name></author><category term="agentic" /><category term="specification" /><category term="cognitive-load" /><summary type="html"><![CDATA[Les agents de code ont réduit la construction à quelques minutes. Spécifier, valider et relire n'ont pas bougé. Pourquoi je relis désormais le comportement, pas le code.]]></summary></entry><entry xml:lang="fr"><title type="html">La question qui contenait sa propre réponse</title><link href="https://anasdox.github.io/la-question-qui-contenait-sa-propre-reponse/" rel="alternate" type="text/html" title="La question qui contenait sa propre réponse" /><published>2026-05-28T00:00:00+00:00</published><updated>2026-05-28T00:00:00+00:00</updated><id>https://anasdox.github.io/la-question-qui-contenait-sa-propre-reponse</id><content type="html" xml:base="https://anasdox.github.io/la-question-qui-contenait-sa-propre-reponse/"><![CDATA[<p>Au début de mes années de conseil, j'ai participé à une séance de
discovery avec la responsable des opérations d'un client. Je voulais
comprendre comment son équipe traitait un fichier de rapprochement
quotidien. J'avais une hypothèse : le travail était répétitif, il
gagnerait à être automatisé, l'équipe était probablement en
sous-effectif pour le volume.</p>

<p>La première chose que j'ai demandée, c'est : <em>« Vous ne pensez pas
que ça aiderait si on automatisait ça ? »</em></p>

<p>Elle a dit oui. Évidemment qu'elle a dit oui. Je lui avais demandé,
devant son propre patron, si elle aimerait que son équipe soit
soulagée. La seule réponse qui ne la faisait pas passer pour ingrate
était celle que j'avais déjà écrite dans la question.</p>

<p>Nous avons passé deux mois à construire l'automatisation. L'équipe
l'a utilisée une semaine, puis elle est discrètement retournée sur
Excel.</p>

<p>Quand je suis revenu demander pourquoi, la vraie histoire est sortie.
Le rapprochement n'était pas la partie pénible de leur journée. La
partie pénible, c'était le fichier en amont : il arrivait en retard,
dans des formats incohérents, avec des lignes qui contredisaient
celles de la semaine précédente. Le fonctionnement sous Excel s'était
construit autour de ces bizarreries. L'automatisation que nous avions
construite était stricte là où ils avaient appris à être souples, et
elle cassait à la première ligne mal formée.</p>

<p>La vraie correction se situait en amont, et elle n'était pas
technique. C'était une conversation avec le producteur des données
sur des garanties de format. Une conversation que nous n'avons jamais
eue, parce que ma première question lui avait fermé la porte avant
même qu'elle s'ouvre.</p>

<hr />

<p>Cette séance est le moment où j'ai commencé à prendre l'entretien au
sérieux, comme un métier. J'ai reconstruit ma pratique de la
discovery autour de trois règles, et je les suis depuis.</p>

<p><strong>Pas de questions en forme de solution.</strong> La forme de la question
contraint la forme de la réponse. <em>« Est-ce que ça vous aiderait
d'avoir X ? »</em> obtiendra un oui poli. <em>« Racontez-moi la dernière
fois que ça a fait mal »</em> obtiendra l'histoire dont vous avez besoin.</p>

<p><strong>Les cinq pourquoi, sans raccourci.</strong> La première réponse est la
surface. La deuxième est le contournement. La troisième est
généralement la contrainte. Au-delà de la quatrième, vous touchez le
vrai moteur, qui est presque toujours organisationnel, économique, ou
lié à la peur de mal paraître.</p>

<p><strong>Écrire les Faits d'abord, les Insights ensuite, les Recommandations
en dernier.</strong> Les deux mois perdus sur la mauvaise automatisation
étaient deux mois de recommandations bâties sur un seul fait biaisé.
Si j'avais écrit <em>« J'ai posé une question orientée ; elle a dit
oui »</em> dans la couche des Faits, aucun Insight honnête n'aurait
survécu à son contact.</p>

<hr />

<p>La discipline n'a rien de glamour et elle n'impressionne pas dans une
proposition commerciale. Mais c'est la seule chose que je connaisse
qui empêche le mode d'échec silencieux : livrer la mauvaise chose,
dans les délais, dans le budget, correctement construite, et
discrètement inutilisée.</p>

<p>La méthode complète est sur la page
<a href="/methode/">Méthode</a>. La version courte est
celle du début : passer plus de temps à comprendre le problème qu'à
concevoir la solution.</p>]]></content><author><name>Anas Ameziane</name></author><summary type="html"><![CDATA[Une question orientée en séance de discovery a coûté deux mois d'automatisation que personne n'a utilisée. Les trois règles d'entretien que je suis depuis.]]></summary></entry><entry xml:lang="fr"><title type="html">Le dépôt AI-native</title><link href="https://anasdox.github.io/le-depot-ai-native/" rel="alternate" type="text/html" title="Le dépôt AI-native" /><published>2026-05-20T00:00:00+00:00</published><updated>2026-05-20T00:00:00+00:00</updated><id>https://anasdox.github.io/le-depot-ai-native</id><content type="html" xml:base="https://anasdox.github.io/le-depot-ai-native/"><![CDATA[<p>La plupart des ingénieurs avec qui je parle d'assistants de code IA
décrivent le même arc : quelques démos impressionnantes, puis une
longue traîne de frustration. Le modèle hallucine une fonction qui
n'existe pas, suggère une API dépréciée, ou réécrit un fichier qui
marchait avec une version légèrement moins bonne de lui-même.</p>

<p>La réponse habituelle est d'accuser le modèle. Je pense que le modèle
va généralement bien. C'est le dépôt qui pose problème.</p>

<h3 id="le-dépôt-comme-contexte">Le dépôt comme contexte</h3>

<p>Un grand modèle de langage n'a pas accès à l'intuition de votre
équipe. Il n'a aucun souvenir de la revue d'architecture du trimestre
dernier, aucune idée de l'abstraction qui porte la charge, aucun
indice que <code class="language-plaintext highlighter-rouge">customfield_12320</code> signifie « Acceptance Criteria » dans
votre instance Jira. Chaque interaction démarre à froid.</p>

<p>Si vous voulez que le modèle soit utile, vous devez écrire cette
intuition. Pas sous forme de commentaires éparpillés dans le code,
mais comme un contrat de premier niveau que le modèle peut lire d'une
traite. Dans mes propres dépôts, il vit dans un fichier appelé
<code class="language-plaintext highlighter-rouge">CLAUDE.md</code>, placé par convention à la racine. C'est la première
chose que lit le modèle, et c'est la différence entre un modèle qui
aide et un modèle qui livre du code cassé.</p>

<h3 id="ce-quon-y-met">Ce qu'on y met</h3>

<p>Trois choses, par ordre d'importance :</p>

<ol>
  <li>
    <p><strong>La posture.</strong> Qui est l'utilisateur, ce qu'il cherche à
accomplir, et quelle voix le modèle doit adopter pour lui
répondre. Pas du vernis sur le ton : de vrais garde-fous. « Fais
remonter les risques clairement. Propose des décisions, pas des
constats. Bref, direct. »</p>
  </li>
  <li>
    <p><strong>Les conventions.</strong> Les choses non évidentes. Où vivent
réellement les critères d'acceptation. Quels champs sont
modifiables par quelle API. Quels types de liens sont de vraies
dépendances et lesquels sont des anti-patterns. Chaque morceau de
savoir tribal qu'un nouvel ingénieur apprendrait pendant son
premier mois.</p>
  </li>
  <li>
    <p><strong>Les anti-patterns à refuser.</strong> Les erreurs que j'ai vu le modèle
faire deux fois. Pas comme des suggestions, comme des règles.
« N'affiche jamais un lien Jira sous la forme <code class="language-plaintext highlighter-rouge">Blocks &lt;- X</code>, le
sens est ambigu. Rends toujours le verbe complet, du point de vue
du ticket interrogé. »</p>
  </li>
</ol>

<p>Ce fichier est modifié chaque fois que le modèle se trompe d'une
nouvelle façon. Au fil des mois, il prend la même texture que la
mémoire de travail d'un ingénieur senior, sauf qu'elle est partagée,
versionnée, et rechargée à chaque prompt.</p>

<h3 id="le-levier">Le levier</h3>

<p>Le levier, ce n'est pas que le modèle écrive plus de code. C'est
qu'il écrive du code qui s'intègre. Les pull requests rétrécissent.
Les revues accélèrent. Ce qui demandait un échange Slack de quinze
minutes se règle désormais dans le prompt lui-même.</p>

<p>Je n'appellerais pas ça un gain de productivité. J'appellerais ça une
montée en gamme de la collaboration.</p>]]></content><author><name>Anas Ameziane</name></author><category term="agentic" /><summary type="html"><![CDATA[Les assistants de code IA échouent moins à cause du modèle qu'à cause du dépôt. Ce que doit contenir le contrat de contexte posé à la racine d'un repo.]]></summary></entry></feed>