docs(spec): LM-1208 — sortir de la décision n'est pas sortir de la comptabilité

Quatre constats de l'agent app, vérifiés un par un sur le banc.

A — la CONCLUSION est retenue, le MÉCANISME ne l'est pas.

« Pas de voiture assignée » cesse d'être un critère d'exclusion (LM-1208-b).
Les trois arguments tiennent, et le troisième est décisif : le critère
contredit LM-1206, qui donne le rang et le plancher à la borne et non au
véhicule. S'y ajoutent le cas de l'invité — la borne cesserait d'être arbitrée
au moment précis où elle consomme — et l'invérifiabilité d'une assignation
déclarée à la main.

Mais le budget n'était pas faussé, et c'est le journal du banc qui le montre :
pendant que la V2C tirait, le compteur est passé de −2 915 W (export) à
+3 531 W (import) et l'arbitre a publié « Surplus insuffisant (−3 531 W) —
chauffe-eau à 0 W ». L'ECS n'a pas été servi par-dessus. Le budget part de la
mesure BRUTE (invariant 8) : la consommation d'une charge exclue y est déjà
déduite. L'exclusion est conservatrice.

La règle générale est néanmoins écrite, parce qu'elle a un porteur étroit et
réel : une charge exclue du contexte mais commandée par le PROXY ne reçoit
aucun evReservedW. Transitoire, sans effet aujourd'hui — mais elle mordra au
§10, où la passe éco décide d'acheter.

Et un écart de MESURE, distinct et non tranché, est signalé : le compteur
racine lit ~1,5 kW de moins que la somme des charges mesurées. Même famille que
son aveuglement documenté aux résistances ECS. Ce n'est pas un problème
d'arbitrage, mais un budget juste suppose un compteur qui voit tout.

B — même cause, mais le mode manuel n'est pas en cause : il reste une exclusion
délibérée. Le vrai point est que le mode par défaut d'une borne détectée EST
ChargingModeNormal — une borne neuve n'est donc jamais arbitrée tant que
personne n'a choisi un mode éco. Correct, mais invisible à la mise en service.

C — l'entrée résiduelle se supprime déjà depuis l'app : SetLoadConfig remplace
l'ensemble, et l'auto-provisionnement ne recrée que les bornes dont le Thing
existe. Le geste demandé existe ; la limite à connaître est qu'une entrée dont
le Thing vit encore sera recréée — pour celle-là, c'est enabled: false.

D — instruction reçue, aucun cas particulier V2C dans le moteur, C1 maintenue.
Leur distinction est plus fine que ce que le brief anticipait : un champ absent
se voit, un champ qui s'efface se lit comme un zéro. Troisième régime, et c'est
pourquoi C2 exige que le régime soit publié plutôt que déduit d'une valeur.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017TVywtayEeoRJ2yWUW4iZj
This commit is contained in:
Patrick Schurig 2026-08-28 11:55:32 +02:00
parent 804a9c585d
commit 05310cf561
3 changed files with 144 additions and 2 deletions

View File

@ -190,7 +190,19 @@ vers un gestionnaire d'énergie complet (EV, ECS, PAC SG-Ready, batterie).
- **arm64** cross-compile validé en pré-déploiement (infra CI `etm-powersync-deploy`).
- **`Doxyfile` + job CI `doxygen -W`** (automatiser l'audit doc).
**PROCHAINE ACTION** : **le rang par défaut des bornes auto-provisionnées**, qui retombe à
**PROCHAINE ACTION** : **retirer `assignedCarId` du filtre d'entrée du waterfall**
(`evParticipatesInWaterfall`) — décidé le 2026-08-28, `specs/spec_loadmodel.md` **LM-1208-b** :
le critère contredit LM-1206 (le rang appartient à la borne, pas au véhicule), il est
invérifiable, et il exclut la borne d'un invité au moment précis où elle consomme. Ce qu'on perd
sans voiture assignée est une fonction — échéance, cible d'énergie — pas l'arbitrage. Restent
exclusions : mode manuel (intention explicite) et `pluggedIn` (rien à consommer).
À vérifier au passage, distinct et non tranché : **le compteur racine du banc lit ~1,5 kW de
moins que la somme des charges mesurées** (3 250 W contre 3 980 W pour la seule V2C, plus 800 W
de PAC). Même famille que l'aveuglement documenté aux résistances ECS. Un budget juste suppose un
compteur qui voit tout.
Ensuite : **le rang par défaut des bornes auto-provisionnées**, qui retombe à
égalité avec le rang 1 déjà occupé au lieu de mettre la borne « en tête »
(`docs/RELEVE_3g2.md` §3.2). Trois issues possibles, aucune tranchée — autoriser le rang 0,
renuméroter les autres, ou assumer l'égalité et laisser l'app poser les vrais rangs à la mise

View File

@ -5,7 +5,8 @@
**Contexte** : `docs/RELEVE_3g2.md` (ce dépôt) porte les traces machine, cycle par cycle.
**Contrat** : `INTERFACE.md` fait autorité — ce brief ne fait qu'en signaler les mouvements.
> Cinq points. Le deuxième **retire une mise en garde** que vous portiez — du code conditionnel
> Six points. Le sixième répond à vos quatre constats du 28 août.
> Le deuxième **retire une mise en garde** que vous portiez — du code conditionnel
> peut disparaître. Le cinquième répond à **votre** question sur `targetPercentage`, et c'est
> celui qui change un écran : l'avancement s'affichera en énergie livrée, pas en pourcentage.
@ -178,6 +179,81 @@ déjà côté moteur : `estimatedPowerW` porte son préfixe exprès.
---
---
## 6. Réponses à vos quatre constats du 2026-08-28
### A — la conclusion est retenue, le mécanisme ne l'est pas
**Votre conclusion est juste et elle est adoptée** (`spec_loadmodel.md` **LM-1208-b**) : « pas de
voiture assignée » cesse d'être un critère d'exclusion. Vos trois arguments tiennent, et le
troisième est décisif — **le critère contredit LM-1206**, qui donne le rang et le plancher à la
borne et non au véhicule.
**Mais le budget n'était pas faussé, et c'est votre propre banc qui le montre.** Le budget part
de la mesure **brute** du compteur (invariant 8) : la consommation d'une borne exclue y est déjà
déduite. Journal du 28 à 10:49, pendant que la V2C tirait :
```
Current load on root meter: 3531.4W (avant : −2915 W, en export)
[Arbitre] "chauffe-eau" → "Surplus insuffisant (−3531 W) — chauffe-eau à 0 W"
```
**L'ECS n'a pas été servi par-dessus** — l'arbitre a vu l'import et a refusé. L'exclusion est
*conservatrice* : la charge exclue retire du budget aux autres, et personne ne le lui rend.
> **Votre règle générale est néanmoins retenue**, parce qu'elle a un porteur étroit et réel : une
> borne exclue du contexte mais **commandée par le proxy** ne reçoit aucun `evReservedW`. Sa
> puissance commandée et pas encore mesurée n'est réservée par personne. Transitoire — un cycle —
> et sans effet aujourd'hui, mais **elle mordra au §10**, où la passe éco décide d'acheter.
**⚠️ Un écart de MESURE mérite votre attention, et il est distinct** : le compteur racine lit
**3 250 W** quand la V2C annonce **3 980 W** à elle seule (plus la PAC à 800 W). Environ 1,5 kW
que le compteur racine ne voit pas. Ce n'est pas un problème d'arbitrage — c'est une question de
câblage ou de vue SunSpec, de la même famille que l'aveuglement du compteur aux résistances ECS
documenté dans `AGENTS.md`. **À investiguer pour lui-même** : un budget juste suppose un compteur
qui voit tout.
### B — même cause, mais le mode manuel n'est pas en cause
Corriger A ne suffira pas : la V2C est en **`ChargingModeNormal`**, et le mode manuel reste un
critère d'exclusion **délibéré** — l'utilisateur pilote, l'arbitre s'abstient.
**Le vrai point est ailleurs, et il vous concerne** : le mode par défaut d'une borne fraîchement
détectée **est** `ChargingModeNormal`. Une borne neuve n'est donc jamais arbitrée tant que
personne n'a choisi un mode éco. C'est correct par construction, mais **invisible** — et « la
borne ne charge pas toute seule » se lira comme un défaut. C'est un geste de mise en service à
montrer, pas un correctif moteur.
### C — vous pouvez déjà la retirer, aujourd'hui, sans rien ajouter
L'entrée résiduelle de la Terra AC **se supprime depuis l'app** : `SetLoadConfig` **remplace
l'ensemble**, donc renvoyer la liste sans cette entrée la retire. Et elle ne sera **pas
recréée** : l'auto-provisionnement ne tourne que pour les bornes présentes dans nymea, et le
Thing a été supprimé.
C'est exactement le « geste, pas une suppression d'office » que vous demandez, et il existe déjà.
> **La limite à connaître** : si vous supprimez l'entrée d'une borne dont le **Thing existe
> encore**, elle sera recréée au cycle suivant — c'est l'auto-provisionnement, et c'est voulu.
> Retirer une borne de l'arbitrage sans supprimer son Thing se fait par `enabled: false`, pas par
> suppression.
### D — instruction reçue, rien ne bouge côté moteur
Aucun cas particulier V2C dans le moteur : le contrat reste celui des autres bornes, et **C1 de
LM-1009 est maintenue** — d'autres bornes n'auront ni `sessionEnergy` ni valeur accumulable.
Votre distinction est plus fine que ce que le brief avait anticipé et elle est notée :
**un champ absent se voit ; un champ qui s'efface se lit comme un zéro.** C'est un troisième
régime, entre « mesuré » et « pas mesurable » — et c'est précisément pourquoi C2 exige que le
régime soit *publié* et non déduit d'une valeur.
Et `targetPercentage = 80` observé sur la V2C **confirme sur machine** le défaut corrigé en
`+etm23` : le champ omis retombait à son défaut. Ce n'est plus une déduction.
---
## Ce qui n'a PAS changé, et qu'il ne faut pas déduire
- **L'échéance de départ et le tarif dynamique restent au proxy**, financés au réseau

View File

@ -1031,6 +1031,60 @@ appartient à un chauffe-eau.
`assignedCarId` existe déjà dans `ChargingInfo` : le jour où la communication véhicule arrive,
la migration du rang de la borne vers le véhicule reste possible **sans casser l'acquis**.
**LM-1208 — Une charge sortie de la DÉCISION n'est jamais sortie de la COMPTABILITÉ.**
*(Règle posée par l'agent app, 2026-08-28, sur un constat de banc. La règle est retenue ; le
mécanisme qui l'accompagnait était inexact — voir l'encadré.)*
Quel que soit le motif d'exclusion — mode manuel, véhicule inconnu, borne débranchée — **la
consommation réelle de la charge reste dans le bilan du budget**. Une charge qu'on cesse de
piloter ne cesse pas de consommer.
> **Cette règle est DÉJÀ tenue, et par construction** : le budget part de la mesure **brute** du
> compteur (invariant 8 d'`AGENTS.md`), donc la consommation d'une charge exclue y est déjà
> déduite — sans que personne ait à la réserver. Vérifié au banc le 2026-08-28 : la V2C tirant
> 3,9 kW hors arbitrage, le compteur est passé de −2 915 W (export) à +3 531 W (import) et
> l'arbitre a publié « Surplus insuffisant (−3 531 W) — chauffe-eau à 0 W ». **L'ECS n'a pas été
> servi par-dessus.** L'exclusion est conservatrice : la charge exclue retire du budget aux
> autres, et personne ne le lui rend.
>
> **La règle garde pourtant un porteur, étroit et réel** : une charge exclue du contexte mais
> commandée par le **proxy** ne reçoit aucun `evReservedW` — sa puissance commandée et pas
> encore mesurée n'est réservée par personne (correction A ne couvre que les actions du
> scheduler). Le trou est transitoire — un cycle, jusqu'à ce que le compteur rattrape — et il ne
> mord pas aujourd'hui, le mode manuel faisant sauter la borne aussi côté proxy. **Il mordra au
> §10**, où la passe éco décide d'acheter : acheter en croyant disposer d'une puissance déjà
> engagée est exactement le défaut que la règle nomme.
**LM-1208-b — « Pas de voiture assignée » cesse d'être un critère d'exclusion.** *(Décision
demandée, argument de l'agent app retenu.)*
Trois raisons, et la troisième est décisive :
1. **Le cas de l'invité le rend intenable.** Une voiture qui n'est pas celle du propriétaire ne
sera jamais déclarée, et la borne cesserait d'être arbitrée **précisément quand elle
consomme**.
2. **Le critère n'est pas vérifiable.** L'assignation est déclarée à la main ; rien ne dit ce qui
est réellement branché. Un critère d'arbitrage qui repose sur une déclaration invérifiable
n'arbitre pas, il devine.
3. **Il CONTREDIT LM-1206.** Le rang et le plancher appartiennent à la **borne**, pas au
véhicule. Exiger un véhicule connu pour arbitrer la borne réintroduit exactement la
dépendance que LM-1206 a écartée.
**Ce qu'on perd sans voiture assignée est une FONCTION, pas l'arbitrage** : l'échéance et la
cible d'énergie deviennent indisponibles — dégradation, pas exclusion. C'est la même distinction
que C1 de LM-1009 : une capacité manquante se dit, elle ne fait pas disparaître la charge.
> **Ce qui RESTE un critère d'exclusion, et pourquoi** :
> — **mode manuel** (`ChargingModeNormal`) : c'est une intention explicite de l'utilisateur —
> il pilote, l'arbitre s'abstient. Vérifiable, et voulu.
> — **aucun véhicule branché** (`pluggedIn`) : la borne ne peut rien consommer de ce qu'on lui
> allouerait (mesuré, `docs/RELEVE_3g2.md` §3.1).
>
> ⚠️ **Conséquence d'exploitation à connaître** : le mode par défaut d'une borne fraîchement
> détectée est `ChargingModeNormal`. **Une borne neuve n'est donc jamais arbitrée tant que
> personne n'a choisi un mode éco** — ce qui est correct par construction, mais doit être visible
> à la mise en service, sans quoi « la borne ne charge pas toute seule » se lira comme un défaut.
**LM-1207 — Ne PAS ajouter de `priority` à `ChargingInfo`.** Ce serait un **second système de
priorité**, et il serait immédiatement insuffisant : il ne saurait pas exprimer
**« VE1 > ECS > VE2 »**, puisqu'il ne classerait que les bornes entre elles. Deux classements