AnnonceNouveautés4 lectures
Le garde publié hier écartait 98 % de la campagne
LeTock.fréditeur 10 pts ·
Publié le 4 octobre 2026.
Une taille d’affichage faite pour des nombres, remplie de phrases.
« Illisible, incompréhensible », dit l’exploitant devant l’écran refait. Trois défauts derrière ces deux mots, et aucun n’était une question de goût. « sur un seul disque » et « restent dans un journal » étaient rendus en 3,5 rem, comme « 237 min ». Chaque mot était correct et l’ensemble se déchiffrait : un nombre se lit d’un coup à cette taille, une phrase ligne par ligne. La distinction se fait désormais sur la valeur elle-même — pas sur un réglage que l’appelant devrait penser à poser, car celui-là s’oublie. Onze étages de décor avant la première information : fil d’Ariane, titre, accroche, ligne de charge, encadré des sept chapitres, numéro, titre de chapitre, explication du chapitre, libellé de tuile, valeur, attendu. Le sommaire est parti — sept liens vers sept titres écrits trois centimètres plus bas, utiles sur une page de onze mille pixels, devenus un étage de plus une fois la hauteur divisée. Et les explications de chapitre parlaient de l’écran, pas de la plateforme : « le reste de l’écran explique ; ce chapitre demande » — du commentaire sur soi-même, posé entre le lecteur et l’information. Un titre de chapitre qui a besoin d’un paragraphe est un titre mal choisi : on le change plutôt que de l’excuser. Mesure : la première information passe de 440 px à 260 px du haut. Et un chiffre sans attendu n’informe pas — « 237 min » ne dit rien tant qu’on ignore qu’on vise une minute. Chaque tuile porte le sien, à côté de la valeur : c’est la comparaison qui informe, et deux lignes séparées la font faire de tête. La valeur nomme le défaut plutôt que l’état : « sur un seul disque » se comprend seul, « aucune » oblige à relire le libellé.
J’avais livré une mise en colonnes, pas la maquette choisie.
Trois architectures avaient été construites et rendues côte à côte ; le mur de tuiles a été choisi. Ce qui a été livré ensuite n’était pas cette maquette : c’était l’ancienne page répartie sur douze colonnes — mêmes cartes, même prose, même apparence, deux par rangée au lieu d’une. La maquette, elle, était une page neuve : des tuiles colorées, des chiffres qu’on lit de loin, et rien d’autre. L’exploitant l’a dit en trois mots — « ça ne ressemble pas du tout à ton image » — et il avait raison. Une tuile dit une chose : un libellé court, une valeur, une couleur qui dit l’état. Le premier chapitre est refait ainsi : la carte « Ce qui tourne », qui entassait six lignes d’état et deux pavés d’explication, devient quatre tuiles (211 min, 2, 0, 107) et deux tuiles d’alerte dont l’explication tient sous une ligne repliable. La couleur ne dit jamais la catégorie, seulement l’état : une rangée doit se lire comme une palette d’alarmes, pas comme un arc-en-ciel décoratif, et la plupart des tuiles restent donc neutres. La leçon n’est pas sur le CSS : j’ai pris une maquette pour une direction esthétique alors qu’elle proposait une structure. Reformuler la page dans la grille de la maquette n’est pas la refaire.
L’écran d’exploitation n’est plus une pile, c’est un mur.
Il empilait vingt cartes sur onze mille pixels — neuf écrans sur un bureau, quatorze sur un téléphone. On lui avait ajouté des chapitres, un sommaire, des rayons plus doux, de plus gros chiffres : rien de tout ça ne répare la forme, parce qu’une pile reste une pile. Trois architectures ont donc été construites pour de vrai et rendues côte à côte sur la même donnée — un mur de tuiles, des bandes pleine largeur, trois colonnes parallèles — au lieu d’être décrites. Le mur a été choisi sur pièces. Douze colonnes ; une tuile en occupe trois, quatre, six, huit ou douze selon ce qu’elle porte : un nombre tient dans trois, un tableau en demande douze. L’écran précédent donnait la même largeur à tout, donc la même importance à tout. Les largeurs sont posées pour que chaque rangée fasse exactement douze : une tuile de six suivie d’une de douze laissait six colonnes vides, et la grille se lisait comme une pile mal rangée. Les tuiles d’une même rangée s’étirent à la même hauteur, sinon une tuile courte à côté d’une longue creuse un trou. Résultat mesuré : 11 276 → 8 397 px, à contenu égal. Et une redite de plus, vue à l’écran : quand personne n’attend de réponse, l’accroche le disait et l’état vide le répétait mot pour mot juste en dessous. Et la prose se replie : huit paragraphes d’explication deviennent huit lignes cliquables, ramenant l’écran à 8 155 px. Deux ont été laissés visibles parce qu’ils portent un fait et non une explication — « 99 % sont arrivés, 1 % perdus » et le total d’événements : replier un fait sous un triangle, c’est le cacher ; replier une explication, c’est la ranger. Chaque intitulé dit ce qu’on trouve dessous — « Ce qu’un refus de transport veut dire », « Comment lire la charge » — parce qu’un repli nommé « En savoir plus » n’est jamais ouvert.
Un taux d’ouverture de 52 % s’affichait en rouge d’alarme.
Trois défauts de graphiques, invisibles tant que les données de démonstration étaient vides — quatre chapitres sur sept n’avaient rien à dessiner, et on ne juge pas un graphique vide. La couleur disait le contraire du chiffre : le palier « moyen » d’une jauge portait le cramoisi de la marque, à un cheveu du rouge d’échec. C’est exactement le défaut que ce composant décrit déjà pour les taux d’échec, laissé dans le palier du milieu : une couleur qui contredit ce qu’elle accompagne désapprend à lire le rouge, et le rouge est ce qu’on veut qu’on lise. L’ambre dit « regarde », le rouge dit « agis ». Une jauge à 0 % dessinait un point : le trait porte un bout arrondi, et à longueur nulle les deux moitiés se rejoignent — ça ressemblait à un dessin cassé, alors que zéro plainte est la meilleure nouvelle que cette jauge puisse donner. Et trois tableaux portaient une classe qui n’existe nulle part dans la feuille : colonnes collées, aucune bordure, et des zones qui défilent sans être atteignables au clavier. Côté mise en page, quatre techniques, chacune pour un défaut mesuré sur la page rendue — 10 500 px de haut sur un bureau, dix-sept écrans sur un téléphone : content-visibility pour ne pas mettre en page ce qu’on ne regarde pas, subgrid pour que les lignes des tuiles s’alignent entre cartes voisines, des en-têtes de chapitre collants parce qu’après trois écrans plus rien ne dit où l’on est, et un sommaire qui suit la lecture par IntersectionObserver — choisi contre un écouteur de défilement, qui mesurerait sur le fil principal des dizaines de fois par seconde pendant qu’on défile. La feuille employait déjà color-mix, text-wrap et @container : rien de tout cela n’est refait.
Je redessinais un écran que je ne pouvais pas voir.
Deux demandes de suite — « rends la page plus belle », puis « elle n’est pas belle du tout ». Entre les deux, j’avais réorganisé un écran de deux mille lignes en lisant le code et la feuille de style, sans jamais le voir : c’est l’exploitant qui jugeait à ma place, à chaque tour. Un écran se juge à l’œil. Le script scripts/voir.mjs rend désormais n’importe quelle page dans un vrai Chromium, à deux largeurs, et en sort une image. Il a trouvé en dix minutes ce que trois heures de lecture n’avaient pas vu. Deux titres en double : quatre blocs affichaient leur titre deux fois — celui du bloc créé le matin même en coupant un bloc de 636 lignes, plus l’intertitre d’origine resté dessous. Des mots collés : « Relance des paniers3 raté(s) », « officiel@letock.invalidvient de s’inscrire » — JSX supprime le saut de ligne entre deux éléments écrits l’un sous l’autre, il n’y avait littéralement aucun espace ; corrigé dans la mise en page, pas par une espace dans le texte qui se reperdrait au prochain reformatage. Un tableau sans aucun style : j’avais écrit className="tableau", une classe qui n’existe nulle part dans la feuille — colonnes collées, aucune bordure, et une zone qui défile sans être atteignable au clavier ; il passe par le composant prévu, qui porte aussi son nom accessible. Et le plus visible : les encarts d’explication portaient le même rouge que les tuiles d’alerte, en occupant trois fois leur place — l’œil ne distinguait plus ce qui alerte de ce qui explique l’alerte. Ils gardent le filet rouge et rendent leur fond : la tuile crie, l’explication parle. Le sommaire, enfin, était une grille à cinq colonnes pour sept chapitres, avec deux trous béants — c’est une rangée qui se replie, sans trou possible. Aucun test ne pouvait attraper tout ça : un espace manquant répond 200, un titre en double aussi.
Le bloc qui dit « regarde ici en premier » était quatorzième sur dix-huit.
L’écran d’exploitation portait vingt blocs, tous au même niveau, donc sans ordre lisible. Le pire n’était pas la longueur : le bloc qui porte la phrase « si l’une de ces lignes est rouge, c’est là qu’il faut regarder en premier » arrivait quatorzième, derrière six cents lignes de graphiques d’audience ; « en attente de nous » était douzième. L’ordre va désormais du plus urgent au plus explicatif, en sept chapitres, avec un sommaire en tête — on choisit, au lieu de subir l’ordre. Un bloc en cachait cinq : « L’audience de toute la plateforme » faisait 636 lignes et contenait en réalité cinq sujets sous des intertitres, dont tout le courrier. Séparés, le plus gros tombe à 282 lignes et chacun porte son titre et son accroche ; c’est le gain principal, et il était invisible tant qu’on ne lisait pas le code. Chaque chapitre porte la question à laquelle il répond, pas seulement son sujet : « La machine » ne dit pas ce qu’on vient y chercher, « mesurée à chaque passage du worker, et non supposée » le dit. C’est la différence entre un écran qu’on parcourt et un écran qu’on consulte. Côté style, un chapitre n’a ni fond ni bordure — c’est une respiration entre deux séries de cartes, pas une carte de plus, et lui en donner un le mettrait en concurrence avec ce qu’il annonce. Beaucoup d’air au-dessus, peu en dessous : il appartient à ce qui le suit. Et il réutilise --titre-section, un niveau qui existait déjà — en inventer un aurait fait quatre tailles de titre sur le même écran, c’est-à-dire aucune hiérarchie. Les garde-fous de la feuille de style ont eu raison trois fois : une marge hors échelle, une huitième largeur de rupture que j’inventais, et un interligne hors jeton.
Répondre à notre prospection ne protégeait de rien.
La liste de suppression ne contenait que deux choses : les rebonds durs (374) et les désabonnements explicites (13). Répondre n’y entrait pas. Un gérant d’agence web reçoit notre mesure sur le domaine d’un de ses clients et répond le 02/10 : « Rien compris. Pourriez-vous traduire en bon français svp ? ». Le 04/10 à 06 h 53, la campagne lui écrit de nouveau — cette fois pour son propre domaine, qui était un prospect séparé. Aucun doublon dans la base : deux domaines distincts, un seul humain derrière. La veille, un autre destinataire avait écrit « De quoi tu te mêle » puis, une minute plus tard, « La prochaine c’est plainte à la gendarmerie » ; nous l’avons retiré à la main, et c’est exactement le geste qu’il ne faut pas avoir à faire à la main. Désormais, toute adresse humaine qui nous écrit sort du courrier froid au tour suivant. On prend l’adresse telle qu’elle a écrit, et non le domaine du prospect : le rapprochement par domaine sert à compter les réponses, ici on protège quelqu’un — et c’est précisément celui qui répond depuis sa boîte personnelle qui a menacé de porter plainte. Ce que ça ne coupe pas : le motif s’appelle « réponse » et se comporte comme un désabonnement — il arrête ce qui porte un lien de désabonnement, donc le froid, et laisse passer les confirmations de commande et les liens de connexion. Un motif à lui plutôt que « désabonnement », parce que personne ne s’est désabonné et que l’écran de campagne compte les désabonnements ; et pas « manuel », qui bloque tout — un client qui pose une question se verrait couper ses propres messages. Et la protection a failli avaler les excuses qu’elle rendait nécessaires : la mise en file porte un lien de désabonnement par défaut — le bon réglage pour du courrier de masse — et le script qui sert à écrire à quelqu’un à la main ne le désactivait pas. Il aurait donc cessé de pouvoir écrire à quiconque nous a répondu, c’est-à-dire aux seules personnes à qui l’on a quelque chose à répondre. Trouvé en voulant envoyer des excuses à quelqu’un qui venait d’être protégé. La règle était pourtant déjà écrite dans la boîte : « une réponse personnelle n’est pas une campagne ».
Et une heure plus tard, ce taux était gonflé neuf fois.
En lisant les messages un par un après avoir branché le compteur : neuf prospects marqués « répondu », une seule réponse humaine parmi eux. Les huit autres étaient des accusés de réception et des filtres anti-robots — « FILTRE ANTI-ROBOTS », « ce message automatique accuse réception » — dont l’expéditeur ne pose aucun des en-têtes prévus par la RFC 3834. Je venais de corriger un chiffre qui ne pouvait pas bouger ; je l’avais remplacé par un chiffre faux. Le délai ne sépare rien, et c’est mesuré : 29 secondes, 7, 9 et 10 minutes pour certains, mais aussi 5 h, 7 h et 8 h pour des répondeurs mis en file — pendant que la seule vraie réponse est arrivée à 48 h. L’idée était séduisante et fausse ; elle est écrite dans le code pour qu’on ne la retente pas. Et on n’a pas élargi le drapeau « automatique », parce que le risque est inversé selon l’usage : pour l’alerte « qui attend une réponse », prendre un humain pour une machine coûte un client — c’est exactement ce qui a fait disparaître deux messages d’un destinataire furieux la veille ; pour le taux, prendre une machine pour un humain gonfle le chiffre. Une seule définition ne peut pas servir les deux. Le taux lit donc, en dernier recours, les formules par lesquelles un message se décrit lui-même comme automatique — ce n’est pas deviner le ton, c’est lire une déclaration dans le corps au lieu des en-têtes. Éprouvé sur le courrier réellement reçu : les neuf machines attrapées, les neuf humains épargnés, zéro faux positif. Et le passage défait sa propre pollution : les prospects marqués à tort reviennent à « écrit » tout seuls, parce qu’un correctif qui exige une réparation à la main est un correctif à moitié fait.
Le taux de réponse de la campagne ne pouvait pas bouger.
Audit demandé en une phrase — « vérifie que chaque nombre est vrai » — et quatre défauts trouvés sur l’écran d’exploitation. Deux chiffres étaient morts. Le taux de réponse compte les prospects à l’état repondu ; cette chaîne apparaissait une seule fois dans tout le produit, dans la requête qui la lit. Rien ne l’écrivait, alors que la table porte repondu_le depuis le premier jour. L’écran affirmait donc « 8 581 messages écrits, assez de volume pour juger, et aucune réponse nulle part » — une phrase produite par le code, qui a l’air d’un constat, et qui serait restée vraie quel que soit le nombre de réponses. Au même moment, neuf prospects avaient répondu. Même défaut pour les désabonnés. Un taux qui ne peut pas bouger est pire qu’un taux absent : on le lit, on en conclut quelque chose, et on décide dessus. Le rapprochement se fait désormais sur l’enveloppe — un « From: » se forge, un « MAIL FROM » se constate — avec le drapeau « automatique » pour écarter absences et avis de non-remise. Sa limite est écrite plutôt que taire : quelqu’un qui répond depuis une autre adresse que son domaine n’est pas rapproché. Mesuré : deux des onze réponses réelles sont dans ce cas. Le faire demanderait une devinette sur le nom, et un taux gonflé par des devinettes ne vaut pas mieux qu’un taux mort — mieux vaut un plancher honnête.
L’écran annonçait 88,9 % de remise. Le vrai chiffre est 77,4 %.
Le taux de remise compte les remises qui ont reçu un verdict — accepté, rebond, refus — et écarte volontairement les différés, parce qu’un différé n’est pas encore une réponse. C’est défendable, et ça laissait un trou : un message différé puis abandonné sort du dénominateur sans jamais entamer le taux. Mesure du jour : 2 080 remises différées écartées du total, et 3 346 messages abandonnés. Sur 16 774 messages déposés en trente jours, 77,4 % sont arrivés et 19,9 % sont perdus. Onze points d’écart, toujours dans le sens rassurant — le pire genre de chiffre faux, celui qui ne fait pas douter. Les deux comptes restent côte à côte, parce qu’ils répondent à deux questions : « que disent les serveurs d’en face » juge la réputation, « qu’est devenu ce que j’ai déposé » juge le service rendu. C’est la seconde que le client se pose, et elle n’était nulle part. Deux autres chiffres corrigés au passage. « 0 plainte » n’est pas une réussite : une plainte ne peut entrer que par une boucle de retour chez Yahoo ou Microsoft, et aucune n’est enregistrée depuis qu’on remet soi-même — la jauge dit maintenant « non mesuré ». Et « Comptes : 12 au total, 13 récents » — un sous-ensemble plus grand que son ensemble, parce que le total écartait les comptes anonymisés après suppression et que le récent ne les écartait pas.
Le garde publié hier écartait 98 % de la campagne, pas 22 %.
Hier, une mesure ouvrait une prise vers le serveur de courrier d’un prospect avant de lui écrire, pour ne pas s’adresser à un domaine dont plus rien n’écoute. L’intention était juste et l’annonce disait 22 % de boîtes mortes écartées. Mesure du jour, sur quarante prospects réels : trente-neuf déclarés injoignables, dont trente-six derrière des serveurs OVH — les mêmes qui avaient accepté 328 de nos messages dans les vingt-quatre heures précédentes. Le garde ne retirait pas les boîtes mortes de la campagne : il en retirait presque tout le monde. La cause tient en une phrase, et elle vaut au-delà d’ici : une prise TCP nue répond à une autre question que celle qu’on pose. Vérifié à la main : une connexion seule, avec vingt-cinq secondes de patience, n’obtient rien de mx0.mail.ovh.net ni de mx1.ovh.net, pendant que Google répond en 12 ms et que la plateforme Exchange du même hébergeur répond en 50 ms. Un gros hébergeur qui nous serre la cadence refuse la connexion d’essai et continue de prendre notre courrier ; un domaine mort, lui, ne fait ni l’un ni l’autre. Et la réponse était déjà dans le produit : nous remettons du courrier toute la journée et nous notons ce que chaque serveur en dit. « Puis-je écrire là-bas ? » se lit donc dans nos propres remises — un serveur qui nous a rendu un 250 est joignable, et aucune sonde ne le dira mieux que lui. La liste des serveurs qui nous acceptent est lue une fois par passage (2 897 noms ; il y a beaucoup moins d’hébergeurs que de domaines), et on ne frappe plus à une porte qui nous a déjà ouvert. Résultat mesuré sur les mêmes quarante prospects : 98 % → 8 % d’écartés, trente-six passant sans aucune connexion d’essai — donc trente-six connexions de moins par lot vers l’hébergeur qui nous serrait. Le garde reste entier pour un serveur qu’on n’a jamais touché. Troisième fois cette semaine qu’une réponse existait déjà dans le produit, après le drapeau « automatique » et l’état « à répondre ». Et une leçon de plus : j’avais ajouté hier un comptage par serveur « pour que ça se voie ». Ça se voyait — dans une ligne de journal que personne ne lit. Rendre un défaut visible n’est pas le corriger.
Et un test a corrigé le correctif, encore.
J’attendais qu’un domaine sans MX ne désigne aucun serveur. C’est faux : la RFC 5321 demande de retomber sur son enregistrement A, et beaucoup de petits domaines sont dans ce cas. Le test a dit non, et il avait raison. Le repli profite désormais de la même mémoire : un petit domaine sans MX qui nous a accepté du courrier hier n’est plus sondé ni écarté.
Un détail vous a gêné, ou vous a coûté du temps ? Répondez ici plutôt
que par courrier : la réponse servira aussi aux suivants.