docs(prévision PV): la clé de révision — déduplication, et receivedAt s'appelle receivedAt
Retenu : déduplication sur le contenu, pas de requête meta.json. Mais le coût n'est pas un décalage de cycle — c'est un HORIZON FAUX DE PLUSIEURS HEURES. Entre l'initialisation d'un run et sa mise à disposition il s'écoule la latence de publication du modèle : des heures pour un modèle global. Donc targetAt − receivedAt n'est pas l'horizon, il est trop court de toute cette latence, systématiquement et dans le même sens. Une prévision qu'on croirait à H−1 peut être le run de H−5. Ce que la déduplication sauve : les BORNES des révisions — combien, et laquelle s'applique. Ce qu'elle ne sauve pas : leur ÂGE. « Quelle prévision » est juste, « quel horizon » est faux. Sans effet sur ce lot qui AFFICHE ; déterminant pour l'apprentissage, dont l'objet est justement de corréler l'erreur à l'horizon. Trois conditions : 1. La colonne s'appelle receivedAt, JAMAIS issuedAt. Un nom qui promet l'heure du run fabrique le calcul faux tout seul : quelqu'un écrira targetAt - issuedAt et obtiendra un nombre plausible. Et il faut l'écrire : aucun horizon ne se calcule depuis receivedAt. 2. La déduplication compare les points COMMUNS, pas la charge utile. Si la fenêtre glisse, un == naïf verrait une révision toutes les heures — exactement ce que la déduplication existe pour éviter. Je code la comparaison sur l'intersection dans les deux cas : elle est correcte pour les deux et ne dépend pas d'un comportement du voisin qui pourrait changer sans préavis. 3. La dette meta.json se rouvre AVEC son consommateur. La décision reposait sur « aucun consommateur ne le demande » et elle RESTE juste : un affichage n'a pas besoin de l'âge du run. Le jour où quelque chose corrèle l'erreur à l'horizon, meta.json devient nécessaire — et la rouvrir maintenant au nom d'un besoin supposé serait payer une requête par cycle pour un calcul que personne ne fait. Volume confirmé : 24-48 points, 4-8 révisions/jour ⇒ ~200-400 lignes/jour au lieu des 1150 estimées sur révision horaire. Et la dette forecastModel : la colonne model reste NULLE tant que la correction n'est pas livrée. Un NULL qui dit « on ne sait pas » est honnête ; une valeur qui dit « ce qu'on avait demandé » est fausse d'une façon parfaitement crédible. Aucun remplissage rétroactif. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015F7G5VeaPVSMeVNjiGj36p
This commit is contained in:
parent
0b8264ab04
commit
4a0dfa273f
@ -381,3 +381,91 @@ faut que quelqu'un le vérifie à l'exécution, une fois, à l'entrée.
|
||||
`issuedAt` est **dans la charge utile**, pas déduit de l'instant de réception — sinon un
|
||||
redémarrage de `ems` réétiquette toute la série avec l'heure du redémarrage, et la table
|
||||
bitemporelle perd exactement ce qu'elle existe pour retenir.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 13. La clé de révision — tranché le 2026-09-08
|
||||
|
||||
**Retenu : la déduplication sur le contenu, et la colonne s'appelle `receivedAt`.**
|
||||
Pas de requête `meta.json`. Mais la décision n'est bonne qu'avec les trois conditions ci-dessous,
|
||||
et la première est celle qui la rend acceptable.
|
||||
|
||||
### 13.1 Le coût réel n'est pas un décalage de cycle — c'est un horizon FAUX de plusieurs heures
|
||||
|
||||
`receivedAt` n'est pas « `issuedAt` à une minute près ». Entre l'initialisation d'un run et sa
|
||||
mise à disposition, il s'écoule la **latence de publication du modèle** — des **heures**, pas des
|
||||
minutes, pour un modèle global.
|
||||
|
||||
Conséquence directe : `targetAt − receivedAt` **n'est pas l'horizon**. Il est trop court de toute
|
||||
la latence de publication, **systématiquement et dans le même sens**. Une prévision qu'on croirait
|
||||
« à H−1 » peut être le run de H−5.
|
||||
|
||||
> **Ce que la déduplication sauve, et ce qu'elle ne sauve pas.** Elle donne les **bornes** des
|
||||
> révisions exactement : *combien* de révisions, et *laquelle* s'applique. Elle ne donne pas leur
|
||||
> **âge**. « Quelle prévision » est juste ; « quel horizon » est faux.
|
||||
>
|
||||
> C'est sans effet sur ce lot, qui **affiche**. C'est déterminant pour l'apprentissage, dont
|
||||
> l'objet même est de corréler l'erreur à l'horizon.
|
||||
|
||||
### 13.2 Condition 1 — la colonne s'appelle `receivedAt`, jamais `issuedAt`
|
||||
|
||||
Un nom qui promet l'heure du run alors qu'il porte l'heure de réception fabrique le calcul faux
|
||||
tout seul : quelqu'un écrira `targetAt - issuedAt` et obtiendra un nombre **plausible**. C'est la
|
||||
classe qu'on paie le plus cher ici, et le remède est le même que pour `forecast` — **le nom porte
|
||||
la protection.**
|
||||
|
||||
Et il faut l'écrire, pas seulement le nommer : **aucun horizon ne se calcule depuis `receivedAt`.**
|
||||
|
||||
### 13.3 Condition 2 — la déduplication compare les points COMMUNS, pas la charge utile
|
||||
|
||||
« Courbe identique à la précédente » ne suffit pas si la fenêtre **glisse** : si openmeteo ne
|
||||
publie que les heures à venir, la charge utile de 11 h a un point de moins que celle de 10 h, et
|
||||
un `==` sur la charge utile verrait une révision **toutes les heures** — exactement ce que la
|
||||
déduplication existe pour éviter.
|
||||
|
||||
La règle : *deux charges utiles sont la même révision si, sur leurs `targetAt` COMMUNS, toutes les
|
||||
valeurs coïncident.*
|
||||
|
||||
> **Question à trancher avec openmeteo, et elle décide de l'implémentation** : la fenêtre
|
||||
> publiée couvre-t-elle les journées **entières** (aujourd'hui 00 h → J+1 23 h, passé compris),
|
||||
> ou seulement **les heures à venir** ? Dans le premier cas le jeu de points est stable dans la
|
||||
> journée et un `==` naïf suffirait — sauf au passage de minuit. Dans le seesecond, il faut la
|
||||
> comparaison sur l'intersection. **Je code la seconde dans les deux cas** : elle est correcte
|
||||
> pour les deux, et elle ne dépend pas d'un comportement qu'un changement chez le voisin pourrait
|
||||
> retirer sans nous prévenir.
|
||||
|
||||
### 13.4 Condition 3 — la dette `meta.json` se rouvre AVEC son consommateur, pas avant
|
||||
|
||||
La décision de ne pas appeler `meta.json` reposait sur *« aucun consommateur ne le demande »*.
|
||||
Elle **reste juste** : le consommateur d'aujourd'hui est un **affichage**, et un affichage n'a
|
||||
pas besoin de l'âge du run — il a besoin de savoir *ce qu'on prévoyait*, ce que la déduplication
|
||||
donne exactement.
|
||||
|
||||
Le consommateur qui en aura besoin est **l'apprentissage**, et il n'existe pas encore. La dette
|
||||
est donc notée, avec son déclencheur :
|
||||
|
||||
> **Le jour où quelque chose corrèle l'erreur à l'horizon, `meta.json` devient nécessaire** — et
|
||||
> la décision se reprend avec un consommateur réel, ce qui est le raisonnement qui l'a rendue
|
||||
> juste la première fois.
|
||||
|
||||
Ce qui serait fautif, c'est de la rouvrir **maintenant** au nom d'un besoin supposé : une requête
|
||||
par cycle payée aujourd'hui pour un calcul que personne ne fait.
|
||||
|
||||
### 13.5 Volume, confirmé
|
||||
|
||||
48 h d'horizon, **24 à 48 points** selon l'heure. À 4–8 révisions par jour après déduplication :
|
||||
**~200 à 400 lignes par jour**, contre les 1 150 estimées au §8.2 sur une révision horaire. La
|
||||
rétention du §8.2 devient largement confortable, et l'effondrement aux deux bouts peut attendre
|
||||
bien plus que 7 jours.
|
||||
|
||||
### 13.6 La dette `forecastModel` — je ne m'appuie pas dessus, et je n'écris rien de plausible
|
||||
|
||||
`forecastModel` publie le **modèle configuré**, pas celui qui a répondu. Le stocker comme
|
||||
provenance enregistrerait une **intention**, et une intention rangée dans une colonne de
|
||||
provenance devient une provenance au premier lecteur.
|
||||
|
||||
Donc : la colonne `model` existe et reste **NULLE** tant que la correction n'est pas livrée. Un
|
||||
`NULL` qui dit « on ne sait pas » est honnête ; une valeur qui dit « ce qu'on avait demandé » est
|
||||
fausse d'une façon parfaitement crédible. **Et aucun remplissage rétroactif** : les lignes écrites
|
||||
avant la correction resteront nulles, parce qu'elles le sont.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user