Files
decision/actes/2026-11-03-m7-lecteur.md
T

210 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Acte — Mise en ligne M7 (le lecteur refait, lot U)
Classe : déploie
Projet : libreDecision Date : 2026-11-03
**État : EN PRÉPARATION** sur `b2e597b` (`b2e597b65356cac14fbffdbf33318d620940b6f3`) — préparé par
l'intégrateur libredecision-d4 ; exécuté par orch (dev-63) sous son mandat (« déploie » et « pousse », du
03/11 au 08/11). Relecture indépendante : en cours (lancée le 03/11 à 09 h 05).
## Intention
Mettre en ligne le lot U, la réponse à la revue d'Yvv du 02/11 (registre, revue en ligne de M5) :
« Améliore l'ux : la page est trop longue, trop fournie et on ne comprends pas tout de suite. » ;
l'ordonnancement « en fin de section, qui ajoute des "poignées" aux modules de la section. Et permette de
voter. » ; « distingue avec habileté les différentes nature des modules » ; pas de redondance entre
« consoles locales » et celles du bas ; « la distinction entre un déplier façon toggle et un menu qui
ouvre à droite doit être pertinente » ; « Simule le vote à tout endroit. ». Avec l'ajout du 02/11 à
06 h 26 : « combien il faut de oui pour passer et combien de non pour maintenir l'opposition ».
## Ce qui part
Version `b2e597b`, qui contient la version en ligne `bb4bdf5`. **L'interface seule** : `web/` (lecteur,
composants `OrderLine`, `Reorder`, `QuorumSetting`, `Crans`, chaînes fr, en, es, contrôles C35 à C37) ;
le reste est documentation (`CLAUDE.md`, `HANDOFF.md`, actes, ADR, `CONTROLES.md`, `UX-lecteur.md`,
tableau). `git diff bb4bdf5 b2e597b -- crates seeds docker .woodpecker .env data` → **vide** (vu par
l'intégrateur et par orch le 03/11 à 08 h 49) : le serveur est celui qui est en ligne.
## Ce que l'acte écrit dans la base de production (donnée runtime)
**Rien.** Aucune migration, aucun amendement, aucun code serveur nouveau. Au démarrage, comme à chaque
démarrage depuis M6, la file de publication suspendue reporte ses 7 lignes (`next_at`).
## Répétition
**Faite le 03/11 de 08 h 56 à 08 h 57**, avec le serveur de `b2e597b` (binaire de la boucle, copié en
`m7/ld-server-b2e597b`), sur une copie de la copie de production prise par orch à 08 h 49 min 02 (santé
`bb4bdf58`), publication vers un dépôt nu local (`m7/repetition.sh` ; journal `m7/repetition-m7.log`,
scratchpad de l'intégrateur). Deux démarrages.
- `m7/counts.sh` avant, après le premier démarrage, après le second : **identiques** (migrations 1–11,
1 identité, 0 vote, 0 bulletin, 0 signalement, propositions `inertia/withdrawn:3 order/in_force:16
text/open:70 title/in_force:2`, 113 révisions, 144 traductions, `seed_amendments` 16, quorums par cran,
I1, E1, E2 au cran 2 sans texte en vigueur, file 7 en attente et 13 faites).
- **La base entière comparée** (`.dump`, 868 lignes avant et après) : seules changent les 7 lignes de la
file en attente, par leur `next_at` (la publication suspendue les reporte à chaque démarrage, comme
depuis M6).
- Journal : « publication suspended … waiting=7 », aucun amendement, aucune ligne ERROR ni WARN ; 0 commit
vers le dépôt des textes.
## Recette écran
**Faite le 03/11 de 09 h 00 à 09 h 03**, sur deux autres copies de la copie de 08 h 49 : l'interface de
`b2e597b` (« après ») et celle de `bb4bdf5`, en ligne (« avant », construite dans une copie de travail
jetable), servies par le même serveur, connexion de développement (identités `dev:` écrites dans ces
copies seulement). Bureau 1360 × 900 et téléphone (Pixel 7), `fr-FR`. Script `m7/recette.mjs`, rapports
`m7/shots/avant-rapport.json` et `m7/shots/apres-rapport.json` : 38 étapes, 0 échec. Captures, toutes dans
`/tmp/claude-1001/-home-yvv-Documents-PROD-DEV-libreDecision/d0a7108b-7f2f-484a-bcb0-de339238199d/scratchpad/m7/shots/`,
regardées une à une.
La revue d'Yvv du 02/11, ligne par ligne :
1. **« la page est trop longue, trop fournie et on ne comprends pas tout de suite »**
- Hauteur de la page d'un membre, Monnaie libre, mêmes données : **6 079 → 2 529 px** sur bureau,
**6 744 → 3 365 px** sur téléphone.
- Premier écran : avant, « Aucun article n'est en vigueur. Les propositions ci-dessous remontent… »
puis les blocs « Ordre des articles » ; après, « Aucun article n'est encore en vigueur. Commence par
les Propositions seed… », puis Raison d'être avec la marque « Proposition seed », Unicité du compte,
Réciprocité, puis « Propositions en cours » repliées par section (« Tout déplier », « Voter cette
section »).
- Captures `avant-*-membre-ml-ecran.png` et `-page.png`, `apres-*-membre-ml-ecran.png` et `-page.png`,
`geste-*-3a-propositions-repliees.png`, `geste-*-3b-propositions-depliees.png`.
2. **« la répétition de "ordonnancement" est nulle. […] en fin de section, qui ajoute des "poignées" aux
modules de la section. Et permette de voter. »**
- Avant : sept blocs « Ordre des articles · <section> » en tête (Introduction à Inertie), chacun
répétant la liste de ses articles. Après : aucun ; une ligne « Ordre de la section » au bout de chaque section.
- « Réordonner » sur Engagements techniques : 11 articles, 11 poignées, sur place (le panneau reste
fermé) ; un article monté, « Proposer cet ordre », le vote se déplie à la ligne, « Pour » → « Vote
simulé. », la ligne dit « 1 ordre proposé ».
- Captures `geste-*-5a-ligne-ordre.png`, `-5b-poignees.png`, `-5c-ordre-vote-simule.png`.
3. **« distingue avec habileté les différentes nature des modules : les textes ; l'inertie ;
l'odonnancement »**
- Texte : la carte de l'article. Inertie : les crans dessinés (cinq barres, « basse ») sur la carte, et
« Inertie · 2 / 5 · basse » dans le vote déplié. Ordre : l'icône poignée et « Ordre de la section ».
Titre du document : « Titre du document · seed a minima · 0 vote », crans « inertie 4 / 5 · haute »,
« Le vote », « Proposer un autre titre », sous le titre.
- Captures `apres-*-ecran.png`, `geste-*-6-titre.png`.
4. **« vérifie qu'il n'y a pas de redondance entre les "consoles locales" et celles du bas »**
- Vote déplié et panneau ouvert : 15 titres visibles, **0 doublon** (étape 8, bureau et téléphone).
Le panneau n'a plus d'onglets, il porte un titre : « Panier de vote », « Réglages de la formule ».
- Captures `geste-*-7a-panneau-panier.png`, `geste-*-9-panneau-reglages.png`.
5. **« la distinction entre un déplier façon toggle et un menu qui ouvre à droite doit être
pertinente »**
- La règle (`UX-lecteur.md`) : sur place, ce qui se lit et se décide sur un article (le vote, l'ordre
de sa section, le titre) ; à droite, ce qui travaille sur plusieurs articles ou demande de la place
(panier, réglages, détails, proposer). Vue : vote d'une proposition depuis la liste et vote d'un
ordre, panneau fermé (étapes 4 et 5) ; « Voter en lot » et « Réglages de la formule » ouvrent le
panneau.
6. **« Simule le vote à tout endroit. »** et le tampon (« je vois ce que j'ai fait sans attendre »)
- Monnaie libre (chaîne fermée) : sur une Proposition seed, une proposition de la liste, un ordre,
chaque « Pour » donne « Vote simulé. » ; aussitôt « Ton vote : pour · simulé », « 1 pour · 0 contre
dont 1 simulé », la note « tant qu'une décision humaine n'efface pas les votes simulés » ; la marque
« vote simulé » près de « Voter en lot ». « Vote enregistré. » : jamais vu.
- Groupe d'essai (vote sur le serveur) : le vote est enregistré, pas simulé, comme il se doit.
- Captures `geste-*-1-seed-vote-deplie.png`, `-2-seed-vote-simule.png`, `-4-proposition-vote-simule.png`,
`-11-essai-vote.png`. Les captures 4 et 5c de la première passe avaient été prises pendant la requête
(boutons grisés, « Tu n'as pas voté ») : **reprises le 03/11 à 09 h 22-09 h 23** sur une nouvelle
copie, après la réponse du serveur (« Ton vote : pour · simulé », « 1 pour · 0 contre dont 1
simulé », panneau fermé ; `m7/recette-reprise.mjs`, `shots/reprise-rapport.json`, 6 étapes, 0 échec).
7. **L'ajout du 02/11 à 06 h 26, « combien il faut de oui pour passer et combien de non pour maintenir
l'opposition »**
- Avant tout vote : « 9 oui sur 12 votants pour passer » (Propositions seed, cran 2), le quorum dans
l'infobulle (« Quorum : 12 votants. En dessous, les votants qui manquent comptent comme « non ». ») ;
dans la liste, « 9 oui sur 12 » et « 39 oui sur 50 » (cran 3). Après un vote : « 9 oui pour passer ·
le quorum la bloque », « Il manque 8 voix pour. ». Essai : « 1 oui sur 1 votant pour passer ».
- **Le quorum de l'auteur** (corrigé après la relecture, voir prémisse 3) : la seule identité de la
production est **administratrice** (une invitation). Or l'administrateur fixe le quorum d'un texte du
seed tant que personne n'y a voté (décision d'Yvv du 02/11, registre : « L'auteur, avant le 1er vote
», un administrateur pour les textes du seed ; `trustin_access::sets_quorum`, ADR 0013). Sur les
données de production, `canSetQuorum` est donc **vrai sur les 33 articles pour l'administrateur**
(vu par le relecteur sur une copie fraîche ; 32 sur ma copie de reprise, où un vote de test venait
d'en fermer un) et faux pour un membre (étape 10). Après M7, chaque vote déplié lui montre « Quorum ·
12 votants », un champ et « Fixer ce quorum » : **un geste qui écrit** dans la base de production
(`units.quorum`, `quorum_changes`). La route est ouverte depuis M6 ; M7 la rend visible. Captures
`geste-bureau-12-admin-quorum.png`, `geste-telephone-12-admin-quorum.png` (reprise du 03/11 à 09 h 23,
le bouton jamais cliqué). L'auteur d'un nouvel article : prouvé par C37 sur une base de test.
Vu en passant, **pas du lot U, déjà en ligne** :
- « 0 contre » collé à « dont 1 simulé » (« 0 contredont 1 simulé ») : l'espace avant la marque se perd
(`VoteFold.svelte:163`, lot V, `d57326d`, en ligne depuis M6) → lot T2 ;
- la note d'inertie du vote déplié, « plus il faut de voix pour changer ce texte quand peu de gens
votent », a l'imprécision relevée sur F1.1 → lot T2 ;
- le bas du menu latéral (langues, ambiances) touche le bord droit : liste d'attente (vu par H).
- Le serveur de recette signale une fois « web of trust size: no node nor indexer answered, keeping the
last value » : pas de réseau vers les nœuds dans la recette.
## Effet attendu
- Le lecteur d'un document change pour tout le monde (les deux groupes, fr, en, es) ; les données, les
votes, les textes et la publication ne changent pas à la mise en ligne.
- **Un geste d'écriture apparaît pour l'administrateur** (Yvv) : sur chacun des 33 articles, tant que
personne n'y a voté, le réglage du quorum dans le vote déplié (« Fixer ce quorum », « Revenir au
défaut »). Il écrit `units.quorum` et `quorum_changes` quand on s'en sert. Voulu (décision d'Yvv du
02/11) ; à lui dire.
- Le dépôt des textes reste à `9e0f45a`.
Irréversibilité : **aucune** côté données ; le code se remet en arrière.
## Avant — prémisses vivantes
1. La production sert `bb4bdf5` : santé `"build":"bb4bdf58"` ; `prod/main` → `bb4bdf5`.
2. `git diff bb4bdf5 b2e597b -- crates seeds docker .woodpecker .env data` → vide.
3. La relecture indépendante de `b2e597b`, inscrite « ok » dans `~/harness/etat/relectures.json`.
**Première relecture** (sous-agent neuf, lancée à 09 h 05, rendue à 09 h 22) : « b2e597b : à reprendre
», **le dossier, pas le code** (« Le code peut partir tel quel »). Aucun bloquant.
- À reprendre : le dossier disait que personne ne règle le quorum sur les données de production ;
l'administrateur, seule identité, le peut sur les 33 articles. **Corrigé** (recette, point 7 ; Effet
attendu), captures de l'administrateur jointes.
- Ce qu'elle a vérifié de son côté : `needOf` reprend `yesNeeded` / `noNeeded` du serveur sans rien
recalculer ; réglage du quorum seulement si `canSetQuorum` ; le vote simulé jamais dit « enregistré »
(« Voter cette section » sur Conclusion : « 3 votes simulés. ») ; objections, coquilles, panier,
chaîne simulée, réglages tenus ; anciennes adresses `?onglet=` ; en et es sur téléphone sans reste de
français ni défilement ; ambiances sombres, mouvement réduit ; boucle web 0 / 0, 64 / 64, build ; e2e
38 / 40 puis 40 / 40 (C1, C2 hors délai une fois sous charge, `reader.spec.ts` seul 15 / 15) ; sa
propre répétition (`.dump` : seules les 7 dates de reprise de la file) ; le retour.
- Mineurs, **liste d'attente** (lot U2 proposé) : deux captures prises trop tôt (reprises) ; cibles de
36 px sur téléphone (« Tout déplier » `DeepList.svelte:225`, « Autres versions » `VoteFold.svelte:345`,
« Fixer ce quorum » `QuorumSetting.svelte:64`) ; « Si tout pa » coupé sur téléphone, sans indice de
défilement (`+page.svelte:525`) ; « Proposer cet ordre » éteint sans dire pourquoi
(`Reorder.svelte:196`, `order.edit.unchanged` jamais affiché) ; redites dans le vote déplié
(l'inertie deux fois, la ligne d'une Proposition seed au-dessus de son vote, l'autre version deux
fois) ; « N propositions en cours » compte les ordres ; un changement d'inertie proposé sur un ordre
ou le titre absent de « Propositions en cours » (aucun ouvert en production).
- Non vérifié par elle : la production (dont l'absence du marqueur `deploying`), la chaîne réelle, le
doigt sur un vrai téléphone, un lecteur d'écran, Firefox et Safari. Ses copies de la base de
production sont supprimées.
4. Boucle verte sur `b2e597b`, le 03/11 (journaux `m6/loop-m7.log`, `m7/e2e-c25.log`, `m7/e2e-all.log`) :
- de 08 h 48 à 08 h 55 : fmt, clippy `-D warnings`, 294 tests Rust, svelte-check 0 / 0, 64 vitest,
build ; e2e 39 / 40, **C25 (chaîne Ğ1 et téléphone) hors délai à 1,5 min**, la machine à une charge
de 11 à 12 (les sessions HCO) ;
- à 08 h 55, `modules.spec.ts` seul : 4 / 4, ce C25 en 7,3 s ;
- de 08 h 56 à 08 h 59, **la suite e2e complète : 40 / 40**.
Image de production construite le 03/11 de 09 h 00 à 09 h 01, sortie 0 : l'étage serveur repris du
cache (code inchangé depuis `bb4bdf5`, dont l'image a rejoué les tests Rust à 07 h 48) ; l'étage web
rejoué (svelte-check 0 / 0, 64 vitest, build). Image de contrôle retirée à 09 h 01.
## Commande exacte
```sh
cd /home/yvv/Documents/PROD/DEV/libreDecision
git push prod b2e597b65356cac14fbffdbf33318d620940b6f3:main
```
## Vérifications après
- [ ] Santé vue de l'extérieur → `"build":"b2e597b6"`.
- [ ] Journaux : « publication suspended … waiting=7 », aucune ligne ERROR ni WARN, aucun amendement.
- [ ] La page d'un document, vue de l'extérieur, sert la nouvelle interface (le paquet JS contient
« Réordonner » et « oui pour passer »).
- [ ] Sur une copie fraîche : comptes de `m6/counts.sh` identiques à la copie d'avant ; `integrity_check`
ok.
- [ ] Le dépôt des textes reste à `9e0f45a`.
## Retour
`docker tag libredecision-app:previous libredecision-app:latest`, puis
`cd /opt/libredecision-app && docker compose up -d --force-recreate`. `previous` sera `bb4bdf5`, le même
serveur, qui attend aussi le premier texte pour publier : rien à couper, aucune donnée à reprendre.
## Exécution
(à remplir par orch)