8 Commits

Author SHA1 Message Date
Patrick Schurig
5dfd8b9047 docs: trois modes tranchés, et les transitions de dérogation sont écartées du tri
DÉCISION PRODUIT (Patrick, 2026-09-08, après validation du lot sur le banc) :
trois modes — Normal (manuel), PV, Min+PV — et le boost n'en est PAS un
quatrième. C'est la dérogation : un bouton d'action à côté du sélecteur, posé
par SetLoadDerogation et non par SetChargingInfo, avec sa durée obligatoire et
bornée [60 s, 6 h] que l'écran doit faire saisir. Gravé dans les RÉPONSES
FIGÉES : un mode se choisit et dure, une dérogation répond à un besoin ponctuel
et s'efface — les deux ne se rangent pas au même endroit.

CRITÈRE DE TRI DE L'ÉTAPE 4 — une clause de plus, écrite sur la mesure. Une
dérogation fait bouger la consigne de plusieurs kilowatts d'un coup, et CHAQUE
BORD ouvre une divergence : à l'ouverture la voiture négocie sa montée (13800
attendus, 3930 mesurés, convergence en 300 s), à la fermeture la borne n'a pas
encore décru (0 attendu, 8367 mesurés).

La fermeture est la plus trompeuse : immédiate, énorme, et trait pour trait
semblable à une commande ignorée. Le discriminant est temporel et déjà publié —
une divergence née dans le même cycle qu'un DEROGATION_ENDED, ou qu'un
DEROGATION_ACTIVE neuf, est une transition.

Sans cette clause, chaque boost compterait pour DEUX incidents, et l'étape 4 se
justifierait d'elle-même en comptant ses propres transitoires : le mécanisme du
§6.2 — un instrument qui fabrique la preuve dont il a besoin — déplacé du banc
vers la mesure.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015F7G5VeaPVSMeVNjiGj36p
2026-09-08 12:09:03 +02:00
06e728415f docs: protocole du relevé du 2026-09-08, écrit avant la mesure
Même raison que le critère de tri du §6 : un protocole rédigé après coup se plie à
ce qu'on a vu.

TROIS OBSERVATIONS. (1) progress.regime de la V2C — première bascule observable sur
du réel, et la dérogation en dépend entièrement puisque sa fin measurementLost se
déclenche sur ce signal. Les trois issues possibles sont écrites d'avance, et
AUCUNE n'est un échec : chacune décide de ce qu'on peut promettre. (2)
command.divergent — les premières traces qui passent le critère du §6, maintenant
qu'une borne charge vraiment et qu'un compteur suit ; regarder d'abord les épisodes
COURTS, ce sont eux qui décident si l'étape 4 vaut le risque de rejouer une
commande. (3) Min+PV sur la borne, où le tirage est dix fois celui du chauffe-eau.

Et le biais de comptage est rappelé : contrairement à « error limit reached », les
lignes [Divergence] DÉBUT/FIN sont émises aux transitions seulement — c'est le
comptage juste.

CE QUI INVALIDERAIT LE RELEVÉ est écrit aussi : tout redémarrage de nymead pendant
la fenêtre repose la base d'avancement. Ne rien déployer pendant l'observation.
2026-09-08 06:22:01 +02:00
9659518916 docs: verdict de la fenêtre du week-end — rien d'exploitable, et pourquoi
La V2C est restée HORS WATERFALL du samedi 18:00 au dimanche 11:46, 1 066 cycles
portant « Borne V2C Trydan hors waterfall (mode manuel ou aucun véhicule
branché) » et « has no car assigned. Ignoring... ». Elle n'a produit aucune trace
sur la période visée, et ce n'était pas un battement de lien.

La voiture est devenue visible à 11:46 dimanche, pas samedi soir. Huit cycles
utiles ont suivi, 11:47 à 12:08, sur le PV simulé à 9 kWc — démarrages en
tolérance d'acquisition puis consignes de surplus. Puis plus rien : le banc est
passé d'un simulateur 9 kWc à une installation réelle de 2 kWc, et 2 kWc ne peut
pas alimenter le plancher de 4 140 W d'une borne triphasée à 6 A.

Bilan : V2C aucune trace, chauffe-eau et pac-terrain écartées par le critère du §6
(compteurs constants, 1 500 et 800 W puis 0). C'est un résultat, pas un échec — il
dit que la fenêtre a été ouverte sur un banc qui ne pouvait pas la remplir, et il
nomme les deux raisons.

Précondition pour la prochaine : un compteur réel sur une charge pilotée, et une
borne effectivement dans le waterfall — vérifié au journal AVANT d'ouvrir.
2026-09-06 13:23:57 +02:00
322cf27e0f docs: crête PV à 6 kWc, voiture branchée, et la convention de signe du réseau
TROIS FAITS du 2026-09-06, consignés parce que les traces de lundi en dépendent.

11:47:23 — crête PV du simulateur portée de 9 000 à 6 000 W (banc/cmd/peak,
retenu, courtier 192.168.1.131). Vérifié contre le modèle : écart moyen 0,3 W sur
216 échantillons de plein jour, contre 1 102 W pour l'hypothèse 9 000.

~12:00 — voiture branchée à la V2C. pluggedIn true, lien connected,
sessionEnergy 0,44 kWh. Aucun redémarrage de nymead dans les deux cas : ce ne sont
pas des coutures de baseline.

CE QUE 6 kWc NE CASSE PAS, contrairement à ce que j'avais craint. minPowerW vaut
4140 W (3 × 6 A × 230 V) et le surplus ne dépasse pas ~2 700 W à cette crête ; j'en
avais conclu que la borne ne démarrerait jamais. Faux : mesuré à midi simulé, elle
passe en EV_GRID_START dès 2 140 W de budget, puis en SURPLUS_SETPOINT. Le chemin
d'appoint réseau existe pour ce cas, et BELOW_MIN_POWER seul ne dit pas que la
borne est bloquée — il dit que CE budget-là ne suffit pas. Encore une conclusion
tirée d'un motif lu hors de sa trajectoire.

CONVENTION DE SIGNE, mesurée pour lever une ambiguïté d'écran.
currentPowerAcquisition est NÉGATIF en injection, POSITIF en soutirage — même
convention que banc/etat/grid. Dix échantillons appariés dont un passage par zéro
(−638 → +1939 W) : 10/10 de même signe. currentPowerProduction est négatif de même,
par la convention nymea « from a consumer perspective ».

Un client qui affiche « consommation réseau » sur un currentPowerAcquisition
négatif inverse le sens : la valeur dit que l'installation INJECTE. Le signe porte
la direction ; la valeur absolue seule ne la porte pas.
2026-09-06 12:11:48 +02:00
bf8d890c8e docs: conditions de la fenêtre d'observation du week-end
Posé dimanche 2026-09-06 à 08:19 (Europe/Paris) : chauffe-eau, minEnergyWhPerDay
3000 → 2000, dailyDeadline inchangé à 12:00. Discipline habituelle — capture sur
disque avant écriture, 76 clés comparées, 1 divergence attendue, 0 imprévue — mais
PAS de restauration : la configuration reste en place tout le week-end.

Symboles de débogage laissés en place jusqu'à lundi, donc aucune couture
supplémentaire pendant la fenêtre. Les deux dernières restent 06:53:30Z (fuseau) et
09:22:57 (installation des symboles), toutes deux du 2026-09-05.

CE QUE L'ÉCRAN MONTRE À LA POSE, et pourquoi ce n'est pas un défaut. À 08:19 le
palier est ECO_FLOOR_MET avec deliveredWh = 30 475 Wh pour une cible de 2 000.
Arithmétiquement correct et sans intérêt : le compteur de l'ECS publie 1 500 W en
permanence, donc deliveredWh monte de 1,5 kWh/h que la charge soit commandée ou
non. La période a basculé hier à 12:00 ; vingt heures plus tard elle a « livré »
30 kWh.

LA FENÊTRE UTILE EST À 12:00 et dure ~80 minutes. À la bascule, la base est reprise
(LM-1013-c) : deliveredWh repart de 0 face à 2 000 Wh sur 24 h, soit une cadence de
83 W financée par le réseau si le surplus manque, que le compteur fixe comble en
2000/1500 = 80 min. Deux fenêtres sur le week-end — dimanche 12:00 et lundi 12:00.

ET C'EST LA CINQUIÈME FORME D'HOMOGÉNÉITÉ QUI FIXE CE PLAFOND. Sur un banc dont le
compteur ne suit pas la commande, on ne peut pas avoir à la fois une cible modeste
et un chemin d'achat longuement exercé : ce qui décide n'est pas la cible, c'est la
constance du compteur. Tenir l'achat en éveil tout le week-end demanderait de
dépasser 36 kWh/jour, c'est-à-dire acheter au plafond — précisément ce qu'on
voulait éviter. La contrainte est du banc, pas du moteur.
2026-09-06 08:20:33 +02:00
217f20b58f 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.
2026-09-05 16:54:38 +02:00
Patrick Schurig
3eb59e86f9 docs+test(commande perdue §3): le recrédit est un prêt consenti contre l'obéissance
Mesuré AVANT d'implanter, et la mesure a corrigé le diagnostic.

Le constat disait « un budget de surplus qui ignore ces watts ». Ce n'est pas
ce qui se passe : quand une charge consomme et OBÉIT, la comptabilité est
juste — sa conso est recréditée puis réallouée à elle-même, et les suivantes
ne reçoivent que le surplus réel. Export 500 W, A à 4 400 W obéissante, B
reçoit 500 W. Corriger cela aurait été corriger un non-défaut.

Le vrai défaut est plus grave, et l'hypothèse est écrite dans le code :
« le budget est une mesure dont la conso de la charge a déjà été retranchée »,
c'est-à-dire « je peux rendre ces watts parce que je peux les reprendre ».
C'est un prêt, et rien ne vérifie que l'emprunteur rembourse.

Mesuré, le cas où la promesse est engagée : A commandée à 0 par son plancher,
ses 4 400 W redistribués à B. Si A obéit, tout est juste. Si A n'obéit pas —
commande perdue, mode manuel, véhicule qui limite — la maison tire 8 400 W
pour 4 900 de production : 3 500 W importés que personne n'a décidés.

Et l'identité surplus + recrédit − alloué == restant TIENT dans les deux cas.
C'est ce qui distingue un prêt d'une erreur : la comptabilité est juste,
c'est l'hypothèse sur laquelle elle repose qui n'est pas vérifiée — donc
aucun contrôle de cohérence ne pouvait l'attraper.

Le test épingle le comportement ACTUEL, correct SOUS HYPOTHÈSE, et dit à
quelle condition il devient faux : le jour où le recrédit sera conditionné à
l'obéissance constatée, c'est l'allocation de B qu'il faudra revoir, pas le
test. Écrit pour qu'on ne le « corrige » pas par réflexe.

Ce que le design proposait — retrancher la conso subie du budget — est SANS
OBJET : elle en est déjà retranchée par le compteur. La note est conservée
pour que personne ne la réimplante en la croyant oubliée.

Suite : simulation 60/60, loadmodel 22/22, charging 48/48 identique à la
référence, doxygen 0 avertissement.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015F7G5VeaPVSMeVNjiGj36p
2026-09-01 11:58:06 +02:00
Patrick Schurig
4d73ff2482 docs: §10 déployé sur .75, et le design de la commande perdue
Déploiement vérifié SUR MACHINE et non déduit du script : version relue,
nymead actif, arbitre initialisé, et les quatre motifs du §10 présents dans
le binaire posé.

Piège de vérification noté au passage : authorisedW, perPhaseBound et
binding sont des QStringLiteral, donc stockés en UTF-16 et invisibles à
`strings` par défaut. Un premier relevé les donnait absents — j'ai failli
les rapporter manquants. `strings -el` les trouve. Vérifier une chaîne dans
un binaire demande de savoir comment elle y est encodée.

Et le design du premier constat de l'app, ouvert plutôt qu'attaqué au code.
Trois choses qu'il établit, toutes mesurées :

Le titre est trop étroit. « Réappliquer la commande de l'arbitre » ne décrit
pas le cas : en mode manuel l'arbitre NE COMMANDE PAS. Ce qui s'est passé est
qu'une écriture du proxy a échoué pendant l'indisponibilité, que personne ne
l'a rejouée, et que l'organe est resté sur une consigne dont plus aucun
commandeur ne se réclame.

La pièce qui manque est là où le constat porte : l'EvAdapter ne garde PAS sa
dernière consigne, là où les adaptateurs en watts la gardent. Ils en ont
besoin pour l'écrêtage de verrou ; la borne était pilotée par le proxy, qui
n'a jamais eu à se relire.

Le vrai coût n'est pas l'affichage. draw.committedW à 0 pendant que 4,4 kW
sont tirés veut dire que le budget de surplus est calculé sans ces watts :
le moteur alloue de l'énergie qui n'existe pas. Le délestage, lui, protège —
il agit sur la marge MESURÉE, qui les inclut. C'est le budget qui ment.

Quatre décisions posées, dont la principale : signaler toujours, réappliquer
jamais telle quelle. Rejouer une consigne vieille de plusieurs minutes, c'est
décider avec des données mortes — ce que le mode dégradé L2 refuse déjà de
faire. Ce qui manque n'est pas le rejeu, c'est que l'écart soit DIT tant
qu'il dure, et il dure indéfiniment quand personne ne reprend la main.

Ordre de travail : mémoire de la commande, puis écart publié sans décider
dessus, puis comptabilité corrigée, et la reprise en main EN DERNIER — c'est
la seule étape qui commande du matériel, et on saura alors combien de fois
le cas se produit vraiment.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015F7G5VeaPVSMeVNjiGj36p
2026-09-01 07:12:05 +02:00