17 KiB
Acte — Mise en ligne M8 (aucun chiffre daté dans les textes votés, lots T3 et T3b)
Classe : déploie
Projet : libreDecision Date : 2026-11-03
État : PRÉPARÉ, non figé (en attente de la relecture indépendante de e7ab82f) — sur e7ab82f
(e7ab82f48f41f52b3f31e322553f7cf18bc21601) ; 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).
Pour Yvv : ce que tu liras de changé
Quatre phrases, avant / après (le français fait foi), et un exemple retiré. Toutes dans les textes votés de départ, dans les deux groupes ; F1.1 n'est pas touché.
- N1.1, la phrase du quorum (premier paragraphe) :
- avant : « Chaque cran a aussi son quorum, qui n'est pas un nombre minimal de votants : sous le quorum, les votants qui manquent comptent comme « non ». »
- après : « Chaque cran a aussi son quorum : sous le quorum, les votants qui manquent comptent comme « non », et il faut autant de « pour » que si le quorum avait voté. »
- N1.1, l'introduction des cinq crans :
- avant : « Les cinq crans : le quorum dans Monnaie libre, la part exigée quand le groupe vote comme d'habitude, puis quand tout le monde vote, et ce qui est à ce cran au départ. »
- après : « Les cinq crans : le quorum dans Monnaie libre, la part exigée au-delà du quorum, quand le groupe vote comme d'habitude, puis quand tout le monde vote, et ce qui est à ce cran au départ. »
- N1.1, la phrase de G (dernier paragraphe) :
- avant : « G se calcule pour que la part exigée, à la participation habituelle, soit exactement celle
du cran :
G = ln(1 − (s − M)/(1 − M)) / ln(p̃), où s est la part exigée comme d'habitude et p̃ la participation habituelle divisée par W. » - après : « G se calcule pour que la part exigée, au-delà du quorum, soit exactement celle du cran
quand le groupe vote comme d'habitude :
G = ln(1 − (s − M)/(1 − M)) / ln(p̃), où s est cette part du cran (60, 67, 75, 83 ou 90 %) et p̃ la participation habituelle divisée par W. »
- avant : « G se calcule pour que la part exigée, à la participation habituelle, soit exactement celle
du cran :
- F1.2, « Par défaut » :
- avant : « Le cran par défaut est le 3 (moyenne) : M = 55 %, un quorum de 50 dans Monnaie libre, et le groupe demande 75 % de « pour » quand il vote comme d'habitude. Tout nouvel article commence à ce cran. »
- après : « Le cran par défaut est le 3 (moyenne) : M = 55 %, un quorum de 50 dans Monnaie libre, et, au-delà du quorum, le groupe demande 75 % de « pour » quand il vote comme d'habitude. Tout nouvel article commence à ce cran. »
- N1.1, l'exemple retiré (le paragraphe qui suivait la phrase de G ; rien ne le remplace) : « Exemple : avec 7 224 membres et une participation habituelle de 120 votants, quand 120 personnes votent, il faut 72, 81, 90, 100 ou 108 voix pour, du cran 1 au cran 5 ; au cran 3, 75 % des 120 votants, soit 90. Sous le quorum, les absents comptent comme « non » : au cran 2 (quorum 12), 9 voix pour passent avec 3 « contre » au plus ; au cran 3 (quorum 50), il faut 39 voix pour, avec 11 « contre » au plus. »
Pourquoi.
- L'exemple (5) : ta décision du 03/11, aucun chiffre daté dans un texte voté. 7 224 membres et 120 votants sont un état de la toile et une participation d'une date ; ce qui en était calculé sort avec eux.
- La phrase du quorum (1) : « pas un nombre minimal de votants » est faux pour un quorum bas fixé par l'auteur. Au quorum 2 (le plus bas dans Monnaie libre), il faut 2 « pour », à tout cran et sur toute toile : le quorum y est bien un minimum. La phrase nouvelle est vraie pour tout quorum : sous le quorum, le moteur demande exactement le seuil du quorum. « autant de « pour » » plutôt que « autant de voix pour », qui se lisait d'abord « pour que ».
- Les phrases 2, 3 et 4 disaient la part du cran « comme d'habitude » sans condition. C'est faux quand la
participation habituelle reste sous le quorum : le groupe est alors jugé sur le quorum. Exemple : une
toile de 3 000 membres dont la participation habituelle est de 40 votants (dans les bornes : 1 % de
3 000, c'est 30), au cran 3, quorum 50 : la courbe donne 75 % à 40 votants, mais la part exigée se calcule
sur 50 (74,2 %), et il faut 38 « pour » de ces 40 votants, soit 95 %, pas 75 %. Cela arrive dès que la
toile passe sous 5 000 membres avec une participation habituelle sous 50, ou quand l'auteur d'un article
fixe un quorum au-dessus de la participation habituelle. Les phrases 2 et 4 ont été trouvées par le lot
T3 ; la phrase 3 par la relecture indépendante de T3 («
2ce2028: à reprendre »), reprise par le lot T3b. Accord d'orch sur les trois (03/11, à 17 h 46, puis en réponse à mon message de 18 h 13).
Les preuves, phrase par phrase, et les textes entiers en fr, en, es :
docs/chantiers/acte-certification/textes-quorum-seed.md, section « Lot T3 » (avec « Après la relecture
de 2ce2028 »).
Intention
Mettre en ligne les lots T3 et T3b. Yvv, le 03/11 avant 16 h 56, mot pour mot : « Je valide
textes-quorum-seed (dont le point 3, pas de chiffre datés dans un texte voté). Tu peux lancer la livraison
de decision. » (registre ~/harness/etat/reponses-yvv.md, commit 9b701da). Ordre T3 d'orch (dev-63, 03/11
vers 16 h 57) : retirer des textes votés F1.1, F1.2, N1.1 (fr, en, es ; deux groupes) tout chiffre qui
dépend de l'état de la toile ou d'une participation à une date ; le texte reste vrai pour tout W ; la phrase
de N1.1 « pas un nombre minimal de votants », fausse pour un quorum d'auteur bas, écrite vraie. Points 1, 2,
4 et 8 de textes-quorum-seed.md : le défaut reste.
en et es (fidèles au français) :
- 1 : « Each level also has its quorum: below the quorum, the voters who are missing count as votes against, and it takes as many votes in favour as if the quorum had voted. » ; « Cada nivel tiene además su quórum: por debajo del quórum, los votantes que faltan cuentan como «no», y hacen falta tantos votos a favor como si hubiera votado el quórum. »
- 2 : « the share asked beyond the quorum, when the group votes as usual » ; « la proporción exigida más allá del quórum, cuando el grupo vota como de costumbre ».
- 3 : « G is computed so that the share asked, beyond the quorum, is exactly that of the level when the
group votes as usual:
G = …, where s is that share of the level (60, 67, 75, 83 or 90%) and p̃ the usual turnout divided by W. » ; « G se calcula para que la proporción exigida, más allá del quórum, sea exactamente la del nivel cuando el grupo vota como de costumbre:G = …, donde s es esa proporción del nivel (60, 67, 75, 83 o 90 %) y p̃ la participación habitual dividida por W. » - 4 : « and, beyond the quorum, the group asks for 75% of votes in favour when it votes as usual » ; « y, más allá del quórum, el grupo pide un 75 % de votos a favor cuando vota como de costumbre ».
Les preuves (tests de crates/ld-server/tests/seed_quorum_texts.rs) :
- aucun chiffre daté :
every_number_of_the_quorum_texts_is_the_engine_sn'admet que des paramètres (vu rouge sur les textes de T2) ; « 100 votants » y est dit pour ce qu'il est, deux fois le quorum de référence, etthe_reference_turnout_is_a_parameter_the_bounds_bring_backmontre que les bornes le ramènent hors de 200 à 10 000 membres ; - 1 :
under_the_quorum_it_takes_as_many_for_as_if_the_quorum_had_voted, plus de 500 000 cas (W de 100 à 10 000 000, chaque quorum de la borne basse à W, les cinq crans, quatre participations, le groupe d'essai) ; - 2 et 4 :
the_share_of_a_level_as_usual_is_asked_beyond_the_quorum; - 3 :
g_gives_the_share_of_the_level_beyond_the_quorum_when_the_group_votes_as_usual(même grille ; G tel qu'écrit égale celui du moteur ; s au-delà du quorum, plus bas en dessous ; le cas 3 000 / 40 en dur) ; - F1.1 laissé :
b_to_the_power_w_never_counts_in_the_web_of_trust(« B^W ne compte pas », de 100 à 10 000 000 membres).
Ce qui part
Version e7ab82f (lots T3 et T3b), qui contient la version en ligne 6f6197c. Code touché : crates/ld-server/src/seed_amend.rs
(les deux amendements), crates/ld-server/src/wot.rs (une constante rendue publique pour les tests, valeur
inchangée), seeds/acte-engagement-certification.json (bases neuves), des tests et une fixture
(tests/fixtures/seed-quorum-t2.json, les textes de T2) ; le reste est documentation. web/ et
crates/ld-engine : rien. Configuration (docker/, .woodpecker/, .env, data/) et migrations : rien
(prémisse 4).
Ce que l'acte écrit dans la base de production (donnée runtime)
- Aucune migration.
- Amendement de seed gardé
2026-11-03-f1-2-chiffreset2026-11-03-n1-1-chiffres, qui suivent (follows) ceux de T2 (2026-11-03-f1-2-phrases,-n1-1-phrases), décidé une fois par document, dans une transaction, seulement si personne n'a touché l'article : 0 vote (simulé compris), 0 ligne de bulletin, aucune coquille, traduction de membre ni objection, texte d'avant identique à l'empreinte posée par T2 (F1.296caf353…, N1.17fbedcb8…) ; textes d'après : F1.2ddce5aa5…, N1.17f62fd42…; F1.2 et N1.1 admis à la révision 4 seulement si ce sont les amendements suivis (M5, M6b, M6c), et eux seuls, qui l'ont écrite.proposals: texte fr, révision + 1 (F1.2 et N1.1 → 5) ;revisions: une ligneamendment;translations: en et es remplacés ;seed_amendments: la décision ;outbox: une ligne par article dans Monnaie libre, qui attend (publication suspendue) ; rien pour l'essai. Refus possibles, le texte d'avant reste :not_a_seed,no_open_version,voted_into_force,confirmed,votes,ballots,corrected,translation_edited,signalled,revised,text_differs,changed.
- Les amendements de T2 sur F1.2 et N1.1 sont marqués dépassés : ils ne décident plus rien.
- F1.1 n'est pas touché. Aucun vote, aucune autre proposition, aucun autre article n'est touché ; la publication reste suspendue.
Répétition
Faite le 03/11 de 18 h 54 min 44 à 18 h 55 min 28, réseau coupé (unshare -rn, boucle locale seule :
m8/repetition-isolee.sh), avec le serveur de e7ab82f (binaire de la boucle, construit à 18 h 54, copié en
m8/ld-server-e7ab82f), sur une copie (18 h 47 min 52) de la copie de production prise par orch de
17 h 46 min 22 à 17 h 46 min 30 (production sur 6f6197cc), publication vers un dépôt nu local (journal
m8/repetition-m8b.log, scratchpad de l'intégrateur). Deux démarrages. Orch comparera les comptes de la
production à ceux de cette copie avant de pousser.
| Avant | Après | |
|---|---|---|
| F1.1 (deux groupes) | ouverte, seed, révision 3, 0 vote, 0 bulletin | inchangée |
| F1.2, N1.1 (deux groupes) | ouvertes, seed, révision 4, 0 vote, 0 bulletin | révision 5 |
| Révisions | 119 | 123 |
| Traductions | 144 | 144 (en, es des deux articles remplacés) |
seed_amendments |
22 | 26 |
| File de publication (Monnaie libre) | 10 en attente, 13 faites | 12 en attente, 13 faites |
| Commits vers le dépôt des textes (local) | — | 0 (« publication suspended … waiting=12 ») |
Tout le reste (m8/counts.sh : migrations 1–11, propositions, unités en vigueur, I1/E1/E2, inertia_changes, votes, bulletins, signalements, identités, quorums) |
identique |
La base entière comparée (.dump, et colonne par colonne) : changent exactement les 4 propositions de
F1.2 et N1.1 (body, revision, updated_at : ff53cbdc, 13ee215f dans Monnaie libre, e7ae6bcb,
d75f7e90 dans l'essai), leurs 8 traductions en et es (body, source_hash, updated_at), 4 révisions et
4 décisions ajoutées, 2 lignes de file ajoutées et les 10 lignes en attente reportées (next_at), les deux
compteurs (sqlite_sequence : révisions 123, file 25). Rien d'autre (settings inchangé : W n'a pas pu être
relu, réseau coupé). integrity_check ok, foreign_key_check vide. Les textes écrits sont ceux du seed de
e7ab82f, en fr, en et es, dans les deux groupes (comparés). Journal : quatre « seed amendment applied »
(2026-11-03-f1-2-chiffres, -n1-1-chiffres × essai, Monnaie libre), « publication suspended …
waiting=12 », aucune ligne ERROR ; un seul WARN, attendu réseau coupé : « web of trust size: no node nor
indexer answered, keeping the last value ». Un second démarrage ne rejoue rien (comptes identiques,
aucun « applied »).
Une première répétition, sur 2ce2028 (lot T3 seul), le 03/11 à 17 h 54, avait donné les mêmes comptes ; le
réseau n'y était pas coupé (W relu sur rpc.duniter.org, settings.wot_size 5 709 → 5 711), ce que la
relecture a relevé. Ses copies sont retirées (18 h 47).
Effet attendu
- Dans les deux groupes, N1.1 n'a plus d'exemple chiffré et dit la phrase du quorum vraie ; N1.1 et F1.2 disent « au-delà du quorum » ; en fr, en et es. F1.1 inchangé.
- Rien d'autre ne change ; le dépôt des textes reste à
9e0f45a.
Irréversibilité : partielle. Le code se remet en arrière ; les nouveaux textes restent (l'ancien est dans l'historique de chaque proposition).
Avant — prémisses vivantes
- La production sert
6f6197c: santé"build":"6f6197cc";prod/main→6f6197c. - Sur une copie fraîche,
m8/premisse.sh <db>(scratchpad de l'intégrateur, lecture seule) : 6 lignes, toutesopen, origineseed, révision 3 pour F1.1 et 4 pour F1.2 et N1.1, votes, bulletins, coquilles et objections à 0 ; migration 11. Un article touché est refusé par l'amendement avec sa raison, et l'acte reste valable pour l'autre. Lu par l'intégrateur le 03/11 à 17 h 47, puis à 18 h 54, sur ses copies de la copie d'orch de 17 h 46 : l'attendu exact ; 0 vote et 0 ligne de bulletin en tout ; une identité. À relire sur la copie fraîche juste avant la poussée, et comparercounts.shà la colonne « Avant » de la répétition. - La relecture indépendante de
e7ab82f, inscrite « ok » dans~/harness/etat/relectures.json.- Première relecture,
2ce2028: à reprendre (sous-agent neuf, sans le contexte de l'intégrateur, lancé à 17 h 55, inscrit à 18 h 12 ; transcript~/.claude/projects/-home-yvv-Documents-PROD-DEV-libreDecision/d0a7108b-7f2f-484a-bcb0-de339238199d/subagents/agent-a3341da520d4c5530.jsonl) : la phrase de G de N1.1 fausse sous le quorum ; mineurs : « autant de voix pour que si » ambigu, le test de « 100 votants » qui ne pouvait pas échouer, la répétition qui avait lu W sur la chaîne. Tout repris par le lot T3b (e7ab82f). - Relecture de
e7ab82f: en cours (sous-agent neuf, sans le contexte de l'intégrateur, lancé le 03/11 à 18 h 56).
- Première relecture,
git diff 6f6197c e7ab82f -- docker/ .woodpecker/ .env data/ crates/ld-server/migrations/ web/ crates/ld-engine/→ vide (vu par l'intégrateur le 03/11 à 18 h 48).- Boucle verte sur
e7ab82f, le 03/11 de 18 h 47 à 18 h 54 (journalm8/loop-b.log), du premier coup : fmt, clippy-D warnings, 314 tests Rust, svelte-check 0 / 0 (648 fichiers), 78 vitest, build, e2e 42 / 42 (18 h 50 à 18 h 54). Image de production construite le 03/11 de 18 h 56 à 19 h 01 (copie principale surd17a5f6, même code quee7ab82f: le dossier seul en plus), sortie 0 : étage serveur rejoué (fmt, clippy, 314 tests Rust « ok », 0 échec, build release) ; étage web repris du cache (web/identique depuis6f6197c) ; image de contrôle retirée à 19 h 01 (journalm8/docker-m8b.log). - Sur sonic, aucun témoin
/opt/libredecision-app/deploying.
Commande exacte
cd /home/yvv/Documents/PROD/DEV/libreDecision
git push prod e7ab82f48f41f52b3f31e322553f7cf18bc21601:main
Vérifications après
- Santé vue de l'extérieur →
"build":"e7ab82f4". - Journaux : quatre « seed amendment applied » (
2026-11-03-f1-2-chiffres,-n1-1-chiffres× essai, Monnaie libre), « publication suspended … waiting=12 », aucune ligne ERROR ni WARN. - Redémarrage à froid : aucun amendement rejoué.
- Sur une copie fraîche : F1.2 et N1.1 en révision 5, F1.1 en révision 3, dans les deux groupes ; le
reste identique à la ligne près à la copie d'avant (comptes de
counts.sh) ;integrity_checkok. - Le dépôt des textes reste à
9e0f45a.
Retour
- Le code :
docker tag libredecision-app:previous libredecision-app:latest, puiscd /opt/libredecision-app && docker compose up -d --force-recreate.previoussera6f6197c, qui attend aussi le premier texte pour publier : pas de coupure de la publication à faire.6f6197csert les nouveaux textes tels quels (ce sont des données). - Les textes : pas de retour automatique ; l'ancien texte reste dans l'historique de chaque proposition, un nouvel amendement gardé pourrait le remettre.