develop #256

Merged
gabriel merged 9 commits from develop into main 2026-09-09 20:45:53 +00:00
Owner

Ce que ça change

Closes #

Preuve


Si ça touche infra/terraform/

  • terraform plan -out=tfplan ci-dessous, avant la fusion
  • terraform apply tfplan ci-dessous, après la fusion
  • Le pair a relu le plan, pas seulement le code
terraform plan -out=tfplan

terraform apply tfplan

Relecture

  • Un pair a relu et laissé un commentaire, même court
  • Ses remarques sont traitées, ou une réponse explique pourquoi elles ne le sont pas

Ce qui suit le code

  • docs/runbooks/ mis à jour, un geste d'exploitation a changé
  • docs/adr/ complété, une décision structurante a été prise
  • docs/journal.md complété, un incident a été rencontré
  • Une nouvelle variable d'environnement est apparue, elle est dans .env.example

Où regarder en priorité

## Ce que ça change <!-- Deux phrases. Ce qu'un relecteur doit comprendre avant d'ouvrir le code. --> Closes # ## Preuve <!-- Ce que la chaîne d'intégration ne peut pas vérifier à ma place : sortie de commande, capture d'écran, journal d'exécution. La chaîne contrôle déjà le format, les tests et l'absence de secrets, inutile de le répéter ici. --> ``` ``` ## Si ça touche `infra/terraform/` <!-- Supprimer cette section entière si ce n'est pas le cas. L'`apply` n'est pas automatisé, faute de service principal : cette trace est la seule preuve que l'appliqué correspond au relu (ADR 0007). Ne jamais coller le fichier `tfplan` lui-même, il porte l'état. --> - [ ] `terraform plan -out=tfplan` ci-dessous, **avant** la fusion - [ ] `terraform apply tfplan` ci-dessous, **après** la fusion - [ ] Le pair a relu le plan, pas seulement le code <details><summary><code>terraform plan -out=tfplan</code></summary> ``` ``` </details> <details><summary><code>terraform apply tfplan</code></summary> ``` ``` </details> ## Relecture - [ ] Un pair a relu et laissé un commentaire, même court - [ ] Ses remarques sont traitées, ou une réponse explique pourquoi elles ne le sont pas ## Ce qui suit le code <!-- Ne cocher que ce qui s'applique, supprimer le reste. --> - [ ] `docs/runbooks/` mis à jour, un geste d'exploitation a changé - [ ] `docs/adr/` complété, une décision structurante a été prise - [ ] `docs/journal.md` complété, un incident a été rencontré - [ ] Une nouvelle variable d'environnement est apparue, elle est dans `.env.example` ## Où regarder en priorité <!-- Là où tu as hésité, ou ce qui mérite un second avis. Facultatif, mais ça fait gagner du temps au relecteur. -->
supervision: la dérive du modèle s'alerte mais ne se regarde nulle part (#117)
All checks were successful
Intégration / Contrôles statiques du dépôt (pull_request) Successful in 10s
Intégration / Terraform — format, validité et lint (pull_request) Successful in 16s
Intégration / Tableau de bord — dépendances, tests et construction (pull_request) Successful in 44s
Intégration / Checkov — audit de la configuration (pull_request) Successful in 19s
Intégration / Workflows — lint et audit de sécurité (pull_request) Successful in 17s
Intégration / Python — qualité, tests et dépendances (pull_request) Successful in 5m49s
2660e51ea3
Le #117 a livré la sixième alerte d'exploitation et les sept métriques qui la
nourrissent, mais AUCUN panneau : aucun des huit tableaux de bord ne
référençait `ev_ia_*`. La dérive était donc binaire et muette — soit une issue
s'ouvrait dans la forge, soit on ne voyait rien.

Trois conséquences, et la deuxième est la plus gênante.

1. L'étage « surveillance » ne s'affichait nulle part. C'est pourtant lui qui
   justifie un verdict à trois valeurs plutôt que deux : il existe pour qu'on
   VOIE VENIR une dérive sans être réveillé. Sans graphe, il ne servait à rien.

2. L'annotation `action` de la règle demandait de comparer
   `entrees_deplacement_ecarts_types` et `erreur_ratio` — c'est le geste qui
   sépare « le parc a changé de régime, le modèle tient » de « le modèle
   décroche, il faut réentraîner ». Elle nommait deux séries qu'il fallait
   aller chercher à la main dans Explore, au moment précis où l'on vient
   d'être réveillé.

3. Rien ne montrait la surveillance elle-même s'arrêter. L'âge de la dernière
   mesure réussie déclenche l'alerte à 3 h, mais sa montée n'était visible
   qu'après coup.

Nouveau tableau de bord `modele` (uid `enervision-modele`), treize panneaux :
six indicateurs de tête (verdict, âges des deux horodatages, les trois
écarts), puis les courbes — verdict en marches, MAE récente contre MAE de
référence en kW, un graphe par écart avec sa borne en ligne tiretée, les
couples (prévu, réalisé) avec leur plancher de 14, et l'âge de la mesure.

LES BORNES DES PANNEAUX SONT CELLES DE `inference/config.py`, orange compris :
l'orange est l'étage « surveillance » tel que `derive._verdict` le calcule —
la moitié de la borne pour ce qui part de zéro, la moitié du CHEMIN jusqu'à la
borne pour la dispersion, dont le repos vaut 1. Un orange posé à la moitié de
la valeur serait tombé sous le repos et se serait allumé en permanence.

Les séries se lisent par `max by (modele_version)` : la référence est figée à
la promotion, une nouvelle version est une nouvelle série et non la suite de
la précédente. Un TROU dans une courbe veut dire « pas mesuré », jamais
« stable » — chaque description de panneau le dit, parce que c'est la lecture
qui coûte cher de se tromper.

Le banc de supervision exige désormais qu'un tableau de bord — n'importe
lequel, le contrôle ne nomme pas de fichier — trace les quatre séries dont on
a besoin pour trancher une fois l'issue ouverte. C'est ce qui empêche l'oubli
de se reproduire : il ne comptait jusqu'ici que les règles et leurs
destinataires.

Le runbook n'avait pas suivi non plus : il annonçait « dix règles » depuis le
#228, sa vérification d'après déploiement attendait dix titres et sept
tableaux de bord, et sa table du § 7 n'avait pas la ligne de la dérive.
front : le tableau de bord affiche l'heure du poste, et le dit
All checks were successful
Intégration / Contrôles statiques du dépôt (pull_request) Successful in 9s
Intégration / Terraform — format, validité et lint (pull_request) Successful in 16s
Intégration / Checkov — audit de la configuration (pull_request) Successful in 17s
Intégration / Tableau de bord — dépendances, tests et construction (pull_request) Successful in 45s
Intégration / Workflows — lint et audit de sécurité (pull_request) Successful in 17s
Intégration / Python — qualité, tests et dépendances (pull_request) Successful in 5m50s
a6ea7372fe
Toutes les heures de données sortaient en UTC. Un écran ouvert à Paris à 20 h 10
affichait « dernière relève 17:59 » sur une donnée vieille de onze minutes, et
son dernier bâton à « 16 h » sur l'heure de 18 h. La conclusion naturelle est
que la chaîne a deux heures de retard. Elle a été tirée en interne ce soir, sur
une chaîne qui venait justement de passer aux dix minutes. Devant un jury, elle
serait tirée aussi et personne ne serait là pour détromper.

Les instants passent donc dans le fuseau du poste : étiquettes d'axe, en-tête
d'infobulle, heure de relève, colonnes des tableaux. Ce qui ne change pas :
l'heure reste ABSOLUE, jamais « il y a X minutes » — un relatif calculé contre
l'horloge du poste grandit sans fin et ne dit rien de la fraîcheur.

LE FUSEAU EST ÉCRIT À L'ÉCRAN, à côté de « dernière relève », qui est la seule
valeur de l'en-tête qu'un lecteur compare à sa propre montre. Il est lu à
l'exécution et non figé : écrire « heure de Paris » en dur mentirait à qui
ouvrirait le tableau ailleurs.

UNE EXCEPTION, ET ELLE EST DÉLIBÉRÉE. `formaterJour` reste en UTC. Le journal
de collecte nomme une JOURNÉE, pas un instant : « 2026-09-01 » est une date
nue, que le navigateur lit à minuit UTC. La convertir ferait afficher la veille
à l'ouest de Greenwich, soit un journal décalé d'un jour, en silence. Un cas
d'essai garde cette exception, sans quoi le prochain passage l'effacerait par
souci de cohérence.

Les « (UTC) » des en-têtes de tableau disparaissent : la colonne porte l'heure
du poste, et le fuseau se nomme une fois, pas à chaque colonne.

LE FUSEAU DES CAS D'ESSAI EST FIXÉ à « Europe/Paris » dans `vitest.config.js`.
Un lancement en UTC passerait sans rien prouver, les deux formes coïncidant :
la conversion qu'on vient d'introduire ne serait jamais exercée. Posé dans la
configuration et non dans le script npm, parce que `TZ=… npm run` ne fonctionne
pas sur un poste Windows et que la moitié de l'équipe en a un.

Deux cas ajoutés pour ce que le décalage change vraiment : une série qui
bascule de jour à 23:30 UTC — l'axe portait deux « lun. 31 » à la suite — et
l'heure d'hiver, où l'écart tombe à une heure. Un décalage figé à deux heures
serait faux la moitié de l'année, et personne ne le verrait avant décembre.

Éprouvé : 510 cas front au vert, construction Vite au vert.
docs: le rapport EC02 porte le RACI, la méthode, les jalons, les risques et le CRA
All checks were successful
Intégration / Contrôles statiques du dépôt (pull_request) Successful in 9s
Intégration / Terraform — format, validité et lint (pull_request) Successful in 18s
Intégration / Tableau de bord — dépendances, tests et construction (pull_request) Successful in 46s
Intégration / Checkov — audit de la configuration (pull_request) Successful in 17s
Intégration / Workflows — lint et audit de sécurité (pull_request) Successful in 17s
Intégration / Python — qualité, tests et dépendances (pull_request) Successful in 5m55s
8a539dc318
Le rapport couvrait trois des attendus de l'épreuve — décisions révisées,
écart planning/réalisé, rituels. Les quatre autres manquaient : le RACI, la
méthode et le backlog, les jalons et la gestion des risques, les indicateurs
avec leur base de départ, et un compte rendu d'activité qui dise ce qui n'a
pas été livré.

Ajouté : RACI déduit des commits par zone et du CODEOWNERS, avec les deux
croisements de rôle assumés ; méthode Kanban, modèles de tickets et écart
assumé à la user story canonique ; les trois jalons et leur critère de
sortie ; les six indicateurs avec leur base de départ ; le registre des
risques, le risque n°1 de chaque journée et ce qu'il est devenu ; le CRA
adossé au procès-verbal de recette ; les incidents avec leur cause et leur
coût ; la montée en compétences mesurée par les rejeux de manuels.

Corrigé, tout étant remesuré au 09/09 à 21 h 30 :

- capacité de 40 à 44 jours-personne — la table du rapport en sommait 38, et
  aucune des deux branches ne produisait 40 ;
- écart estimation/capacité de +66 % à +70 %, les deux entrées étant fausses ;
- délai médian de 2 j à 1,2 j, plus long délai de #37 à #47 ;
- « 47 commits avant 9 h » à 7 : un tiers des commits sont horodatés en UTC,
  la table mélangeait deux fuseaux ;
- « vingt-six commits » le week-end à onze, ici et dans docs/journal.md ;
- treize fiches ADR à quatorze, dont huit portent une révision datée ;
- 90/70 tickets à 97/85, et la charge de 77 à 78,5 j.h dont 75,0 fermés.

Ref #48
front : l'import dupliqué de formaterJour ne tenait que par esbuild
All checks were successful
Intégration / Contrôles statiques du dépôt (pull_request) Successful in 9s
Intégration / Terraform — format, validité et lint (pull_request) Successful in 17s
Intégration / Tableau de bord — dépendances, tests et construction (pull_request) Successful in 45s
Intégration / Checkov — audit de la configuration (pull_request) Successful in 17s
Intégration / Workflows — lint et audit de sécurité (pull_request) Successful in 17s
Intégration / Python — qualité, tests et dépendances (pull_request) Successful in 6m16s
5f5f294564
`formaterJour` était importé deux fois dans le même bloc d'import. C'est
une SyntaxError au sens de la spec ESM — `node --check` refuse le fichier
avec « Identifier 'formaterJour' has already been declared ».

Les 510 cas passaient quand même parce qu'esbuild, qui transforme le
fichier avant Vitest, déduplique les spécificateurs en silence. Rien ne
cassait aujourd'hui ; le premier outil qui parse à la lettre — Rollup en
natif, un lint d'import, une bascule TypeScript — aurait fait tomber le
fichier entier, et avec lui les vingt-sept cas qu'il porte.
Merge pull request 'front : le tableau de bord affiche l'heure du poste, et le dit (#254)' (#254) from lenaic/heure-locale into develop
All checks were successful
Intégration / Contrôles statiques du dépôt (push) Successful in 9s
Intégration / Terraform — format, validité et lint (push) Successful in 31s
Intégration / Tableau de bord — dépendances, tests et construction (push) Successful in 50s
Intégration / Workflows — lint et audit de sécurité (push) Successful in 20s
Intégration / Checkov — audit de la configuration (push) Successful in 48s
Intégration / Python — qualité, tests et dépendances (push) Successful in 6m32s
c1d698bd04
Les horodatages de données s'affichaient en UTC : une relève de 19 h 59 se lisait « 17:59 » sur un écran parisien, et faisait conclure deux heures de retard sur une donnée fraîche de onze minutes.

Le module d'affichage convertit désormais dans le fuseau du poste, sauf la date nue du journal de collecte, qui nomme une journée et non un instant. Le fuseau est lu à l'exécution et écrit à côté de « dernière relève ». Le fuseau des cas d'essai est fixé à Europe/Paris, sans quoi la conversion ne serait jamais exercée.
Merge branch 'develop' into gabriel/117-tableau-derive
All checks were successful
Intégration / Contrôles statiques du dépôt (pull_request) Successful in 10s
Intégration / Terraform — format, validité et lint (pull_request) Successful in 17s
Intégration / Tableau de bord — dépendances, tests et construction (pull_request) Successful in 45s
Intégration / Checkov — audit de la configuration (pull_request) Successful in 17s
Intégration / Workflows — lint et audit de sécurité (pull_request) Successful in 22s
Intégration / Python — qualité, tests et dépendances (pull_request) Successful in 6m27s
6af9f5a039
Merge pull request 'supervision : la dérive du modèle se regarde, pas seulement s'alerte (#117)' (#253) from gabriel/117-tableau-derive into develop
Some checks are pending
Intégration / Python — qualité, tests et dépendances (push) Waiting to run
Intégration / Tableau de bord — dépendances, tests et construction (push) Waiting to run
Intégration / Contrôles statiques du dépôt (push) Waiting to run
Intégration / Terraform — format, validité et lint (push) Waiting to run
Intégration / Checkov — audit de la configuration (push) Waiting to run
Intégration / Workflows — lint et audit de sécurité (push) Waiting to run
2491a73205
Reviewed-on: https://10.105.200.41/g2/enervision/pulls/253
Reviewed-by: lenaic <lenaic@noreply.10.105.200.41>
Merge branch 'develop' into gabriel/48-rapport-ec02-completude
All checks were successful
Intégration / Tableau de bord — dépendances, tests et construction (pull_request) Successful in 47s
Intégration / Contrôles statiques du dépôt (pull_request) Successful in 9s
Intégration / Terraform — format, validité et lint (pull_request) Successful in 13s
Intégration / Checkov — audit de la configuration (pull_request) Successful in 14s
Intégration / Workflows — lint et audit de sécurité (pull_request) Successful in 18s
Intégration / Python — qualité, tests et dépendances (pull_request) Successful in 6m11s
5917db6b76
Merge pull request 'docs : le rapport EC02 porte le RACI, la méthode, les jalons, les risques et le CRA' (#255) from gabriel/48-rapport-ec02-completude into develop
Some checks failed
Intégration / Contrôles statiques du dépôt (push) Successful in 10s
Intégration / Tableau de bord — dépendances, tests et construction (push) Successful in 45s
Intégration / Terraform — format, validité et lint (push) Successful in 24s
Intégration / Workflows — lint et audit de sécurité (push) Successful in 20s
Intégration / Checkov — audit de la configuration (push) Successful in 45s
Intégration / Tableau de bord — dépendances, tests et construction (pull_request) Successful in 42s
Intégration / Contrôles statiques du dépôt (pull_request) Successful in 8s
Intégration / Terraform — format, validité et lint (pull_request) Successful in 14s
Intégration / Python — qualité, tests et dépendances (push) Successful in 6m27s
Intégration / Checkov — audit de la configuration (pull_request) Successful in 1m9s
Intégration / Python — qualité, tests et dépendances (pull_request) Successful in 6m4s
Intégration / Workflows — lint et audit de sécurité (pull_request) Failing after 16m9s
0be141f7ea
Reviewed-on: https://10.105.200.41/g2/enervision/pulls/255
Reviewed-by: lenaic <lenaic@noreply.10.105.200.41>
gabriel approved these changes 2026-09-09 20:45:47 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
g2/enervision!256
No description provided.