Les trois premiers constats de BRIEF_agent_plugin.md, dans l'ordre de ce qu'ils coûtent.
§2 — Renommer une charge n'atteignait jamais l'adaptateur. updateSoftConfig() ne
portait que priority et needs, donc un changement de libellé seul était compté
« inchangée » : l'adaptateur gardait son ancien nom et le journal contredisait
GetLoadConfig jusqu'à la prochaine reconstruction. `label` entre dans la signature et
dans le prédicat soft de l'arbitre, sans entrer dans sameHardware() — mise à jour EN
PLACE, pas reconstruction. La vraie prise était le Q_UNUSED de SgReadyAdapter, hérité
d'avant le lot B-bis : sans lui, renommer la PAC — le cas même qu'on allait tester —
n'aurait rien changé, et on aurait conclu que le correctif ne marchait pas.
§3 — relays[] n'est plus comparé par index. Un réordonnancement reconstruisait la
charge : contacts ouverts, verrous réarmés à froid. Comparer comme un ENSEMBLE aurait
été faux dans l'autre sens — à somme égale la table retient la première combinaison
rencontrée, donc échanger deux relais de même puissance change le contact qui sert ce
palier. sameHardware() compare la TABLE DÉRIVÉE : deux listes qui produisent les mêmes
paliers avec les mêmes contacts sont matériellement identiques, par construction.
§4 — mechanism.stagesW publie les paliers atteignables, en télémétrie et pas dans
GetLoadConfig. La télémétrie n'a aucun chemin d'écriture, donc « lecture seule » y est
vrai par construction ; GetLoadConfig aurait cassé l'aller-retour neutre dont l'app
dépend pour écrire — elle renvoie verbatim ce qu'elle a lu, le champ serait revenu
dans SetLoadConfig, et un refus en bloc aurait emporté toutes les charges.
deriveStages() est l'implémentation unique de la combinatoire, partagée par les trois
usages. C'était le fond de la demande du §4 : une seule règle, pas de divergence.
tests/auto/loadmodel : cible neuve sans serveur nymea, 2 ms. Elle a attrapé un défaut
de la correction elle-même avant le banc — operator== comparait les listes de ThingIds
et voyait une différence entre fermer {K1,K2} et fermer {K2,K1}.
tools/repair_energylogs.py : §1, et ce n'est PAS un correctif de ce plugin. La cause
est extérieure et déjà corrigée (SunSpec float32 aux mots permutés, d08cf50 daté
05:30:14 UTC — la seconde du premier échantillon empoisonné). La séquelle, elle, était
définitive : à 7,5e33 kWh le plus petit incrément représentable vaut 1,67e18, donc le
compteur n'était pas faux mais GELÉ, et rechargé tel quel à chaque démarrage.
Appliqué sur .75 : 62 726 anomalies → 0, accumulation reprise et vérifiée en direct.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XPUo3RMr8SzK6qbFtfBm8H
HAVE_DOT = YES, mais CALL_GRAPH et CALLER_GRAPH restent à NO, et pas pour une question
de coût : le moteur est signal-driven. powerBalanceChanged → verifyOverloadProtection()
est une connexion Qt, invisible à l'analyse statique ; un graphe d'appel montrerait
update() comme un point d'entrée orphelin et raterait le mécanisme principal de la
couche L4. Un schéma faux vaut moins que pas de schéma.
Ce que dot apporte réellement : héritage, collaboration, inclusions. SVG, lisible à toute
échelle et diffable, avec DOT_GRAPH_MAX_NODES = 60 pour éviter les pavés illisibles.
tools/gen-doc.sh : une seule commande, le Doxyfile épinglé. C'est la leçon du piège des
générateurs — 163 avertissements sans sortie contre 113 avec HTML+XML sur le même arbre.
Un chiffre de référence ne vaut que rattaché à une configuration exacte, et une commande
unique empêche qu'on régénère « à sa façon ». Le script signale aussi une version de
doxygen différente de la référence 1.9.8.
Avertissement ajouté en tête du Doxyfile, à côté de celui sur les générateurs : le graphe
d'héritage sera tronqué. EnergyArbitrator : public SmartChargingManager, mais l'amont est
hors INPUT. C'est voulu — élargir INPUT ferait exploser le compte d'avertissements. Sans
cette note, quelqu'un le « réparera ».
graphviz est documenté comme dépendance de la cible doc, pas du build : build-cross-arm64
compile, il ne dessine pas.
Hors de ce lot, comme convenu : \defgroup, carte \dot cliquable, WARN_AS_ERROR = YES,
hébergement.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>