# Minimum garanti — design > Ouvert le 2026-09-06. **Option 2 retenue** : livrer le minimum garanti maintenant, avec la > machinerie du §10 ; le renommage l'accompagne. L'arbitrage au prix (option 3) reste l'horizon, > il demande une source tarifaire et une prévision. ## 1. Le constat, et il est double **Le mode `ChargingModeEcoWithMinCurrent` n'a jamais eu de minimum garanti** — non pas parce que le code manquait, mais parce qu'il n'a jamais été atteint. Établi dans `DESIGN_3g.md` §5 : mort par réécriture chez l'amont, puis mort par exclusion depuis 3g-2. **Et son nom promet l'inverse de ce qu'il fait.** `MinCurrent` désigne **l'exigence de la borne** — les 6 A en dessous desquels elle refuse de charger — **pas une garantie du mode**. Un lecteur y voit « le mode maintient un courant minimum » ; le code, lui, ne fait que nommer un seuil matériel. > **Trois modes annoncés, deux implémentés — et celui qui manque est celui que l'utilisateur > croyait utiliser.** C'est la formulation à retenir : le défaut n'est pas qu'une fonction > manque, c'est qu'elle est *annoncée*. ## 2. Pourquoi livrer le minimum maintenant, sans attendre le prix Chiffrage retenu, tarif de rachat récent à **0,01 €/kWh** : | | coût effectif | |---|---| | charger en journée, 30 % au réseau | **0,073 €/kWh** | | charger la nuit, 100 % au réseau | **0,180 €/kWh** | Sur ces installations — **la majorité du parc neuf** — le minimum garanti en journée est simplement le bon choix, et **aucun arbitrage n'est nécessaire pour le savoir**. Le prix ne devient décisif que sur les anciens contrats à **0,1296 €**, où l'écart tombe à deux centimes et **s'inverse sous 62 % de couverture solaire**. **Conclusion de conception** : l'option 3 (comparer deux scénarios au prix) est le bon horizon, mais elle exige une source tarifaire et une prévision. L'option 2 livre l'utile aujourd'hui, et elle ne ferme pas la porte : un arbitrage au prix choisira plus tard *s'il faut* garantir, pas *comment* garantir. ## 3. Condition 1 — la machinerie du §10, pas un second chemin d'achat Le minimum garanti **passe par la passe éco**, celle qui achète déjà : - **borné par l'autorisation de soutirage** (`DrawCap` / `DrawMargin`, trois sources) — comme tout achat ; - **`funding: Grid`** quand le surplus ne couvre pas ; - **le motif dit combien est acheté**, comme `ECO_FLOOR_GRID` le fait déjà. **Ce que cela EXCLUT explicitement** : porter le minimum par `EV_GRID_START`. Ses trois bornes dérivent toutes du surplus (`budgetW > 0`, seuil proportionnel, consommation de tout le budget) ; un minimum permanent en est indépendant par définition, donc les lever revient à créer le second mécanisme. Et `EV_GRID_START` achète **hors** du registre d'autorisation — deux mécanismes dont un seul est borné, et c'est le second qui ferait disjoncter. Raisonnement complet dans `DESIGN_3g.md` §5.4. ## 4. Condition 2 — une puissance permanente, portée sans dupliquer `needs` ### Le champ Un champ de plus **dans `needs`**, frère de `minEnergyWhPerDay` — pas une structure parallèle : ``` needs : { minEnergyWhPerDay : Uint, // énergie, avec échéance dailyDeadline : String, guaranteedPowerW : Uint // NOUVEAU — puissance, permanente } ``` **À ne pas confondre avec `minPowerW`** (`LM-1201`), et la différence est de nature : | | ce que ça dit | |---|---| | `minPowerW` | **SI** on sert cette charge, au moins ceci. Un plancher de **modulation**. | | `needs.guaranteedPowerW` | On sert cette charge au moins ceci, **TOUJOURS** — surplus ou non. Une obligation de **présence**. | Le premier borne une consigne ; le second en crée une. Les deux peuvent coexister sur la même charge sans se contredire. ### La composition dans la passe éco `computeEcoTarget()` rend aujourd'hui une cadence dérivée de l'obligation en énergie. Elle rendra le **maximum des deux** : ``` watts = max( cadenceObligation , guaranteedPowerW ) ``` Quatre invariants, et chacun ferme un silence : 1. **La garantie ne se « tient » JAMAIS.** `tenue` ne décrit que l'obligation en énergie ; une puissance permanente n'a pas de cible et ne se complète pas. Donc quand l'obligation est tenue, `watts` retombe sur la garantie — **pas sur zéro**. C'est exactement la différence de nature, et c'est là qu'elle se voit dans le code. 2. **`progress` ne décrit que l'obligation.** Sur une charge à garantie seule, `progress` est **absent** — jamais à zéro : un avancement nul se lirait « rien livré », alors qu'il n'y a rien à avancer. 3. **Le motif dit LEQUEL DES DEUX MORD.** Sans ça, l'écran affiche un nombre qu'il ne peut pas expliquer — et deux causes différentes produiraient le même chiffre. Le motif gagne `guaranteedW` et une marque de ce qui borne. 4. **Une garantie non honorée se DIT.** Si l'autorisation de soutirage ne la permet pas, elle n'est pas servie — et c'est `DRAW_CAP` qui le dit, en nommant la garantie. Le silence ici ferait croire à une garantie tenue. ## 5. Condition 3 — nommer les trois modes pour ce qu'ils font **Le fil ne peut pas être renommé** : `ChargingMode` est une énumération publiée, et changer ses identifiants casserait tout client déployé. Ce qui se corrige, c'est **la description au contrat** — c'est là que vit le mensonge, et c'est de là que l'app tire ses libellés. | valeur | ce que le contrat dit AUJOURD'HUI | ce que le code FAIT | |---|---|---| | `ChargingModeNormal` | « Recharge immédiate au maximum disponible » | **MANUEL.** La borne sort de l'arbitrage — *« l'utilisateur pilote, l'arbitre s'abstient »*. Le moteur ne commande **rien**. Seule la protection de surcharge la touche encore. | | `ChargingModeEco` | « Recharge sur surplus solaire uniquement » | exact | | `ChargingModeEcoWithMinCurrent` | « Eco + courant minimum garanti (6 A) si pas de surplus » | **rien** — le chemin n'est pas atteint | **`Normal` n'est pas un « boost ».** Un boost commanderait le maximum ; celui-ci ne commande pas. La seule chose que le moteur y fasse encore est de délester en surcharge — ce qui doit rester, et doit être **dit** : un mode « manuel » qui coupe quand même mérite de l'annoncer. ## 6. Les étapes, à comportement constant d'abord **Étape A — corriger le contrat.** Les trois descriptions ci-dessus, plus la note sur `MinCurrent` qui nomme l'exigence de la borne. **Aucun code.** Comportement constant par construction, et c'est le pas qui rend la suite lisible. **Étape B — porter `guaranteedPowerW` dans `LoadNeeds`, le persister, le publier**, sans que la passe éco s'en serve. Aller-retour `Get`/`SetLoadConfig`, schéma déclaré une fois. Comportement constant : le champ existe et ne décide de rien. **Étape C — la passe éco le prend en compte.** Le seul pas qui change le comportement, et il arrive quand tout le reste est déjà en place et vérifiable. Avec les quatre invariants du §4, le motif enrichi, et le `DRAW_CAP` qui nomme la garantie. **Étape D — le mode s'y branche.** `ChargingModeEcoWithMinCurrent` posé sur une borne écrit `guaranteedPowerW = plancher de la borne`. C'est le pas qui rend la promesse du nom vraie — et il vient en dernier, parce qu'il n'a de sens qu'une fois C livrée. ## 7. Ce qu'on ne saura pas prouver au banc, et il faut le dire L'installation de `.75` produit **2 kWc** contre un plancher de borne triphasée à **4 140 W**. Une garantie sur cette borne serait donc **toujours** financée au réseau, jamais au surplus — le banc ne peut pas exercer le cas mixte, celui où la garantie complète un surplus partiel. Il l'exercera en revanche très bien sur une charge en watts — le chauffe-eau — dès qu'elle aura un compteur réel (`TEST_TERRAIN.md` §12). **C'est la même précondition que pour l'étape 4 de la commande perdue**, et elle est maintenant nommée par un quatrième chemin.