docs(prévision PV): conversion — fallback retiré, physics seule valeur émise (D1)

Décision de Patrick du 2026-10-13. `fallback` avait été écrit sans
définition (protocole §5.2, design §28.5) et aucun émetteur ne l'a jamais
produit : correction avant publication, notée au changelog 1.1 du
protocole. Une prévision dégradée (température absente) se lit dans
`corrections`, pas dans `conversion`. Le champ reste pour des valeurs
futures.

- OPTIMIZER_PROTOCOL §5.2 et §0 (1.1) ;
- INTERFACE.md, GetForecastSnapshot ;
- design : notes datées en §28.5 et §29, nouveau §30.1 ;
- commentaires du handler (aucun changement de comportement).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Patrick Schurig 2026-10-13 06:39:38 +02:00
parent f05d4c6629
commit 5468192cf8
3 changed files with 28 additions and 6 deletions

View File

@ -1343,6 +1343,8 @@ pas un état du code.*
5. **§5 maintenu : aucune correction apprise dans le GPL.** `conversion` ∈ `physics` | `fallback` ;
le plugin GPL n'émet jamais `hybrid`. Un optimiseur qui corrige la prévision le déclare de son
côté (`OPTIMIZER_PROTOCOL.md` §6, `diagnostics.inputsUsed.pv`).
> *Note du 2026-10-13 : `fallback` est **retiré** — `conversion` vaut `physics`, seule valeur
> émise. Voir §30.1.*
6. **§11 maintenu : la prévision n'entre dans aucune décision sans un lot dédié**, avec sa propre
décision écrite. Les décisions 1 à 4 améliorent la courbe ; elles ne la branchent sur rien.
@ -1374,3 +1376,16 @@ pas un état du code.*
et par pas (brief 3 T2) portera les paramètres en vigueur ; c'est lui qui rendra la cause lisible.
- **`conversion` vaut toujours `physics`.** Aucun émetteur de `fallback` n'existe dans ce dépôt, et
le dépôt ne définit nulle part ce qu'il désignerait — point laissé ouvert, pas deviné.
> *Note du 2026-10-13 : point tranché, `fallback` est retiré (§30.1).*
## 30. Décisions du 2026-10-13 — après les rapports T0/T1 du brief 3
*Consignées telles que rendues par Patrick. Rien de ce qui précède n'est réécrit : les §28 et §29
restent l'état de leur date, et c'est ici qu'on lit ce qui les corrige.*
1. **`conversion` : `fallback` est retiré.** Le §28 décision 5 écrivait `physics` | `fallback` ;
le §29 relevait que `fallback` n'était défini nulle part. La règle devient : `conversion` vaut
`physics`, **seule valeur émise par le plugin GPL** ; le champ reste pour des valeurs futures.
Une prévision **dégradée** (température absente) se lit dans `corrections: []`, pas dans
`conversion`. Correction **avant publication** (`OPTIMIZER_PROTOCOL.md` §0, 1.1) : aucun
émetteur n'a jamais produit `fallback`.

View File

@ -40,6 +40,10 @@ optimiseur 1.0 reste conforme (champs inconnus ignorés, §9).
rév. 3, avant toute implémentation socket). Aucun consommateur déployé n'en dépend ; ils
sont retirés du document sans changement de majeure.
**Correction avant publication (2026-10-13)** : `conversion` n'admet plus `fallback`. La
valeur avait été écrite sans définition ; **aucun émetteur ne l'a jamais produite**. Seule
`physics` est émise ; une prévision dégradée se lit dans `corrections`.
- §5.2 **Prévisions explicites** (`forecast`) : grille temporelle déclarée, PV, consommation
de base, température, prix complet. Remplace le renvoi à `CONTRACT_A_openmeteo.md`.
- §5.3 **Groupes** (`group`) : clé de tri à deux niveaux. `priority` reste le rang effectif.
@ -240,9 +244,12 @@ Règles :
conversion (`DESIGN_PREVISION_PV.md` §4).
- `weatherModel` : modèle météo **qui a réellement répondu** (repli `best_match` compris),
`null` si inconnu — jamais le modèle configuré.
- `conversion` : `physics` | `fallback`. Le plugin GPL **n'émet jamais `hybrid`** :
la correction apprise vit hors GPL (`DESIGN_PREVISION_PV.md` §5). Un optimiseur qui
corrige la prévision le déclare dans `diagnostics.inputsUsed.pv` (§6).
- `conversion` : `physics` (seule valeur émise par le plugin GPL). Le champ reste pour des
valeurs futures ; un consommateur ignore une valeur qu'il ne connaît pas plutôt que de la
deviner. Une prévision **dégradée** (température absente, par exemple) ne se lit **pas**
ici : elle se lit dans `corrections` (`[]` = aucune correction). Le plugin GPL **n'émet
jamais `hybrid`** : la correction apprise vit hors GPL (`DESIGN_PREVISION_PV.md` §5). Un
optimiseur qui corrige la prévision le déclare dans `diagnostics.inputsUsed.pv` (§6).
- `issuedAt` : instant du run s'il est connu, sinon `null`. **Ce n'est pas l'âge de chaque
case** (`DESIGN_PREVISION_PV.md` §20-21). `contentChangedAt` : instant d'apparition du
contenu courant — un producteur figé ne doit pas se lire comme une prévision stable (§26.2).

View File

@ -407,7 +407,7 @@ NymeaEnergyJsonHandler::NymeaEnergyJsonHandler(SpotMarketManager *spotMarketMana
returns.insert("o:model", enumValueName(String));
returns.insert("o:forecastPoints", QVariantList() << snapPoint);
returns.insert("o:corrections", QVariantList() << enumValueName(String));
returns.insert("o:conversion", enumValueName(String)); // physics | fallback
returns.insert("o:conversion", enumValueName(String)); // physics, seule valeur émise
returns.insert("o:acLimitW", enumValueName(Uint));
returns.insert("o:fault", enumValueName(String));
returns.insert("o:faultParams", enumValueName(Variant));
@ -1281,8 +1281,8 @@ JsonReply *NymeaEnergyJsonHandler::GetForecastSnapshot(const QVariantMap &params
// Ce qui a été fait à la courbe, publié AVEC elle (OPTIMIZER_PROTOCOL §5.2) : une liste vide
// est une affirmation — conversion brute — pas une absence.
ret.insert(QStringLiteral("corrections"), QVariant(rev.corrections).toList());
// `physics` : le moteur GPL n'a pas d'autre conversion. Ni `hybrid` (correction apprise, hors
// GPL, §5), ni `fallback` (aucun émetteur aujourd'hui).
// `physics` : le moteur GPL n'a pas d'autre conversion. Jamais `hybrid` (correction apprise,
// hors GPL, §5). Une prévision dégradée se lit dans `corrections`, pas ici (§30.1).
ret.insert(QStringLiteral("conversion"), QStringLiteral("physics"));
if (const std::optional<int> plafond = arb->forecastAcLimitW())
ret.insert(QStringLiteral("acLimitW"), *plafond);