docs: le critère de tri de l'étape 4, écrit AVANT les données

CRITÈRE DE TRI (DESIGN_COMMANDE_PERDUE.md §6), daté et poussé avant l'ouverture de
la fenêtre d'observation. Un critère rédigé après coup se plie aux résultats sans
jamais mentir, et sans qu'on puisse le prouver. S'il doit changer, ce sera un
commit visible avec sa raison.

Deux conditions, toutes deux nécessaires : `measurement.source` != `none`, ET le
compteur doit avoir VARIÉ sur la fenêtre. Un compteur d'écart-type nul n'est pas
un compteur, c'est une constante déguisée, et tout écart mesuré contre lui est un
artefact.

PAS de tri par nom de charge. Écarter chauffe-eau et pac-terrain nommément serait
fragile deux fois : ça se périme au premier renommage, et ça n'attrape pas la
troisième charge à compteur fixe qu'on ajoutera sans y penser. Le critère porte sur
une propriété observable de la donnée.

LES FAUX POSITIFS DE LA V2C sont d'une autre nature, et il faut les séparer avant
de compter. Elle a un vrai compteur, donc elle passe le critère — mais chaque perte
de lien produit une divergence qui n'est pas une commande perdue : c'est une mesure
absente. « Elle n'obéit pas » et « on ne sait pas si elle obéit » sont deux
affirmations que l'écart seul confond.

C'est la distinction `none` contre l'absence, appliquée à un écart. Et le pire cas
est documenté : à la perte du lien la V2C publie currentPower = 0 (LM-1012-d), donc
le zéro est PUBLIÉ, pas absent, et rien dans l'objet `command` ne le distingue d'un
zéro réel. Il produit la divergence maximale — le faux positif qui ressemble trait
pour trait au cas cherché. Conséquence portée au lot : `command` devrait dire que
son observedW n'est pas fiable, comme progress.regime le fait pour l'avancement.

Le compte des écartés sera publié aussi : un tri dont on ne dit pas ce qu'il a jeté
n'est pas un tri, c'est une sélection.

CINQUIÈME FORME D'HOMOGÉNÉITÉ DU BANC (AGENTS.md + INVENTAIRE_MOCK.md), et elle
inverse le mécanisme. Les quatre précédentes MASQUENT un cas ; celle-ci en FABRIQUE
un faux. Un cas masqué se signale par un test qui ne mord pas ; un cas fabriqué se
signale par des données qui rassurent.

14 épisodes en 24 h, de quoi croire le phénomène fréquent et dimensionner un lot
dessus. L'instrument fonctionne, la donnée est réelle, le compte est juste — seule
la question à laquelle ces nombres répondent n'est pas celle qu'on croyait poser,
et un nombre n'annonce jamais de quelle question il est la réponse.

Manque noté au mock : aucun compteur dont la valeur SUIVE la commande de la charge
qu'il mesure. Tant que c'est le cas, aucun test ne peut exercer une charge qui
obéit, donc aucun ne peut distinguer l'obéissance de la désobéissance.
This commit is contained in:
Patrick Schurig 2026-09-05 16:54:38 +02:00
parent d08c82aabf
commit 217f20b58f
3 changed files with 126 additions and 0 deletions

View File

@ -1107,6 +1107,29 @@ aucune, la décision est une intention, et elle se périmera à la vitesse du co
> que « ça compile » : c'est la preuve que le build reproductible produit **exactement ce qui
> tourne**. Tant qu'on ne l'a pas comparé, on a deux artefacts dont on espère qu'ils coïncident.
> ### CINQUIÈME occurrence, et elle inverse le mécanisme (2026-09-05)
>
> Les quatre précédentes décrivent une homogénéité qui **masque** un cas. Celle-ci en **fabrique
> un faux**, et c'est plus dangereux : un cas masqué se signale par un test qui ne mord pas ; un
> cas fabriqué se signale par des **données qui rassurent**.
>
> Le journal de divergence, posé la veille, a produit **14 épisodes en 24 h** — de quoi croire le
> phénomène fréquent et dimensionner tout un lot dessus. Or `ECS-Meter` publie 1500 W en
> permanence et `PAC-Meter` 800 W : ce sont des simulateurs à valeur fixe. L'écart mesuré n'est
> pas une désobéissance, c'est la distance entre une consigne qui varie et un compteur qui n'en
> a rien à faire. **Les quatorze épisodes décrivent le banc, pas le phénomène.**
>
> **Ce qui rend cette forme traître** : l'instrument fonctionne, la donnée est réelle, le compte
> est juste. Rien n'est cassé. Seule la QUESTION à laquelle ces nombres répondent n'est pas celle
> qu'on croyait poser — et un nombre n'annonce jamais de quelle question il est la réponse.
>
> **Parade** : avant de compter, exiger que l'instrument ait pu observer autre chose que ce qu'il
> observe. Ici : un compteur d'écart-type nul sur la fenêtre n'est pas un compteur, c'est une
> constante déguisée, et tout écart mesuré contre lui est un artefact. Le critère de tri
> correspondant est écrit **avant** les données, daté et poussé — cf. `docs/DESIGN_COMMANDE_PERDUE.md`
> §6. Un critère rédigé après coup se plie aux résultats sans jamais mentir, et sans qu'on puisse
> le prouver.
> **Piège de build, 2026-09-01** : changer la DISPOSITION d'une structure dans un en-tête inclus
> transitivement (ici un `QDateTime` ajouté à `EcoProgress`, atteint par `LoadAction`) peut
> laisser des objets compilés contre l'ancienne. Le symptôme est un **plantage dans un

View File

@ -142,3 +142,84 @@ comportement change, et c'est la seule étape qui le fasse.
**Étape 4 — la reprise en main**, si elle est jugée nécessaire après avoir vu les traces des
étapes 2 et 3. **Délibérément en dernier** : c'est la seule qui commande du matériel, et on
saura alors combien de fois le cas se produit réellement.
---
## 6. CRITÈRE DE TRI DES TRACES — écrit le 2026-09-05, AVANT d'avoir les données
> **Écrit avant exprès.** Un critère rédigé après coup se plie aux résultats : on écarte ce qui
> gêne et on garde ce qui confirme, sans jamais mentir, et sans jamais pouvoir le prouver. Celui-ci
> est daté et poussé avant l'ouverture de la fenêtre d'observation. S'il doit changer ensuite, ce
> sera un commit visible, avec sa raison.
### Pourquoi il faut un tri
Le journal de divergence (`+etm56`) a produit **14 épisodes en 24 h** sur le banc, avant même le
retour de la V2C. Aucun n'est exploitable :
```
08:05 DÉBUT "chauffe-eau" — attendu 3500 W, mesuré 1500 W
08:13 DÉBUT "chauffe-eau" — attendu 500 W, mesuré 1500 W
10:01 DÉBUT "chauffe-eau" — attendu 3000 W, mesuré 1500 W
```
`ECS-Meter` publie **1500 W en permanence**, `PAC-Meter` **800 W** — vérifié sur trois lectures
espacées. Ce sont des simulateurs à valeur fixe. L'écart mesuré n'est donc pas une désobéissance :
c'est la distance entre une consigne qui varie et un compteur qui ne varie pas. La divergence
« finit » quand la consigne passe par 1500 W — une coïncidence arithmétique, pas une obéissance.
**Dimensionner l'étape 4 là-dessus aurait été la dimensionner sur des divergences qui n'existent
pas.**
### Le critère, en deux conditions
Une divergence n'est exploitable que sur une charge dont le compteur **suit réellement la
consigne**. Deux conditions, et les deux sont nécessaires :
1. **`measurement.source` ≠ `none`.** Sans mesure propre, l'écart est calculé contre une
estimation, et il ne dit rien de la charge.
2. **Le compteur doit avoir VARIÉ sur la fenêtre**, indépendamment de la consigne. Un compteur
dont l'écart-type est nul sur la période n'est pas un compteur : c'est une constante déguisée,
et tout écart contre lui est un artefact.
**Ne PAS trier par nom de charge.** Écarter `chauffe-eau` et `pac-terrain` nommément serait
fragile de deux façons : ça se périme au premier renommage, et ça n'attrape pas la troisième
charge à compteur fixe qu'on ajoutera sans y penser. Le critère porte sur une **propriété
observable de la donnée**, pas sur une liste.
### Les faux positifs de la V2C, et ils sont d'une autre nature
La V2C a un vrai compteur, donc elle passe le critère ci-dessus. Mais **chaque perte de lien
produira une divergence qui n'est pas une commande perdue** : c'est une **mesure absente**.
Il faut donc distinguer deux affirmations que l'écart seul confond :
| | ce que ça veut dire | geste |
|---|---|---|
| **elle n'obéit pas** | la commande est partie, la mesure la contredit | c'est le cas de l'étape 4 |
| **on ne sait pas si elle obéit** | la mesure manque ou est périmée | rien à reprendre en main |
**C'est exactement la distinction `none` contre l'absence d'un champ, appliquée à un écart.** Une
mesure absente qui se lit comme une mesure à zéro produit une divergence maximale, et c'est le pire
faux positif possible : il ressemble trait pour trait au cas qu'on cherche.
Concrètement, une divergence dont la mesure vaut 0 pendant que le lien est tombé doit être
**comptée à part**, jamais avec les autres. Le relevé du 2026-08-30 le documente : à la perte du
lien, la V2C publie `currentPower` **0** et ses booléens à `false`, tandis que `sessionEnergy`
reste à sa dernière valeur (`LM-1012-d`). Le zéro est donc **publié**, pas absent — et rien dans
l'objet `command` ne le distingue d'un zéro réel.
> **Conséquence à porter au lot**, et à trancher avant de compter : `command` devrait pouvoir dire
> que son `observedW` n'est pas fiable, plutôt que de laisser déduire. C'est la même parade que
> `progress.regime` pour l'avancement. Tant qu'elle n'existe pas, le tri se fait à la main sur les
> traces, en croisant avec les pertes de lien du journal.
### Ce qui sera compté, et ce qui ne le sera pas
- **Compté** : les épisodes sur une charge à compteur variable, hors fenêtres de perte de lien.
- **Compté à part** : les épisodes concomitants d'une perte de lien — ils mesurent la
disponibilité, pas l'obéissance.
- **Écarté** : les épisodes sur une charge dont le compteur est constant sur la fenêtre.
- **Le compte des écartés est publié aussi.** Un tri dont on ne dit pas ce qu'il a jeté n'est pas
un tri, c'est une sélection.

View File

@ -146,3 +146,25 @@ scénario. `thermalProbe` ouvre le volet thermique.
> Aucune de ces trois n'est urgente. Ce qui l'est, c'est de **savoir qu'elles manquent** : sans
> cette liste, chaque lot repaiera le même temps à découvrir qu'un cas est introuvable.
---
## 7. L'homogénéité qui FABRIQUE un cas — 2026-09-05
Les six premières entrées décrivent des cas que le banc ne savait pas **produire**. Celle-ci est
l'inverse : un cas que le banc produit **en trop**, et qui n'existe pas ailleurs.
`ECS-Meter` publie 1500 W en permanence, `PAC-Meter` 800 W. Ce sont des simulateurs à valeur
fixe : ils ne suivent aucune consigne. Le journal de divergence a donc compté **14 épisodes en
24 h** qui ne sont pas des désobéissances, mais la distance entre une consigne variable et un
compteur constant.
**Un cas masqué se signale par un test qui ne mord pas. Un cas fabriqué se signale par des données
qui rassurent** — et rien, dans un compte juste, n'annonce de quelle question il est la réponse.
Le critère de tri est écrit avant les données : `docs/DESIGN_COMMANDE_PERDUE.md` §6.
**Ce qu'il faudrait au mock, et qui manque** : un compteur dont la valeur SUIT la commande de la
charge qu'il mesure. Aucune classe ne le fait aujourd'hui — les compteurs sont des sources
indépendantes qu'on pilote à la main. Tant que c'est le cas, aucun test ne peut exercer une charge
qui obéit, donc aucun ne peut distinguer l'obéissance de la désobéissance.