docs(AGENTS): le miroir — toutes les prémisses vraies, la conclusion fausse

Le bloc voisin traite la conclusion juste posée sur un raisonnement faux. Celui-ci
est l'inverse, et il se lit encore moins bien : chaque prémisse vérifiable et
vraie, conclusion fausse quand même.

Le verrou de logEvent() existe, l'I/O SQLite existe, elle est bien dans le thread
appelant. Et pourtant la conclusion tombe : qCInfo ne passe pas par logEvent(), et
sur la cible le moteur de journal est Influx, qui empile et poste en asynchrone.
Le chemin coûteux existe et n'est jamais emprunté par ce qui était accusé de
l'emprunter.

RÈGLE : un chemin coûteux ne coûte que s'il est PARCOURU. La lecture établit le
mécanisme, jamais la conséquence ; passer de l'un à l'autre demande la fréquence,
et la fréquence se mesure. 2,1 ms par cycle de 60 s, soit 0,0035 %.

ET LA MESURE AUSSI PEUT PORTER À CÔTÉ. Le premier proxy, en Python, donnait 11 µs
par ligne ; la vraie valeur est 70. L'écart n'est pas du bruit : le proxy mesurait
l'écriture alors que le coût est dans le formatage — deux segments du même chemin,
et il tenait le mauvais. Une mesure ne vaut que si elle couvre le chemin entier,
dans les conditions réelles : banc Qt, vraie bibliothèque, vrai matériel.

Le bon résidu quand une piste tombe : le mécanisme reste documenté avec son
chiffre. Le jour où quelqu'un branchera logEvent() sur un signal fréquent, la
mesure d'aujourd'hui dira à quoi comparer. Une hypothèse écartée par la mesure
laisse une borne derrière elle ; une hypothèse jamais posée ne laisse rien.
This commit is contained in:
Patrick Schurig 2026-09-05 13:44:03 +02:00
parent 85ba2a5d3f
commit d08c82aabf

View File

@ -1017,6 +1017,35 @@ aucune, la décision est une intention, et elle se périmera à la vitesse du co
> raison, la raison mérite son propre contrôle. Un test qui vérifie la conclusion ne vérifie pas
> le raisonnement — et le raisonnement est ce sur quoi le lot SUIVANT s'appuiera.
> ### Le MIROIR : toutes les prémisses vraies, la conclusion fausse (2026-09-05)
>
> Le bloc ci-dessus traite la conclusion juste posée sur un raisonnement faux. Voici l'inverse, et
> il se lit encore moins bien : **chaque prémisse était vérifiable et vraie, et la conclusion était
> fausse quand même.**
>
> Cas d'école. « `logEvent()` prend un verrou et fait une I/O SQLite dans le thread qui écrit, donc
> chaque trace vole du temps à la boucle d'arbitrage. » Le verrou existe. L'I/O existe. Elle est
> bien dans le thread appelant. **Et la conclusion est fausse** : `qCInfo` ne passe pas par
> `logEvent()` — il va au gestionnaire de messages — et sur la cible le moteur de journal est
> Influx, qui empile et poste en asynchrone. Le chemin coûteux existe et **n'est jamais emprunté**
> par ce qui était accusé de l'emprunter.
>
> **La règle : un chemin coûteux dans le code ne coûte que s'il est PARCOURU.** La lecture établit
> le mécanisme ; elle n'établit jamais la conséquence. Passer de l'un à l'autre demande la
> **fréquence**, et la fréquence ne se lit pas — elle se mesure. Chiffré ici : 2,1 ms par cycle de
> 60 s, soit 0,0035 %.
>
> **Et la mesure aussi peut porter à côté.** Une première estimation en Python donnait 11 µs par
> ligne ; la vraie est 70. L'écart n'est pas du bruit : le proxy mesurait **l'écriture**, alors que
> le coût est dans le **formatage** — deux segments du même chemin, et le proxy en tenait le
> mauvais. Une mesure ne vaut que si elle couvre le chemin ENTIER, dans les conditions réelles.
> Ici il a fallu un banc en Qt, lié à la vraie bibliothèque, sur le vrai matériel.
>
> **Le bon résidu, quand une piste tombe** : le mécanisme reste documenté, avec son chiffre. Le
> jour où quelqu'un branchera `logEvent()` sur un signal fréquent, la mesure d'aujourd'hui dira à
> quoi comparer. Une hypothèse écartée par la mesure vaut mieux qu'une hypothèse jamais posée —
> elle laisse une borne derrière elle.
> ### Quand un contrôle attrape quatre fois la même erreur, c'est le GESTE qui est piégeux
>
> Le piège d'insertion Doxygen — un bloc glissé **entre un commentaire et sa déclaration**, si