diff --git a/docs/DESIGN_PREVISION_PV.md b/docs/DESIGN_PREVISION_PV.md index 01a441f..db4a056 100644 --- a/docs/DESIGN_PREVISION_PV.md +++ b/docs/DESIGN_PREVISION_PV.md @@ -1177,5 +1177,30 @@ n'avait fait, parce que le symptôme était compatible avec deux causes. - **La FORME des valeurs** : on vérifie qu'une clé est là, pas que son contenu est du bon type ni qu'il a du sens. `forecastPoints: []` passe — et c'est correct, une table vide est un état légitime. -- **Les paramètres OPTIONNELS** : `o:knownAt` n'est jamais exercé. Une déclaration optionnelle - supprimée ne serait pas vue. +- ~~**Les paramètres OPTIONNELS**~~ — **fermé le 2026-09-09**. Le balayage fait un **second + passage** avec les optionnels renseignés, et la contre-épreuve mord : retirer `o:knownAt` fait + sortir `Invalid params: Invalid key: knownAt`. C'était une classe et non un cas — *ce qui n'est + jamais exercé n'est pas « peu testé », c'est indistinguable d'absent*, alors qu'un client lit + les optionnels dans l'introspection et les croit disponibles. + + +--- + +## 25. Alignement des plans — NON OBSERVÉ, et il faut le dire ainsi + +Le producteur confirme son correctif au cycle de 09:20. **Ce cycle ne prouvera rien de mon +côté** : le plan de test a été retiré à 08:11:36, il n'en reste **qu'un**, et une garde qui +compare deux plans ne s'exerce pas sur un seul. + +> **À noter comme NON OBSERVÉ, jamais comme validé.** Un silence de la garde signifie ici « rien +> à comparer », pas « les plans sont alignés ». Les deux produisent exactement la même trace : +> aucune ligne. + +C'est le mode d'érosion de l'instrument dont le silence ressemble à un résultat, dans sa forme la +plus banale — et il aurait été facile de conclure de travers, puisque le résultat attendu et +l'absence de mesure ont la même apparence. + +**Ce qu'il faudra pour l'observer** : deux plans réels et durables sur un site, ou une fenêtre +d'observation pendant laquelle un second plan existe. Le seul relevé exploitable à ce jour reste +celui de 08:08 — deux plans, même `issuedAt`, même `t0`, somme correcte — et il a été obtenu par +le chemin **forcé**, pas par la boucle horaire naturelle. diff --git a/tests/auto/simulation/simulation.cpp b/tests/auto/simulation/simulation.cpp index 97bbe5f..84af2dd 100644 --- a/tests/auto/simulation/simulation.cpp +++ b/tests/auto/simulation/simulation.cpp @@ -7038,6 +7038,15 @@ void Simulation::testEveryGetterReturnsWhatItDeclares() { QStringLiteral("NymeaEnergy.GetPvForecast"), {{"from", "2026-09-09T00:00:00Z"}, {"to", "2026-09-10T23:00:00Z"}} }, }; + // LES OPTIONNELS AUSSI, et c'est une classe à part : aucun appel nominal ne les utilise, + // donc leur disparition ne casse rien de visible. Ce qui n'est jamais exercé n'est pas + // « peu testé » — c'est indistinguable d'absent, alors qu'un client les lit dans + // l'introspection et les croit disponibles. + const QHash optionnels { + { QStringLiteral("NymeaEnergy.GetPvForecast"), + {{"from", "2026-09-09T00:00:00Z"}, {"to", "2026-09-10T23:00:00Z"}, + {"knownAt", "2026-09-09T12:00:00Z"}} }, + }; int verifies = 0; QStringList muettes; @@ -7086,6 +7095,16 @@ void Simulation::testEveryGetterReturnsWhatItDeclares() } } + // SECOND PASSAGE : les mêmes méthodes, avec leurs paramètres OPTIONNELS renseignés. Un + // optionnel supprimé de la déclaration ferait ici « Invalid params », comme les requis. + for (auto it = optionnels.constBegin(); it != optionnels.constEnd(); ++it) { + const QVariantMap brut = injectAndWait(it.key(), it.value()).toMap(); + if (brut.value(QStringLiteral("status")).toString() != QLatin1String("success")) + muettes << QStringLiteral("%1 (avec optionnels) → statut « %2 » (%3)") + .arg(it.key(), brut.value(QStringLiteral("status")).toString(), + brut.value(QStringLiteral("error")).toString()); + } + QVERIFY2(verifies >= 5, qUtf8Printable(QStringLiteral("seulement %1 getter(s) parcouru(s) — le balayage " "ne prouve rien s'il ne balaie rien").arg(verifies)));