docs(prévision PV): BLOQUÉ — le découpage contredit l'invariant « ZÉRO cloud »

Le §1 de ce design fait appeler une API distante par ems. C'est interdit ici, et
l'interdiction est explicite à quatre endroits : AGENTS.md invariant 10 (« aucun
appel réseau sortant vers un service distant […] le moteur expose l'état, il ne
contacte personne », dont la seule exception nommée est un socket local/LAN) et
docs/SAFETY.md, trois fois.

Ce n'est pas une objection de style : « fonctionne sans internet » est un
argument produit, et le mode dégradé L2 est bâti sur l'idée que rien
d'essentiel ne dépend d'un lien externe.

Je n'avais PAS vu ce conflit en écrivant le design — il a été soulevé hors de ce
fil, avec le point d'attribution CC BY 4.0 qui va avec : l'obligation suit
l'appelant, donc si ems appelle, elle atterrit dans un dépôt où elle n'est
écrite nulle part et serait perdue en silence, dans un dépôt GPL publié.

Aucun code avant arbitrage. Deux issues, et ce n'est pas à l'agent de trancher :
soit l'invariant 10 est amendé avec sa raison écrite et l'attribution posée ici,
soit le découpage change et l'appel reste chez le plugin météo.

Trois décisions rendues, consignées :
- nouvelle table, et la raison est plus forte que la mienne — la CLÉ CHANGE DE
  NATURE, une prévision révisée n'a rien à faire dans la base du mesuré ;
- un Get* sans *Changed : l'invariant 11 vise l'ÉTAT VIVANT, pas l'historique.
  La distinction n'y était pas écrite ; l'appliquer mécaniquement aurait produit
  une notification par heure sur une donnée que personne n'attend en direct ;
- aucun effet sur l'arbitrage. Le jour où l'étalement éco lira la prévision, ce
  sera un lot à part — et le §10 est la seule place où elle mordrait, en pariant
  sur une courbe dont le §3 dit qu'elle est un plafond systématique.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015F7G5VeaPVSMeVNjiGj36p
This commit is contained in:
Patrick Schurig 2026-09-08 16:35:11 +02:00
parent 5316a6f723
commit 91250f081f

View File

@ -1,5 +1,33 @@
# Prévision de production PV — une série, et elle est révisée
> ## ⛔ BLOQUÉ — le §1 contredit un invariant du dépôt
>
> **Ce document propose que `ems` appelle lui-même une API distante. C'est interdit ici**, et
> l'interdiction est explicite à quatre endroits :
>
> - `AGENTS.md` invariant **10** : *« ZÉRO cloud — aucun appel réseau sortant vers un service
> distant […] Le moteur expose l'état, il ne contacte personne. »* La seule exception nommée
> est le client d'optimiseur sur socket **local/LAN**, jamais un service externe ;
> - `docs/SAFETY.md` §« Signalisation locale (zéro cloud) », puis deux rappels : *« Aucun canal
> sortant réseau »*, *« Le système fonctionne SANS internet »*.
>
> **Ce n'est pas une objection de style** : « fonctionne sans internet » est un argument produit
> (autoconsommation, local-first), et le mode dégradé L2 est construit sur l'idée que rien
> d'essentiel ne dépend d'un lien externe.
>
> **Et l'attribution CC BY 4.0 suit l'APPELANT.** Si `ems` appelle, l'obligation d'attribution
> d'Open-Meteo atterrit dans un dépôt où elle n'est écrite nulle part — donc elle serait
> **perdue**, en silence, dans un dépôt GPL publié. *(Point soulevé hors de ce fil ; noté ici
> parce que c'est ce dépôt qui la porterait.)*
>
> **Aucun code ne s'écrit avant arbitrage.** Deux issues, et ce n'est pas à l'agent de
> trancher : soit l'invariant 10 est **amendé, avec sa raison écrite** et l'attribution posée
> dans ce dépôt ; soit le **découpage change** et l'appel reste chez le plugin météo, qui a
> déjà le droit de sortir.
>
> Tout ce qui suit reste valable **sous réserve de cet arbitrage** : le §2 (table bitemporelle)
> et les §3 à §5 ne dépendent pas de qui appelle.
> Ouvert le 2026-09-08. **Design avant code, rien d'implémenté.**
> Cadrage donné par Patrick. Les constats météo viennent de l'agent openmeteo et sont
> **repris tels quels** : ils sont mesurés, pas supposés.
@ -217,3 +245,34 @@ s'observe au banc, y compris en travers d'un changement d'heure.
Le pas **D** est celui qui touche à la frontière avec le produit, et il arrive quand la série est
déjà vérifiable.
---
## 11. Décisions rendues le 2026-09-08
**Question 1 — qui appelle l'API.** *Non tranchée, remontée.* Voir l'encadré en tête.
Les quatre décisions ci-dessous ne s'appliquent qu'une fois celle-là réglée.
**Nouvelle table, pas `energylogs.sqlite`.** Retenu, et la raison retenue est plus forte que
celle du §8.3 : ce n'est pas seulement que l'amont migre ce schéma, c'est que **la clé change de
nature**. `energylogs` est indexée par un instant de mesure ; la table de prévision est indexée
par une **paire**. Une prévision révisée n'a rien à faire dans la base du mesuré.
**Un `Get*`, sans `*Changed` — amendement à l'invariant 11.** L'invariant (*« tout élément
runtime a un `Get*` ET un `*Changed` »*) vise **l'état de l'arbitre**, qui bouge à chaque cycle
et dont un client déconnecté se retrouverait en retard sans pouvoir se resynchroniser. **Une
courbe historisée n'a pas ce problème** : elle se lit sur demande, comme `GetPowerBalanceLogs`.
Pas de notification.
> À noter comme précédent : l'invariant 11 porte sur **l'état vivant**, pas sur **l'historique**.
> La distinction n'y était pas écrite, et l'appliquer mécaniquement aurait produit une
> notification par heure sur une donnée que personne n'attend en direct.
**Aucun effet sur l'arbitrage.** Le lot est un **affichage**. La prévision n'entre pas dans le
plan, ne pondère pas l'étalement éco, ne déplace aucune échéance.
> Le jour où l'étalement éco lira la prévision, ce sera **un lot à part avec sa propre
> décision** — et le **§10** est aujourd'hui la seule place où elle mordrait : c'est la cadence
> d'obligation qui achèterait moins ce matin en pariant sur cet après-midi. Un pari, sur une
> courbe dont le §3 dit qu'elle est un **plafond** systématique. À ne pas glisser dans ce lot-ci.