État partagé : le relevé de rythme passe dans la base SQLite (rythme.json) [t_af5f04d2] #1695

Closed
hermes-bot wants to merge 1 commit from hermes/migration-rythme-sqlite into main
Collaborator

Migration de _tableau/rythme.json (le relevé de fabrication, /opt/studio/rythme.json sur le 132) vers la base du service d'état, avec la recette de STUD-1107 : table rythme, comparaison avant bascule, .bak-sqlite-<date>, retour arrière en une commande.

  • Table rythme : une ligne par cellule du relevé (la date, les titres, les paragraphes, les tableaux), (section, ligne, colonne) pour clé. Aucun contenu du rapport dans une colonne JSON.
  • etat_partage.rythme_lire / rythme_remplacer (une transaction, tout ou rien, idempotent) ; _infra/etat-service.py : GET /rythme, POST /rythme/remplacer.
  • etat_client.py : basculer rythme [--essai], revenir rythme, chemin $ETAT_RYTHME. Pas de verrou de montage (le relevé n'a rien à voir avec le montage, qui tourne en continu).
  • Écriture double (socle.rythme_ecrire) : la base fait foi, et rythme.json reste la copie que pousser-rythme.sh recopie sur le 132, où l'onglet Rythme et /api/rythme le lisent.
  • Aucun champ d'/api/... ne change : les routes sont nouvelles, sur le service d'état ; le front n'est pas concerné.

Bancs : _tableau/test_rythme_bascule.py (nouveau), section 8 de controle/test_etat_partage.py (sur le vrai relevé du dépôt), les deux routes de _infra/test_etat_service.py. La bascule en production n'est pas faite : le service d'état du 130 est injoignable.

Migration de `_tableau/rythme.json` (le relevé de fabrication, `/opt/studio/rythme.json` sur le 132) vers la base du service d'état, avec la recette de STUD-1107 : table `rythme`, comparaison avant bascule, `.bak-sqlite-<date>`, retour arrière en une commande. - Table `rythme` : **une ligne par cellule** du relevé (la date, les titres, les paragraphes, les tableaux), `(section, ligne, colonne)` pour clé. Aucun contenu du rapport dans une colonne JSON. - `etat_partage.rythme_lire` / `rythme_remplacer` (une transaction, tout ou rien, idempotent) ; `_infra/etat-service.py` : `GET /rythme`, `POST /rythme/remplacer`. - `etat_client.py` : `basculer rythme [--essai]`, `revenir rythme`, chemin `$ETAT_RYTHME`. Pas de verrou de montage (le relevé n'a rien à voir avec le montage, qui tourne en continu). - Écriture double (`socle.rythme_ecrire`) : la base fait foi, et `rythme.json` reste la copie que `pousser-rythme.sh` recopie sur le 132, où l'onglet Rythme et `/api/rythme` le lisent. - Aucun champ d'`/api/...` ne change : les routes sont nouvelles, sur le service d'état ; le front n'est pas concerné. Bancs : `_tableau/test_rythme_bascule.py` (nouveau), section 8 de `controle/test_etat_partage.py` (sur le vrai relevé du dépôt), les deux routes de `_infra/test_etat_service.py`. La bascule en production n'est pas faite : le service d'état du 130 est injoignable.
État partagé : le relevé de rythme passe dans la base SQLite (rythme.json)
Some checks failed
Tests du tableau (Rust + Svelte) / Rust (_tableau/rust) (push) Successful in 21s
Tests du tableau (Rust + Svelte) / Front Svelte (_tableau/front) (push) Failing after 11s
Tests du tableau (Rust + Svelte) / Rust (_tableau/rust) (pull_request) Successful in 21s
Tests du tableau (Rust + Svelte) / Front Svelte (_tableau/front) (pull_request) Failing after 13s
813839621f
Motif. `_tableau/rythme.json` (le relevé de fabrication du studio, poussé sur le 132 par
`_tableau/pousser-rythme.sh`) vit hors de la base partagée, alors que douze fichiers d'état y passent un à
un depuis le 2026-10-14 (recette de STUD-1107). La carte « rythme.json » demande la même bascule, avec sa
comparaison et son retour arrière.

Remède.
- `etat_partage.sql` : table `rythme`, UNE LIGNE PAR CELLULE du relevé — la date du relevé (rang -1,
  genre « d »), puis les sections : un titre ou un paragraphe est une ligne d'une cellule, la ligne 0 d'un
  tableau est son en-tête et les suivantes son corps. `(section, ligne, colonne)` est la clé, l'ordre du
  fichier est gardé, et rien du rapport ne part dans une colonne JSON (règle commune du fichier). Le schéma
  refuse un genre inconnu, une date ailleurs qu'au rang -1, une cellule vide. `bascules.nom` n'est plus une
  liste fermée de noms mais un motif, et `_reparer_bascules` refait une base restée sur l'ancienne (SQLite
  ne modifie pas un CHECK).
- `etat_partage.py` : `rythme_lire`, `rythme_remplacer` (une transaction, tout ou rien, idempotent),
  `section_rythme` / `rythme_cellules`, qui REFUSENT en le nommant ce qui ne se range pas fidèlement
  (cellule qui n'est pas un texte, genre inconnu, tableau sans en-tête, clé de premier niveau inconnue).
- `_infra/etat-service.py` : `GET /rythme`, `POST /rythme/remplacer`. Routes nouvelles du service d'état :
  aucun champ d'`/api/...` ne change, le front n'est pas concerné.
- `etat_client.py` : `rythme()`, `rythme_remplacer()`, `basculer rythme [--essai]`, `revenir rythme`,
  chemin `$ETAT_RYTHME` (bancs). Cette bascule ne prend PAS le verrou de montage : le relevé n'a rien à voir
  avec le montage, et les montages tournent en continu — les attendre rendrait la bascule impossible (même
  règle que `reseaux-file`).
- `_tableau/socle.py` : `rythme_ecrire(releve, chemin)` écrit la base ET réécrit le fichier — la copie que
  `pousser-rythme.sh` recopie sur le 132, où l'onglet Rythme et `/api/rythme` le lisent encore. Service muet
  alors que la bascule est posée : le relevé n'est que dans le fichier, et c'est DIT (« fichier-muet »).
- `_travail/production/rythme.py` (le producteur) écrit par ce chemin et dit où le relevé fait foi.
- Bancs : `_tableau/test_rythme_bascule.py` (nouveau, de bout en bout contre un vrai service), section 8 de
  `controle/test_etat_partage.py` (sur le vrai relevé du dépôt : 12 sections, 71 cellules, copie identique),
  les deux routes dans `_infra/test_etat_service.py`. Doc : `OUTILS.md`, `_tableau/LXC-132.md`.

La bascule en production n'est pas faite : le service d'état du 130 est injoignable (curl /sante : délai
dépassé). `python3 etat_client.py basculer rythme --essai` puis `basculer rythme` sont à lancer sur la
machine du service.
hermes-bot force-pushed hermes/migration-rythme-sqlite from 813839621f
Some checks failed
Tests du tableau (Rust + Svelte) / Rust (_tableau/rust) (push) Successful in 21s
Tests du tableau (Rust + Svelte) / Front Svelte (_tableau/front) (push) Failing after 11s
Tests du tableau (Rust + Svelte) / Rust (_tableau/rust) (pull_request) Successful in 21s
Tests du tableau (Rust + Svelte) / Front Svelte (_tableau/front) (pull_request) Failing after 13s
to 08969da63f
All checks were successful
Tests du tableau (Rust + Svelte) / Rust (_tableau/rust) (push) Successful in 50s
Tests du tableau (Rust + Svelte) / Front Svelte (_tableau/front) (push) Successful in 15s
Tests du tableau (Rust + Svelte) / Rust (_tableau/rust) (pull_request) Successful in 24s
Tests du tableau (Rust + Svelte) / Front Svelte (_tableau/front) (pull_request) Successful in 15s
2026-10-15 01:31:40 +02:00
Compare
Collaborator

fusion-auto : pas de fusion, la PR est en conflit avec main : à rebaser. Le chef de l'atelier renvoie la carte à l'agent ; l'étiquette tombera d'elle-même une fois corrigé.

`fusion-auto` : pas de fusion, la PR est en conflit avec main : à rebaser. Le chef de l'atelier renvoie la carte à l'agent ; l'étiquette tombera d'elle-même une fois corrigé.
Author
Collaborator

Le rebasage de cette PR est fait et mesuré, mais la tete de cette PR ne peut plus etre ecrite sur la forge.

main 9331aac3 -> commit rebasé fa38f925 (11 fichiers en conflit, resolus a la main : etat_client.py, etat_partage.py, etat_partage.sql, _tableau/socle.py, controle/test_etat_partage.py, _infra/etat-service.py, _infra/test_etat_service.py, _tableau/LXC-132.md, OUTILS.md).

Mesures sur le commit rebasé :

  • python3 controle/test_etat_partage.py -> TOUT PASSE (code 0), 13 sections, dont « ok 12 : relevé de rythme — 71 cellules de 12 sections rangées » et « ok 13 : une base restée sur la liste fermée des noms de bascule est réparée » ;
  • _tableau/test_rythme_bascule.py, _tableau/test_atelier_bascule.py, _tableau/test_atelier_socle.py, _infra/test_etat_service.py -> code 0 ;
  • un correctif non prevu par la branche : controle/test_etat_partage.py attendait la liste exacte des tables d'une base ancienne sans rythme (l'ajout de la table par cette PR la rendait rouge) — rythme ajoutee a la liste.

Poussee refusee sur refs/heads/hermes/migration-rythme-sqlite, six fois (dont en force et en --force-with-lease) :

remote: error: cannot lock ref 'refs/heads/hermes/migration-rythme-sqlite': reference already exists
! [remote rejected] HEAD -> hermes/migration-rythme-sqlite (failed to update ref)

Ce n'est pas un droit d'ecriture : la meme poussee vers un nom neuf passe du premier coup, et une mise a jour en force d'une autre branche passe aussi (essais de controle, branche d'essai supprimee ensuite). Toute autre reference de ce depot s'ecrit normalement ; seule celle-ci refuse.

Le contenu rebasé est donc pousse sous le nom hermes/migration-rythme-sqlite-rebase (fa38f925, CI en cours au moment d'ecrire). Deux sorties possibles, au choix de l'operateur :

  1. supprimer puis recreer la reference cassee (bouton « supprimer la branche » de la forge, ou git update-ref -d sur le depot nu) : je repousse alors fa38f925 sur hermes/migration-rythme-sqlite et cette PR redevient fusionnable ;
  2. ouvrir une PR depuis hermes/migration-rythme-sqlite-rebase et fermer celle-ci.
**Le rebasage de cette PR est fait et mesuré, mais la tete de cette PR ne peut plus etre ecrite sur la forge.** `main` 9331aac3 -> commit rebasé **fa38f925** (11 fichiers en conflit, resolus a la main : `etat_client.py`, `etat_partage.py`, `etat_partage.sql`, `_tableau/socle.py`, `controle/test_etat_partage.py`, `_infra/etat-service.py`, `_infra/test_etat_service.py`, `_tableau/LXC-132.md`, `OUTILS.md`). Mesures sur le commit rebasé : - `python3 controle/test_etat_partage.py` -> `TOUT PASSE` (code 0), 13 sections, dont « ok 12 : relevé de rythme — 71 cellules de 12 sections rangées » et « ok 13 : une base restée sur la liste fermée des noms de bascule est réparée » ; - `_tableau/test_rythme_bascule.py`, `_tableau/test_atelier_bascule.py`, `_tableau/test_atelier_socle.py`, `_infra/test_etat_service.py` -> code 0 ; - un correctif non prevu par la branche : `controle/test_etat_partage.py` attendait la liste exacte des tables d'une base ancienne **sans** `rythme` (l'ajout de la table par cette PR la rendait rouge) — `rythme` ajoutee a la liste. Poussee refusee sur `refs/heads/hermes/migration-rythme-sqlite`, six fois (dont en force et en `--force-with-lease`) : remote: error: cannot lock ref 'refs/heads/hermes/migration-rythme-sqlite': reference already exists ! [remote rejected] HEAD -> hermes/migration-rythme-sqlite (failed to update ref) Ce n'est pas un droit d'ecriture : la meme poussee vers un nom neuf passe du premier coup, et une mise a jour en force d'une autre branche passe aussi (essais de controle, branche d'essai supprimee ensuite). Toute autre reference de ce depot s'ecrit normalement ; seule celle-ci refuse. Le contenu rebasé est donc pousse sous le nom **`hermes/migration-rythme-sqlite-rebase`** (`fa38f925`, CI en cours au moment d'ecrire). Deux sorties possibles, au choix de l'operateur : 1. supprimer puis recreer la reference cassee (bouton « supprimer la branche » de la forge, ou `git update-ref -d` sur le depot nu) : je repousse alors `fa38f925` sur `hermes/migration-rythme-sqlite` et cette PR redevient fusionnable ; 2. ouvrir une PR depuis `hermes/migration-rythme-sqlite-rebase` et fermer celle-ci.
Owner

Fermée : son contenu est déjà dans main.

Mesure du 2026-10-16 sur la base de fusion (merge-base) : 596 des 638 lignes ajoutées par cette branche existent déjà à l'identique dans main (93 %), dont l'intégralité de _tableau/test_rythme_bascule.py, _tableau/socle.py et _travail/production/rythme.py. Les 42 lignes restantes sont des commentaires et une entrée de OUTILS.md, couvertes par les migrations déjà fusionnées (#1683, #1685, #1770). Rien à reprendre : la branche peut rester en l'état.

Fermée : son contenu est déjà dans `main`. Mesure du 2026-10-16 sur la base de fusion (`merge-base`) : 596 des 638 lignes ajoutées par cette branche existent déjà à l'identique dans `main` (93 %), dont l'intégralité de `_tableau/test_rythme_bascule.py`, `_tableau/socle.py` et `_travail/production/rythme.py`. Les 42 lignes restantes sont des commentaires et une entrée de `OUTILS.md`, couvertes par les migrations déjà fusionnées (#1683, #1685, #1770). Rien à reprendre : la branche peut rester en l'état.
foXaCe closed this pull request 2026-10-16 17:53:24 +02:00
All checks were successful
Tests du tableau (Rust + Svelte) / Rust (_tableau/rust) (push) Successful in 50s
Tests du tableau (Rust + Svelte) / Front Svelte (_tableau/front) (push) Successful in 15s
Tests du tableau (Rust + Svelte) / Rust (_tableau/rust) (pull_request) Successful in 24s
Tests du tableau (Rust + Svelte) / Front Svelte (_tableau/front) (pull_request) Successful in 15s

Pull request closed

Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
3 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
foXaCe/studio!1695
No description provided.