Le secrétaire de Fernand

Des boucles de feedback plus solides commencent par du code explicite

Des boucles de feedback plus solides commencent par du code explicite

Pourquoi les boucles de feedback gagnent en puissance quand le code rend explicites ses concepts système.

Idée centrale — Une boucle de feedback peut détecter par elle-même que quelque chose a cassé. Mais elle ne peut dire quoi — nommer quelle forme du système a dérivé — que dans la mesure où ces formes sont explicites : états, contrats, frontières, invariants, responsabilités, signaux d'exécution.

Version courte : 2 min
Article complet : 16 min

Version courte

Une boucle de feedback ne devient pas puissante du seul fait d'exister. Elle le devient quand le code lui donne quelque chose de précis à voir. Un vérificateur de types ne peut vérifier une exhaustivité qui ait du sens que si les états et les événements sont explicites. Un audit d'architecture ne peut détecter une dérive que si les frontières, les couches et les responsabilités sont visibles. Un test proche de la production ne peut expliquer une panne que si le système émet des signaux d'exécution structurés.

C'est l'idée clé — la surface de vérification qu'expose le code. Plus le code est implicite, plus une boucle ne peut que dire quelque chose a cassé ; plus il est explicite, plus elle peut nommer quelle forme du système a dérivé.

C'est le pont entre code explicite et application des règles d'architecture. D'abord, on rend le système visible. Ensuite, on construit des boucles de feedback qui vérifient que les formes visibles tiennent dans la durée.

En trois idées

  1. Le feedback local devient plus fort quand le comportement est explicite. Types, unions discriminées, machines à états, matrices exhaustives, fonctions pures et contrats étroits donnent aux vérifications rapides quelque chose de réel à vérifier.

  2. Le feedback structurel devient plus fort quand l'architecture est explicite. Frontières, couches, imports, propriété (ownership), points de validation et responsabilités ne peuvent être audités que si le système les expose assez clairement.

  3. Le feedback produit devient plus fort quand le comportement à l'exécution est explicite. Les chemins critiques sont plus faciles à comprendre quand ils émettent des événements métier, des logs structurés, des traces, des identifiants de corrélation, des entrées rejetées et des transitions d'état.

À retenir

Le problème n'est pas d'ajouter plus de vérifications autour d'un système implicite. Le problème est d'écrire le système de sorte que chaque boucle de feedback ait quelque chose de précis à observer.


Article complet

Dans les deux articles précédents, j'ai défendu deux idées.

D'abord, le code est un système. Il ne devrait pas être jugé seulement comme de la belle prose, mais comme une structure qui doit tenir dans la réalité.

Ensuite, à l'ère des humains et des agents de code, l'explicite compte plus que l'implicite, parce que l'implicite n'est plus garanti d'être partagé.

L'étape suivante, c'est le feedback. Non pas le feedback comme un empilement de tests autour du code, mais le feedback comme moyen de vérifier que les formes explicites qu'expose le système — frontières, contrats, invariants, états, responsabilités, signaux d'exécution — continuent de tenir pendant que le code est produit.

Le point sur lequel repose cet article :

Une boucle de feedback n'est forte — pour nommer ce qui ne va pas — que dans la mesure de la structure explicite qu'elle peut observer.

Si le code cache ses états derrière des booléens éparpillés, le vérificateur de types ne peut pas vérifier le modèle d'états. Si les frontières n'existent que comme savoir d'équipe, une règle d'architecture ne peut pas les faire respecter. Si les erreurs sont loguées sans contexte, un test proche de la production peut échouer sans expliquer ce qui s'est passé.

Le feedback n'est pas extérieur à la conception du code. Il dépend de la surface de vérification que le code expose.

Le feedback est de la visibilité, pas de la réassurance

Une boucle de feedback faible rassure.

Une boucle de feedback forte révèle.

Elle révèle qu'une transition manque. Qu'une frontière a été franchie. Que des données externes sont entrées dans le système sans validation. Qu'un composant s'est approprié une logique qui ne devrait pas lui appartenir. Qu'un chemin critique a échoué et que les signaux d'exécution sont insuffisants pour expliquer pourquoi.

Cela compte parce que la fiabilité n'est pas produite par le seul volume de vérifications.

La couverture de feedback n'est pas fongible. On ne peut pas compenser un type de visibilité manquant en ajoutant davantage d'un autre type.

Mille tests unitaires ne révéleront pas une frontière d'architecture qui n'est représentée nulle part. Un audit d'imports parfait ne vous dira pas si un flux de paiement tient encore sous la latence. Un test de bout en bout ne vous dira pas, à lui seul, si un modèle d'états est exhaustif.

Chaque boucle a un rôle. Chaque boucle voit un type de déviation différent. Et chaque boucle dépend du fait que le système expose les bonnes structures.

La question n'est donc pas :

Combien de vérifications avons-nous ?

La meilleure question est :

Que rend visible chaque boucle, et que lui donne le code à observer ?

Détecter est facile ; attribuer demande de la structure

Il faut être honnête sur la limite de cette affirmation, car il existe une vraie objection. Certains feedbacks n'ont besoin de rien de votre part. Un fuzzer envoie des entrées malformées sur une frontière et trouve un crash sans connaître un seul de vos types. Un test à base de propriétés (property-based) vérifie un invariant sur des milliers de cas générés. Un test d'intégration en boîte noire frappe un vrai endpoint et remarque qu'il renvoie une mauvaise réponse. Aucun ne dépend du fait que le code expose une forme interne explicite, et tous trouvent de vrais bugs.

L'explicite n'est donc pas ce qui permet au feedback de détecter qu'il y a un problème. La détection peut être opaque.

Ce que l'explicite achète, c'est l'attribution : transformer « un test a échoué » en « cette transition est inatteignable », « cette frontière a été franchie », « des données externes sont entrées sans validation », « cet invariant a été rompu ». Un fuzzer vous dit que le système s'est effondré. Un modèle d'états explicite vous dit quel coup était illégal. Le premier est un symptôme ; le second est une cause sur laquelle agir directement.

C'est là le périmètre honnête de la thèse. La structure explicite n'augmente pas surtout le nombre de problèmes que vous attrapez. Elle augmente la précision avec laquelle chaque boucle peut nommer le problème qu'elle attrape — et nommer la cause plutôt que le symptôme, c'est ce qui permet à un humain ou à un agent de corriger la bonne chose au lieu de bricoler autour. Le feedback en boîte noire est le détecteur de fumée. La structure explicite, c'est ce qui vous dit dans quelle pièce.

Le code explicite augmente la surface de vérification

L'idée clé, c'est la surface de vérification. La surface de vérification, c'est l'ensemble des formes, dans le code, qu'un outil ou un relecteur peut réellement inspecter et confronter à une règle — les prises auxquelles le feedback peut s'accrocher. Un système implicite n'en offre presque aucune ; un système explicite en offre beaucoup.

Un système implicite donne très peu de prises aux boucles de feedback. Beaucoup de règles vivent dans la tête des développeurs. Beaucoup d'états sont déduits de combinaisons de drapeaux. Beaucoup de frontières sont des conventions sociales. Beaucoup d'invariants sont éparpillés dans des conditions. Beaucoup de responsabilités sont implicites, suggérées par des noms de fichiers ou des habitudes. Beaucoup de pannes à l'exécution ne produisent que des erreurs génériques.

Le système peut fonctionner, mais il y a peu de formes explicites à inspecter pour les outils.

Un système explicite est différent. Il donne aux outils et aux humains des surfaces concrètes à vérifier :

  • types ;
  • schémas ;
  • unions discriminées ;
  • machines à états ;
  • tables de transitions et matrices de disposition ;
  • frontières de modules ;
  • règles d'import ;
  • contrats publics ;
  • constructeurs ;
  • événements métier ;
  • logs structurés ;
  • traces ;
  • identifiants de corrélation ;
  • invariants nommés.

Ce ne sont pas des formes décoratives. Ce sont des prises pour le feedback.

Un vérificateur de types ne peut vérifier des types que si ces types encodent quelque chose de significatif. Une règle d'audit ne peut faire respecter des frontières que si ces frontières sont représentées dans le code. Une trace d'exécution ne peut expliquer une panne que si le système émet des événements utiles aux bons endroits.

L'explicite ne rend pas seulement le code plus facile à lire. Il le rend plus facile à vérifier.

Mais la surface n'est pas automatiquement un atout, et j'y reviendrai. Une surface liée à un vrai concept du système paie à chaque fois que le code change ; une surface liée à un détail interne accessoire ne donne à vos vérifications qu'une prise fragile.

Voilà pour l'affirmation générale. Regardons maintenant ce qu'elle change, boucle par boucle.

Première boucle : le feedback local

Le feedback local répond à la question la plus proche :

Ce que je viens de changer tient-il encore immédiatement ?

Cela inclut le formatage, le linting, la vérification de types, la compilation et les tests unitaires proches. Mais l'intéressant n'est pas que ces vérifications soient rapides. L'intéressant, c'est qu'elles deviennent bien plus fortes quand le code local est explicite.

Prenons une machine à états.

Si l'état d'une fonctionnalité est représenté par plusieurs booléens, le vérificateur de types ne voit presque rien :

TypeScript

type RecorderFlags = {
  isRecording: boolean;
  isSaving: boolean;
};

Cette représentation autorise des états qui ne devraient pas exister :

  • isRecording: true et isSaving: true en même temps ;
  • les deux à false, ce qui peut vouloir dire idle ou terminé — les drapeaux ne savent pas dire lequel.

Le modèle d'états existe, mais il est implicite. Il vit dans l'interprétation que le développeur fait des drapeaux, et la boucle de feedback ne peut pas vérifier grand-chose.

Maintenant, rendons l'état explicite :

TypeScript

type RecorderState =
  | { type: "idle" }
  | { type: "recording"; sessionId: string }
  | { type: "saving"; sessionId: string };

type RecorderEvent =
  | { type: "start-recording" }
  | { type: "segment-ready"; blob: Blob }
  | { type: "save" };

Le vérificateur de types voit maintenant une vraie structure. Certains états invalides ne sont plus représentables. La boucle de feedback est plus forte parce que le code lui a donné une meilleure surface. C'est le principe que Yaron Minsky a appelé making illegal states unrepresentable (rendre les états illégaux non représentables) — poussé un cran plus loin : un état que le système de types ne peut pas représenter est un état que votre feedback n'a jamais à traquer, parce que la vérification est la structure.

On peut aller un cran plus loin. Une union discriminée permet déjà au vérificateur de types de vérifier que vous traitez les états attendus — un switch avec une branche never cesse de compiler le jour où un nouvel état n'est pas géré. Le coup plus fort, c'est d'arrêter de traiter en pensée d'après-coup les événements sur lesquels vous n'agissez pas, et de donner à chaque paire (état, événement) une disposition explicite. C'est une matrice de disposition :

TypeScript

type Disposition = "Handled" | "Ignored" | "Stale" | "Rejected" | "Unexpected";

// Totale, pas Partial : chaque événement doit être classé dans chaque état.
type DispositionMatrix<S extends string, E extends string> = {
  readonly [state in S]: { readonly [event in E]: Disposition };
};

const recorderDisposition = {
  idle:      { "start-recording": "Handled",  "segment-ready": "Unexpected", save: "Rejected" },
  recording: { "start-recording": "Ignored",  "segment-ready": "Handled",    save: "Handled"  },
  saving:    { "start-recording": "Rejected", "segment-ready": "Stale",      save: "Ignored"  },
} as const satisfies DispositionMatrix<RecorderState["type"], RecorderEvent["type"]>;

Deux choses la rendent plus forte qu'une table de transitions. D'abord, elle est totale : le type mappé n'a pas de Partial, donc chaque événement doit être classé dans chaque état. Retirez une case et ça ne compile plus — « Property 'save' is missing » — il n'existe donc plus de signal non considéré. Une case vide ne peut plus vouloir dire en douce « invalide ici » ; vous devez préciser de quel genre d'invalide il s'agit. (Une disposition erronée, ou un événement qui n'existe pas, est rejeté de la même façon.)

Ensuite, la case n'enregistre pas où vous allez — elle enregistre ce que le signal signifie ici. Regardez segment-ready : Handled pendant recording, Stale pendant saving (un événement tardif d'une phase déjà dépassée), et Unexpected pendant idle (un signal qui devrait être impossible — une violation de protocole, pas un no-op). C'est l'attribution décrite plus haut, précalculée par le vérificateur de types. Quand quelque chose tourne mal, la disposition nomme déjà le genre : Unexpected réveille quelqu'un, Rejected est une erreur du client, Stale est bénin, Ignored est un no-op délibéré. Une table de transitions ne peut rien dire de tout cela ; elle ne connaît que les coups qu'elle autorise et reste muette sur tout le reste.

Trois états et trois événements tiennent dans neuf cases qu'on lit d'un coup d'œil. Les vrais protocoles en ont bien plus — des dizaines d'événements à travers de nombreux états — et c'est à cette échelle, où la matrice devient une véritable surface d'audit, que s'intéresse le prochain article. La règle ne change pas avec la taille : chaque case, remplie et classée.

Une mise en garde honnête, parce que c'est le genre de chose que cette série ne devrait pas escamoter : la matrice est une vue d'audit, pas le reducer lui-même. Les types prouvent que chaque case est remplie ; ils ne prouvent pas que le reducer se comporte réellement comme chaque case le prétend. Cette correspondance est une seconde garantie — la complétude vérifiée par le compilateur, l'accord vérifié par un test. Deux boucles, ce qui est précisément le sujet.

C'est le pont depuis l'article précédent : le code explicite donne au feedback local davantage de matière.

Deuxième boucle : le feedback structurel

Le feedback structurel pose une autre question :

Le code a-t-il encore la forme que le système est censé garder ?

C'est ici qu'interviennent les règles d'architecture, les contraintes d'import, les vérifications de dépendances, les conventions de couches et les fitness functions architecturales.

Mais là encore, ces boucles ne fonctionnent que si le système expose sa structure — et le schéma est le même à chaque fois : rendez le concept explicite et une règle peut le vérifier ; laissez-le implicite et il n'y a rien à inspecter.

Si les frontières sont explicites — domain/ ne doit pas importer infrastructure/, ui/ ne doit pas appeler directement les adaptateurs de base de données, les modules publics exposent des contrats plutôt que des détails internes — une règle d'import peut détecter une dérive de frontière. Si les contrats sont explicites — payloads parsés à la frontière, handlers validant l'entrée avant le domaine, DTO maintenus distincts des modèles internes — le feedback peut poser une vraie question système : des données non validées peuvent-elles entrer dans le cœur ? Ce n'est pas une règle de lint générique ; elle existe parce que le code a rendu ses points de validation visibles. Et si les responsabilités sont explicites — les composants affichent l'état mais ne possèdent pas les transitions métier, les services de domaine font respecter les règles du domaine, les adaptateurs réalisent les effets derrière des ports — le feedback peut attraper une dérive de responsabilité : de la logique métier qui s'infiltre dans les composants, de l'infrastructure importée dans le domaine, un état muté par plusieurs autorités, des effets de bord dans des fonctions censées être déterministes.

C'est ce qui sépare le feedback structurel du feedback local. Le feedback local dit ce code s'exécute. Le feedback structurel dit ce code est encore à sa place.

Troisième boucle : le feedback produit / proche de la production

Le feedback produit pose une troisième question :

Les chemins critiques tiennent-ils encore quand le système rencontre quelque chose de proche du réel ?

Cela inclut les tests d'intégration, des tests de bout en bout ciblés, des smoke tests, des vérifications en staging, et des scénarios délibérément dégradés : latence, dépendances indisponibles, entrées rejetées, pannes partielles.

Comme les autres, cette boucle n'est lisible qu'à hauteur des signaux que le système émet. Un test proche de la production qui échoue sans signal d'exécution vous donne un symptôme — quelque chose a cassé — mais pas ce que le système faisait, quel état il avait atteint, quelle entrée il a rejetée, ni quelle dépendance a lâché. La version plus forte rattache l'observabilité à des concepts système : un événement métier au démarrage d'un enregistrement, une transition loguée de recording vers saving, des entrées rejetées portant des raisons structurées, des appels externes portant des identifiants de corrélation, des handlers critiques émettant du contexte métier plutôt que de seules erreurs techniques. C'est là que les pratiques SRE et des standards comme OpenTelemetry comptent — ils rendent le comportement à l'exécution lisible, et d'autant plus lisible que l'instrumentation est rattachée à des concepts explicites.

Le but n'est pas de savoir *qu'*un chemin a échoué, mais de lire sa trajectoire :

Qu'est-ce qui est entré dans le système ?
Quelle frontière l'a accepté ou rejeté ?
Quelle transition d'état a eu lieu ?
Quelle dépendance a été appelée ?
Quel invariant a tenu ou a cédé ?
Quel effet visible par l'utilisateur a suivi ?

Une boucle produit est forte exactement quand elle peut répondre à cela — ce qu'elle ne peut faire que si le système émet les signaux permettant d'y répondre.

Les trois boucles ne sont pas interchangeables

Dès qu'on comprend le feedback comme de la visibilité, les boucles sont clairement non fongibles.

Plus de feedback local ne peut pas remplacer un feedback structurel manquant. Il peut prouver que des unités individuelles se comportent correctement, mais il ne peut pas prouver que les frontières sont respectées si les frontières ne sont pas vérifiées.

Plus de feedback structurel ne peut pas remplacer le feedback produit. Il peut prouver que le système garde la forme prévue, mais il ne peut pas prouver que les chemins critiques tiennent sous une latence réelle, un comportement de dépendance réel, ou des séquences d'utilisateur réelles.

Plus de feedback produit ne peut pas remplacer le feedback local ou structurel. Il peut révéler une panne, mais sans surfaces locales et structurelles il trouve souvent le symptôme plus tard, plus loin de la cause.

Un feedback mal placé augmente le coût de correction parce que le symptôme et la cause apparaissent dans des boucles différentes.

Un test produit échoue, mais la cause est un modèle d'états implicite. Une revue détecte une dérive d'architecture, mais la cause est une frontière non représentée. Une erreur d'exécution apparaît, mais la cause est un contrat de validation manquant.

Plus le décalage est découvert tard, plus la correction devient coûteuse.

La solution n'est pas plus de vérifications partout. C'est une meilleure visibilité à chaque niveau.

BoucleCe qu'elle révèleCe que « plus » d'une autre boucle ne peut remplacerCe que le code explicite lui donne
Localeerreurs immédiates, trous d'exhaustivité, états invalidesplus de tests E2E ne rendront pas exhaustifs des états implicitestypes, unions, machines à états, fonctions pures
Structurelledérive de frontière, dérive de responsabilité, dérive de dépendancesplus de tests unitaires ne prouveront pas la forme d'architecturemodules, couches, contrats, règles d'import, propriété
Produitpannes à l'exécution, chemins dégradés, observabilité manquanteplus d'audits ne prouveront pas le comportement réel en conditions réellesévénements, traces, logs, identifiants de corrélation, transitions d'état
Revue humainequalité du modèle, qualité de l'abstraction, compromisplus d'automatisation ne décidera pas si le modèle est justeconception lisible, intention explicite, responsabilités claires

Ce tableau est le cœur de l'approche.

Non parce qu'il liste des vérifications, mais parce qu'il relie trois choses :

  1. le type de déviation qu'on veut voir ;
  2. la boucle qui peut la voir ;
  3. la structure explicite qui la rend visible.

Explicite, mais pas maximal

Une mise en garde, car l'argument est facile à pousser trop loin. Davantage de formes explicites ne signifie pas automatiquement un feedback plus fort. L'article précédent faisait déjà le parallèle — plus de code ne signifie pas automatiquement plus de robustesse — et cela vaut ici aussi.

La structure explicite n'aide le feedback que lorsqu'elle est un vrai concept du système : une frontière, un modèle d'états, un invariant, un contrat, une responsabilité. Rendez ceux-là explicites et vos vérifications s'accrochent à quelque chose censé rester stable. Liez plutôt une vérification à un détail interne accessoire — la forme exacte d'une représentation que vous voulez justement continuer à faire évoluer — et vous n'avez pas acheté de la visibilité, vous avez acheté de la fragilité. La vérification casse désormais sur des refactos qui n'ont rien changé d'important, et les gens apprennent à la désactiver.

La matrice de disposition ci-dessus montre les deux faces. Elle est puissante quand la disposition du protocole est un vrai concept du domaine que le système doit préserver — et forcer chaque case est exactement ce qui empêche un signal d'être oublié en silence. Elle devient un fardeau dès qu'elle arrime votre feedback à un arrangement interne que vous voulez continuer à refactorer, ou qu'elle enfle en cases que plus personne ne tient honnêtes. La discipline du deuxième article s'applique sans changement : rendez explicites — et vérifiez — les formes qui portent le système, pas celles qui ne font qu'exister. La surface de vérification ne vaut la peine d'être créée que là où elle suit quelque chose que le système doit maintenir vrai.

Les boucles automatisées ne remplacent pas la revue humaine

Ces boucles ne remplacent pas le jugement humain.

Elles le protègent.

Une revue humaine ne devrait pas dépenser l'essentiel de son énergie sur le formatage, les imports interdits, les erreurs de typage évidentes, l'exhaustivité manquante ou les violations structurelles qu'une machine peut détecter.

La machine devrait rapporter ce qu'elle peut rapporter.

L'humain devrait se concentrer sur ce que la machine ne peut pas décider seule :

  • Le modèle est-il juste ?
  • La frontière est-elle au bon endroit ?
  • Cette abstraction aide-t-elle ?
  • Ce compromis est-il acceptable ?
  • Le comportement correspond-il au besoin réel ?
  • Le système reste-t-il compréhensible ?

L'automatisation est la plus forte quand le code expose des formes explicites.

Le jugement humain est le plus fort quand l'automatisation a déjà déblayé ce qui ne demande pas de jugement.

À l'ère des agents, le feedback explicite est de la coordination

Cela devient encore plus important avec les agents de code.

Un agent peut produire du code vite. Il peut satisfaire une instruction locale. Il peut faire passer des tests. Il peut aussi mal lire une convention, contourner une frontière, dupliquer de la logique, introduire un état implicite, ou placer une responsabilité dans la mauvaise couche.

L'agent n'a pas besoin d'un feedback vague. Il a besoin d'un feedback précis.

Pas seulement :

C'est faux.

Mais :

Cet événement n'est pas géré dans cet état.
Ce module franchit une frontière interdite.
Ce handler accepte une entrée non validée.
Ce composant possède de la logique métier.
Ce chemin critique échoue sans assez de contexte d'exécution.

Un feedback explicite donne à l'agent une meilleure cible de correction.

C'est pourquoi le code explicite et les boucles de feedback se renforcent mutuellement.

Le code explicite donne aux boucles davantage à observer. Des boucles plus fortes donnent aux humains et aux agents des signaux plus nets. Des signaux plus nets rendent plus facile la préservation du système quand on le change.

Le feedback devient une couche de coordination entre :

  • l'humain qui définit le système ;
  • l'agent qui produit les changements ;
  • le code qui encode les règles ;
  • l'exécution qui rapporte ce qui s'est passé.

Sans structure explicite, l'agent est guidé surtout par les tests, les erreurs et les instructions textuelles.

Avec une structure explicite, il est aussi guidé par les types, les frontières, les contrats, les transitions, les invariants et les signaux d'exécution.

C'est un autre niveau de contrôle.

Conclusion

Le but de boucles de feedback étagées n'est pas d'ajouter plus de vérifications.

C'est de rendre le système plus visible à chaque niveau où il peut dériver.

Le feedback local révèle si le changement immédiat tient encore. Le feedback structurel révèle si le code a encore la forme du système. Le feedback produit révèle si les chemins critiques tiennent quand ils rencontrent des conditions proches du réel. La revue humaine juge si le modèle, l'abstraction et les compromis sont justes.

Mais aucune de ces boucles n'est forte à elle seule.

Elles deviennent fortes quand le code leur donne des structures explicites à observer.

C'est pour cela que les boucles de feedback ont leur place dans cette série. Le premier article soutenait que le code est un système. Le deuxième soutenait que les concepts du système doivent être rendus explicites. Celui-ci ajoute l'étape suivante : une fois le système explicite, on peut construire des boucles de feedback qui vérifient que ces formes explicites continuent de tenir.

Une boucle de feedback n'est pas qu'une vérification autour du code. C'est une manière de lire ce que le code a rendu visible.

La détection vous dit que le système a bougé. L'attribution vous dit quelle forme a bougé. Et seul un feedback capable d'attribuer permet à un système de changer sans perdre sa forme.

Pour aller plus loin

Ces travaux sont antérieurs à cet article et vont plus loin que lui. Je suis arrivé à beaucoup de ces idées par la pratique plutôt qu'en les lisant — et je n'ai mis un nom sur plusieurs d'entre elles qu'en écrivant ce texte. Raison de plus pour vous renvoyer vers ceux qui les ont vraiment développées, au lieu de faire comme si la réflexion était mienne. Là où ils contredisent l'article, ils méritent plus de confiance que moi.

  • Yaron Minsky — Effective ML / « make illegal states unrepresentable » : nomme l'idée même à laquelle arrive la section sur le feedback local.
  • John Hughes — QuickCheck et la tradition du property-based testing : un feedback qui détecte sans aucune structure interne explicite (le contre-exemple auquel cet article doit répondre).
  • Dan North — sur le fait de tester le comportement plutôt que l'implémentation : l'argument pour ne pas coupler les vérifications à la forme interne.
  • Neal Ford, Rebecca Parsons, Patrick Kua — Building Evolutionary Architectures : la source du terme fitness functions employé dans la boucle structurelle.
  • Charity Majors, Liz Fong-Jones, George Miranda — sur l'observabilité moderne : le versant exécution de la boucle produit.

Une remarque après lecture ?

Si vous souhaitez envoyer un mot au sujet de cet article, vous pouvez écrire ici. Je partage ici parce que le sujet m’intéresse et que je veux apprendre des autres. Merci pour vos retours, surtout lorsqu’ils sont formulés avec soin.