Recommandations — moteur générique de règles chargées sans redéploiement #116
Labels
No labels
Compat/Breaking
EC01
EC02
EC03
EC04
EC05
EC06
Kind/BDD
Kind/Back
Kind/Bug
Kind/CICD
Kind/Cloud
Kind/Contenu
Kind/Data
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Front
Kind/IA
Kind/Infra
Kind/Monitoring
Kind/Security
Kind/Testing
Portée/Post-jury
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
ops/alerte
No project
No assignees
2 participants
Notifications
Due date
Dependencies
No dependencies set
Reference
g2/enervision#116
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Issu de la réduction de périmètre du 03/09 (voir
docs/BACKLOG.md, §« Réductions de périmètre assumées », décision 1).Contexte. Pour la fenêtre du 11/09, #39 est réduit à trois règles écrites dans le code. Ce ticket porte le reste : un moteur générique.
Ce qu'il faut faire.
Critères d'acceptation.
Exigence couverte : EF-09. Épreuve : EC06. Hors fenêtre (
Portée/Post-jury).Vérification :
tests/unit/test_moteur_regles.py, joué parpytest tests/unit/test_moteur_regles.py -v.Développé le 09/09, demande de fusion #241. Le ticket reste
Portée/Post-jury: la décision du 03/09 n'est pas rouverte par ce développement, la fusion est une décision d'équipe.Les trois critères d'acceptation
« Une règle ajoutée au fichier de règles est prise en compte sans redémarrage du service. »
Le job tourne en cron à
:45, donc chaque passe est un processus neuf qui relit le fichier. Éprouvé aussi une couche plus bas — deux chargements successifs dans la même instance voient bien deux jeux différents, donc rien n'est mémorisé au niveau du module (test_une_regle_ajoutee_au_fichier_est_prise_en_compte_sans_redemarrage). La désactivation par retrait du fichier est couverte par le cas voisin.Relevé sur le serveur, en pointant le lanceur sur un fichier posé à la main, sans rien redémarrer :
« Chaque recommandation émise cite la règle et les valeurs qui l'ont déclenchée. »
Acquis au #154 et conservé au caractère près, ce qui était le vrai risque de ce ticket.
tests/unit/rules/verdicts-de-reference.jsonporte les 84 verdicts produits par les trois classes Python sur 28 observations couvrant chaque branche, capturés avant leur retrait puis confrontés aux mêmes classes extraites dedevelop: aucun écart. Message, action, gravité, valeurs déclenchantes et motif d'indécision sont comparés à l'identique.« Le jeu de règles actif est horodaté et traçable à une version. »
Migration
0021:jeu_versionetjeu_empreintesurpublic.recommandation. La version est déclarative donc faillible ; l'empreinte est un sha-256 des octets lus. Jouée surenervision_prod— 11 lignes réelles — en transaction annulée :Rejeu vérifié dans la même transaction :
UPDATE 0, aucune contrainte dupliquée.Vérification
pytest tests/unit/rules/(le ticket annonçaittests/unit/test_moteur_regles.py; tout l'existant vit danstests/unit/rules/depuis le #153, la convention l'emporte).Rejoué sur le serveur en Python 3.12, le venv du poste n'ayant aucune dépendance applicative :
ruff,
ruff format, mypy--strict, shellcheck, yamllint, ansible-lint (profilproduction) propres. Suite complète du dépôt : mêmes 5 échecs et 149 erreurs quedevelopavec le même venv — aucune régression.Ce qui n'était pas dans le ticket et a été fait
docs/runbooks/recommandations.md: il n'existait pas de manuel pour ce service. Modifier une règle, la vérifier avant de partir, lire un code 5, savoir quel jeu a produit quoi. Chaque commande a été exécutée sur le serveur.docs/data/etl-pipeline.mdne listait pas cette passe, alors que le lanceur y renvoie pour sa cadence. Corrigé, et la minute du lanceur avec : son commentaire annonçait:37derrière un chargement à:27, deux chiffres périmés depuis le passage au quart d'heure (#206). La crontab réelle porte:45.Réserve
Modifier une règle demande
sudosur le serveur : le fichier estroot:deploy 0640, comme les quatre fichiers voisins. « Sans redéploiement » n'est donc pas « sans droits » — c'est le prix de l'auditabilité, et il est assumé dans l'ADR. À dire si quelqu'un attendait une édition libre.