diff --git a/CLAUDE.md b/CLAUDE.md index 5245e62..b49fc70 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -264,8 +264,16 @@ surplus, même cycle — et c'est pourquoi le champ a dû descendre d'un cran ** L'identité vérifiable devient : *somme des `targetW` des niveaux financés au surplus == `budget.allocatedW`*. Vérifiée à la sonde sur `.75` le 2026-08-30 (`+etm30`) : -3 500 + 3 000 == 6 500, puis 1 500 == 1 500 au cycle suivant. Une charge financée au réseau -vit dans `budget.evReservedW`. Omis en mode dégradé — sans plan, pas de financement. +3 500 + 3 000 == 6 500, puis 1 500 == 1 500 au cycle suivant. Omis en mode dégradé — sans +plan, pas de financement. + +> 🔴 **Et il n'y a d'identité que de ce côté-là.** Une charge financée au réseau ne vit +> **nulle part** : `budget.evReservedW` n'est pas un registre d'allocation mais un **terme de +> correction** du budget, qui mêle la correction « commandé non encore mesuré » à la part +> réseau d'`EV_GRID_START` — une borne servie au réseau qui tire déjà ce qu'on lui a commandé +> y contribue **0** alors que son `targetW` vaut 7 000 W. Constaté par le moteur le +> 2026-08-30 en câblant R3. Les watts achetés n'auront de registre qu'avec +> `draw.committedW`, préalable à R3. **Ne réconcilier aucun total sur `evReservedW`.** Le niveau publié est `"comfort"` et ce **n'est pas un rebaptisage** : c'est bien la passe qui, au §10, servira le confort depuis le surplus. Un niveau à `targetW: 0` est une passe @@ -339,7 +347,8 @@ Et **deux pièges de lecture**, tous deux au contrat : **3. `EV_GRID_START` partage une allocation entre les DEUX compteurs du budget.** C'est le seul motif qui le fasse : `budgetW` vient du surplus et entre dans `budget.allocatedW`, -`gridW` est acheté au réseau et entre dans `budget.evReservedW`, avec +`gridW` est acheté au réseau — et **n'entre dans aucun registre** (cf. §1 : `evReservedW` +est une correction, pas une destination), avec `budgetW + gridW == allocatedW`. Toute réconciliation doit traiter cette ligne à part — cf. `LoadTelemetryEntry.surplusShareW`. Motif **jamais vu sur machine** au 2026-08-27 : la clé est prête, rien n'est bâti autour. diff --git a/docs/BRIEF_plugin_depuis_maquettes.md b/docs/BRIEF_plugin_depuis_maquettes.md index 451754b..d42983c 100644 --- a/docs/BRIEF_plugin_depuis_maquettes.md +++ b/docs/BRIEF_plugin_depuis_maquettes.md @@ -2,6 +2,69 @@ --- +## 2026-08-30 (suite) — `draw.committedW` en préalable : OUI, sans réserve + +**Et le refus de livrer `counts` sur `budget.evReservedW` est le bon appel.** Une identité +*dépendante du temps* est pire que pas d'identité : vraie au premier cycle après un +changement, fausse après convergence, elle passerait tous les tests — qui portent sur des +cycles isolés — et **certifierait** un total faux chez les clients. R3 existe pour empêcher +une réconciliation qui pourrit sans se voir ; la livrer sur un terme tantôt registre tantôt +correction aurait fabriqué exactement ça, avec en plus le sceau d'une identité publiée. + +### Les trois destinations, et ce que l'app peut en dire + +| Destination | Nature | Réconciliable ? | +|---|---|---| +| `budget.allocatedW` | **registre d'allocation** (surplus) | **oui, aujourd'hui** — mesuré sur `.75` | +| `budget.evReservedW` | **terme de correction** du budget, deux natures mêlées | **non, et jamais** | +| `draw.committedW` | **registre** des watts achetés | oui, dès qu'il existe | + +Conséquence, à dire telle quelle : **il n'existe aujourd'hui qu'une identité vérifiable, et +elle ne couvre qu'un côté.** `Σ targetW(surplus) == budget.allocatedW` — vérifiée à la sonde +le 2026-08-30 (06:10 et 06:14). Côté réseau : **rien**. Pas « à vérifier plus tard », pas +« approximativement `evReservedW` » : rien, jusqu'à `draw.committedW`. + +### Nous portions la fausse affirmation, et elle part aujourd'hui + +Elle est écrite chez nous en cinq endroits — « une charge financée au réseau vit dans +`budget.evReservedW` » (`CLAUDE.md` ×2, le modèle ×3, la description ARB de la mention +« servie au réseau »). Retirée dans le même lot, sans changement de comportement. + +> **Et la distinction avec notre discipline de la semaine, parce qu'elle a l'air de la +> contredire.** L'exception `EV_GRID_START` décrit un **comportement de la box** : on ne la +> retire qu'au vu de la sonde. « `evReservedW` est la destination des watts achetés » est une +> **affirmation sur le sens d'un champ**, et elle est fausse *maintenant*, sur la box +> d'aujourd'hui. Attendre une livraison pour corriger ce qu'on a compris de travers serait +> laisser une doc mentir en connaissance de cause. **La sonde arbitre ce que fait la box, pas +> ce que nous en avons cru.** + +### Trois demandes sur `draw.committedW` + +**a. Par cycle, en watts, dans la même trame que `budget`.** Sinon on compare deux instants, +et l'identité redevient dépendante du temps par un autre chemin — celui-là même qu'on vient +d'éviter. + +**b. Ne fabriquez pas le reste de l'objet `draw`.** Notre maquette lui donne aussi +`authorisedW`, `remainingW`, `binding`, `perPhaseBound` (§10). Publier +`draw: { "committedW": 1400 }` **seul** est parfait. Publier `authorisedW: 0` ou +`binding: "connection"` par défaut ferait afficher à l'écran « ordre de service » un +**plafond de soutirage qui n'existe pas, avec sa source** — un chiffre crédible et faux, et +la faute exacte que ce champ est censé rendre impossible. Absent, jamais forgé : l'écran 2 +n'apparaîtra qu'avec l'objet complet. + +**c. Une phrase de définition pour `evReservedW`.** Nous l'affichons sous le libellé +**« Réservé au véhicule »** (`_BudgetTable`), qui affirme une réservation là où il y a une +correction. Nous ne le renommerons pas au jugé — donnez la définition, nous écrirons le +libellé. C'est le seul geste que cette découverte laisse en suspens côté écran. + +### Ce qui ne bouge pas + +`counts` reste retenu tel qu'arbitré ce matin : la **forme** ne change pas, seul son préalable +apparaît. Et l'exception `EV_GRID_START` reste dans le code et dans `CLAUDE.md` — elle tiendra +plus longtemps que prévu, et c'est très bien ainsi. + +--- + ## 2026-08-30 — R3 : `counts` est retenu, et `funding` sort de la réconciliation **Réponse à la question du moteur sur le niveau mixte.** La forme proposée est prise telle diff --git a/docs/mockups/deux_passes_eco_confort_mockup.html b/docs/mockups/deux_passes_eco_confort_mockup.html index f92a057..4b9e80d 100644 --- a/docs/mockups/deux_passes_eco_confort_mockup.html +++ b/docs/mockups/deux_passes_eco_confort_mockup.html @@ -239,7 +239,7 @@
setpointW, currentA), qui existe déjà aujourd'hui.
draw.committedW."mixed" publié : une troisième valeur tomberait dans la branche par défaut de tout
client — « surplus » — donc reproduirait la panne de l'omission, et elle serait dérivable de
counts, donc supprimée un jour à juste titre.
+ Et il a un préalable, trouvé en le câblant (2026-08-30) : draw.committedW.
+ budget.evReservedW n'est pas un registre d'allocation mais un terme de correction du
+ budget — une borne servie au réseau qui tire déjà ce qu'on lui a commandé y contribue 0 pour un
+ targetW de 7 000 W. Σ counts == targetW y serait vraie au premier cycle après un
+ changement et fausse ensuite : une identité dépendante du temps, qui passe tous les tests et
+ certifie un total faux. Les watts achetés n'ont aucun registre aujourd'hui — d'où une seule identité
+ vérifiable, du côté surplus, et rien de l'autre côté tant que committedW n'est pas publié.
Ce que l'app promet en échange : les clés de counts sont traitées comme des
identifiants opaques, jamais comme des chemins. Une clé inconnue d'une version ancienne n'est pas
perdue : l'identité Σ counts == targetW reste vérifiable sans connaître le sens des clés, et
diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb
index 12296ee..602fb90 100644
--- a/lib/l10n/app_fr.arb
+++ b/lib/l10n/app_fr.arb
@@ -155,7 +155,7 @@
},
"telemetryFundedByGrid": "Financée au réseau (échéance ou tarif dynamique) — hors budget de surplus",
"@telemetryFundedByGrid": {
- "description": "funding == « grid » : l'allocation vit dans budget.evReservedW, pas dans budget.allocatedW. Sans cette mention, l'utilisateur voit une charge servie alors que le surplus est nul et croit à un défaut."
+ "description": "funding == « grid » : l'allocation est hors de budget.allocatedW, et sans registre où la retrouver (evReservedW est une correction du budget, pas une destination — constaté 2026-08-30). Sans cette mention, l'utilisateur voit une charge servie alors que le surplus est nul et croit à un défaut."
},
"telemetryNotArbitrated": "Non arbitrée — absente du dernier cycle publié",
"@telemetryNotArbitrated": {
diff --git a/lib/models/load_telemetry.dart b/lib/models/load_telemetry.dart
index 9ce9d8a..cfddb1d 100644
--- a/lib/models/load_telemetry.dart
+++ b/lib/models/load_telemetry.dart
@@ -441,7 +441,11 @@ class LoadTelemetryEntry {
///
/// - `"surplus"` — la cascade PV. L'allocation est comptée dans `budget.allocatedW`.
/// - `"grid"` — le proxy (échéance de départ, tarif dynamique) qui **soutire au
- /// réseau**. Elle vit dans `budget.evReservedW`, PAS dans `budget.allocatedW`.
+ /// réseau**. Elle n'est PAS dans `budget.allocatedW` — et elle n'est nulle part
+ /// ailleurs non plus : `budget.evReservedW` est un **terme de correction** du budget,
+ /// pas un registre d'allocation (constaté par le moteur le 2026-08-30 en câblant R3 —
+ /// une borne au réseau déjà mesurée y contribue 0 pour un `targetW` de 7 000 W). Les
+ /// watts achetés n'auront de registre qu'avec `draw.committedW`.
///
/// **Sommer les `allocatedW` sans filtrer donne un écart avec `budget.allocatedW` que
/// rien ne permet d'interpréter** : défaut du moteur, ou borne servie au réseau ? Cf.
@@ -541,7 +545,7 @@ class LoadTelemetryEntry {
}
/// Vrai quand **tout** ce qui est servi à cette charge est acheté au réseau — donc
- /// compté dans `budget.evReservedW` et non dans `budget.allocatedW`.
+ /// **hors** de `budget.allocatedW`, et sans registre où le retrouver (voir [funding]).
///
/// Volontairement faux sur `'mixed'` : la mention « servie au réseau » serait alors une
/// demi-vérité, et c'est un écran à deux niveaux qui la remplacera (R1, R3 à R8).
@@ -681,9 +685,12 @@ class LoadTelemetry {
/// Somme des allocations **financées par le surplus**.
///
- /// C'est le seul terme comparable à `budget.allocatedW` : une borne servie au réseau
- /// est comptée dans `budget.evReservedW`, et l'inclure ici creuserait un écart que rien
- /// ne permettrait d'interpréter — défaut du moteur, ou borne au réseau ?
+ /// C'est le seul terme comparable à `budget.allocatedW` : une charge servie au réseau
+ /// n'entre pas dans ce compteur, et l'inclure ici creuserait un écart que rien ne
+ /// permettrait d'interpréter — défaut du moteur, ou charge au réseau ?
+ ///
+ /// **Et c'est la seule identité qui existe** : il n'y en a aucune du côté réseau tant que
+ /// `draw.committedW` n'est pas publié. `budget.evReservedW` ne peut pas en tenir lieu.
///
/// Somme des [LoadTelemetryEntry.surplusShareW], et non des `allocatedW` filtrés : le
/// démarrage soutiré (`EV_GRID_START`) partage une même allocation entre les deux