Lot T4 : l'ADR 0014, le fichier de relecture textes-amorce.md, les contrôles e2e au document de T4

ADR 0014 « Les informations de fonctionnement ne se votent pas » : ce qui sort
(F1, F1.1, F1.2, F1.3, N1, N1.1, O1 et l'ordre de leurs sections), comment (rien
d'effacé, units.retired_at), la garde et ses refus, aucun vote futur (404 / 400),
ce que dira l'interface (U3), la file de publication, le retour arrière (prouvé
avec l'image de de1b7eb), les limites. textes-amorce.md : chaque texte avant /
après en fr, en, es, E12, ce qui sort, les choix à confirmer par Yvv.

e2e (aucun changement de web/src) : C3, C9 (27 articles, cinq sections, quatre
Propositions seed), C17 (33 modules à voter), C18 et C31 (le texte d'I1 de
T4), C25 (cinq lignes d'ordre, E12 dans l'ordre de « fondamental »), C35 (E12
entre E1 et E2 ; le glisser d'une place), C38 (4 Propositions seed).
CONTROLES.md suit ; CLAUDE.md : article_amend.rs, retire.rs, amorce.rs,
fixtures/seed-m8, le seed de 27 articles, l'invariant.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Yvv
2026-11-03 21:45:27 +01:00
co-authored by Claude Opus 5.5
parent 093d1ca471
commit 3996f6f99d
11 changed files with 512 additions and 53 deletions
+16 -6
View File
@@ -64,7 +64,10 @@ crates/
# · modules.rs / order.rs / doc_title.rs (les modules, ADR 0009 : l'ordre d'une # · modules.rs / order.rs / doc_title.rs (les modules, ADR 0009 : l'ordre d'une
# section, le titre du document) · module_amend.rs (ajout gardé) · quorum.rs (le quorum # section, le titre du document) · module_amend.rs (ajout gardé) · quorum.rs (le quorum
# d'un article, PUT /units/{id}/quorum ; « un vote existe » : voted_units, ADR 0013) · # d'un article, PUT /units/{id}/quorum ; « un vote existe » : voted_units, ADR 0013) ·
# quorum_amend.rs (les quorums par cran, amendement gardé) · web.rs (sert web/build) # quorum_amend.rs (les quorums par cran, amendement gardé) · article_amend.rs (un
# article du seed ajouté à un document existant, gardé : E12, lot T4) · retire.rs
# (formule, inertie, ordonnancement sortis du document sans rien effacer :
# units.retired_at, ADR 0014) · web.rs (sert web/build)
tests/ # api.rs (scénarios bout en bout) · ballots.rs (vote par la chaîne, indexeur simulé) · tests/ # api.rs (scénarios bout en bout) · ballots.rs (vote par la chaîne, indexeur simulé) ·
# objections.rs · typos.rs (lot F, horloge avancée, migration 0008) · modules.rs (ordre, # objections.rs · typos.rs (lot F, horloge avancée, migration 0008) · modules.rs (ordre,
# titre, ajout gardé) · seed_proposals.rs (Propositions seed, publication suspendue) · # titre, ajout gardé) · seed_proposals.rs (Propositions seed, publication suspendue) ·
@@ -74,10 +77,14 @@ crates/
# seed_quorum_texts.rs (lots T, T2 et T3 : F1.1, F1.2, N1.1 ; aucun chiffre daté, chaque # seed_quorum_texts.rs (lots T, T2 et T3 : F1.1, F1.2, N1.1 ; aucun chiffre daté, chaque
# phrase vraie pour tout W et tout quorum ; fixtures/seed-quorum-m6b.json et # phrase vraie pour tout W et tout quorum ; fixtures/seed-quorum-m6b.json et
# seed-quorum-t2.json, leurs textes depuis M6b et M6c, pour rejouer T2 et T3 sur une # seed-quorum-t2.json, leurs textes depuis M6b et M6c, pour rejouer T2 et T3 sur une
# base comme la production) # base comme la production ; depuis T4, sur le seed de M8) · amorce.rs (lot T4 : les
seeds/ # acte-engagement-certification.json (trilingue, 33 articles, aucun en vigueur ; # textes d'Yvv, E12, le retrait ; après M6c et après M8, chaque ligne de chaque table
# I1/E1/E2 Propositions seed au cran 2 (seed::SEED_PROPOSAL_LEVEL), inertie 3 ailleurs ; # gardée, le retour arrière) · fixtures/seed-m8/ (le seed de M8 : les derniers textes
# modules en vigueur sans vote : le titre à 4, l'ordre de chaque section à 2 ; # de formule, inertie, ordonnancement, référence du lot U3)
seeds/ # acte-engagement-certification.json (trilingue, 27 articles, 5 sections, aucun en
# vigueur ; I1/E1/E12/E2 Propositions seed au cran 2 (seed::SEED_PROPOSAL_LEVEL),
# inertie 3 ailleurs ; modules en vigueur sans vote : le titre à 4, l'ordre de chaque
# section à 2 ;
# quorums par cran : 12 · 12 · 50 · 50 · 50 Monnaie libre, 1 partout essai) # quorums par cran : 12 · 12 · 50 · 50 · 50 Monnaie libre, 1 partout essai)
# upcoming/<groupe>.json : les « À venir » des outils d'un groupe (fr, en, es), lus au démarrage # upcoming/<groupe>.json : les « À venir » des outils d'un groupe (fr, en, es), lus au démarrage
web/src/ web/src/
@@ -134,7 +141,10 @@ docker build -f docker/app.Dockerfile --target production . # rejoue toute la
est la personne ou le groupe, jamais le système. Le français du texte voté fait foi. est la personne ou le groupe, jamais le système. Le français du texte voté fait foi.
- **Moteur pur** : une règle de vote / édition / composition s'écrit et se teste dans - **Moteur pur** : une règle de vote / édition / composition s'écrit et se teste dans
`ld-engine` avant d'être câblée. Le serveur ne décide jamais l'accès seul : `trustin-access`. `ld-engine` avant d'être câblée. Le serveur ne décide jamais l'accès seul : `trustin-access`.
- **Invariants** : au départ, aucun article n'est en vigueur : I1, E1 et E2 sont des Propositions - **Invariants** : les informations de fonctionnement (formule, inertie, ordonnancement) ne se
votent pas : hors du document, une unité retirée (`units.retired_at`) n'est ni lue, ni votée, ni
comptée, ni publiée, et rien n'est effacé (ADR 0014) ; au départ, aucun article n'est en
vigueur : I1, E1, E12 et E2 sont des Propositions
seed (ouvertes, mises en avant, au cran 2 ; seuls les modules sont des *seeds a minima*), et la seed (ouvertes, mises en avant, au cran 2 ; seuls les modules sont des *seeds a minima*), et la
publication d'un document attend son premier texte en vigueur (ADR 0011) ; un quorum par cran publication d'un document attend son premier texte en vigueur (ADR 0011) ; un quorum par cran
(12 · 12 · 50 · 50 · 50 dans Monnaie libre), que l'auteur d'un article change avant le premier (12 · 12 · 50 · 50 · 50 dans Monnaie libre), que l'auteur d'un article change avant le premier
@@ -0,0 +1,143 @@
# 0014 — Les informations de fonctionnement ne se votent pas
> Décision d'Yvv du 2026-11-03 (lot T4). Complète [0009](0009-modules-ordre-et-titre.md) (les
> modules) et [0011](0011-propositions-seed.md) (les Propositions seed). La migration est la
> `0012`. Les textes, avant et après, sont relus dans
> `docs/chantiers/acte-certification/textes-amorce.md`.
**Contexte.** Le seed de l'Acte d'engagement portait, depuis la maquette, trois sections au bas du
document : `formule` (F1 « Formule de vote », F1.1 « Formule du seuil WoT », F1.2 « Paramètres par
défaut », F1.3 « Processus de dépôt officiel »), `inertie` (N1 « Réglage de l'inertie », N1.1
« Niveaux d'inertie ») et `ordonnancement` (O1 « Ordonnancement du document »), chacune avec son
module « ordre des articles » (ADR 0009). Les lots T à T3c ont réécrit F1.1, F1.2 et N1.1 pour
qu'ils disent les règles du moteur. Yvv, 2026-11-03 : « Attention les 3 derniers modules ne sont pas
de votes : ordonnancement, inertie, et formule de vote sont des infos de fonctionnement. Les votes
se font à leur place, et les infos doivent trouver leur place dans l'ux. […] Vire les 3 du bas de
la liste. »
## Décision
**Ce qui sort du document** : les sept articles F1, F1.1, F1.2, F1.3, N1, N1.1, O1, et les trois
modules `ordre.formule`, `ordre.inertie`, `ordre.ordonnancement`. Le document garde cinq
sections (introduction, fondamental, technique, conclusion, annexe) et 27 articles, dont quatre
Propositions seed : I1, E1, E12 « Responsabilité civique » (nouveau, entre E1 et E2) et E2.
**Hors du document, une unité n'est rien pour le vote.** Elle n'est ni lue avec son document
(`docs::load_state` ne lit que les unités sans `retired_at`, et leurs versions), donc ni listée,
ni comptée (`docs::group` : « propositions en cours » ; `overview::modules` : « modules à
voter »), ni mise dans l'ordre d'une section (`DocState::members`), ni publiée (`document.json` et
le Markdown lisent l'état du document ; `publish::waits_for_a_text` et `last_change` l'ignorent).
**Aucun vote futur** : l'API répond 404 à un vote, à la lecture d'une de ses versions, à une
correction, une traduction, une objection faite depuis elle, une proposition sur elle, un
changement d'inertie, un quorum, un ordre (`proposals::guarded` : la version doit être celle d'une
unité du document) ; 400 à un vote groupé qui la nomme (`lines`), à une objection qui la vise
(`other`) et à un nouvel article dans une section sortie (`section`). Rien n'est écrit par ces
refus.
**Une base neuve** naît sans eux : le seed ne les contient plus.
**Une base existante** (la production : Monnaie libre et le groupe d'essai) **n'efface rien**. La
migration `0012` est additive : `units.retired_at` (quand l'unité est sortie) et
`units.retired_reason` (l'amendement qui l'a sortie), les journaux `retirement_amendments` et
`article_amendments`. Le retrait `2026-11-03-fonctionnement-hors-vote`
(`crates/ld-server/src/retire.rs`) est décidé **une fois par document**, pour toutes les unités ou
aucune, et n'écrit que ces deux colonnes : ni leurs versions, ni leurs révisions, ni leurs
traductions, ni la file de publication ne changent. Il n'a lieu que si **aucune personne n'a
laissé de trace** sur l'une d'elles, dans l'une de ses versions, quoi qu'il en soit advenu, et il
dit la première trouvée (raison et code de l'unité) :
| Trace | Raison du refus |
|---|---|
| un vote du serveur, prouvé ou simulé | `votes` |
| une ligne de bulletin, quel que soit son sort | `ballots` |
| une adoption, une version entrée en vigueur ou confirmée, une inertie changée par un vote | `adopted` |
| une version écrite par un membre (texte, retrait, inertie, ordre) | `member_proposal` |
| une révision écrite par une personne, ou d'un genre qu'aucun amendement n'écrit ; une coquille, en attente ou refusée | `corrected` |
| une traduction écrite ou corrigée par un membre | `translation_edited` |
| une objection qui la nomme, levée ou non | `signalled` |
| un quorum fixé (`units.quorum`, `quorum_changes`) | `quorum_set` |
Un amendement du seed n'est pas une trace de personne : F1.1 à sa révision 3, F1.2 et N1.1 à leur
révision 4 (après M6c) ou 5 (après M8) sortent comme les autres. Refusé, rien ne bouge ; la
décision est consignée (`retirement_amendments` : l'issue, la raison, l'unité, les codes sortis)
et dans les journaux. Appliqué là où le document publie (Monnaie libre), une ligne s'ajoute à la
file ; comme toutes, elle attend le premier texte en vigueur (ADR 0011).
Les amendements qui réécrivaient ces textes (`2026-11-02-n1-regles`, `-o1-regles`,
`2026-11-03-f1-1-phrases`, `-f1-2-chiffres`, `-n1-1-chiffres`) sont **dépassés par le retrait**
(`superseded_by`) : le seed ne donne plus leur texte, ils ne se décident plus. Une production
restée à M6c sort donc F1.2 et N1.1 avec le texte de M6c.
## Les textes d'amorce
I1, E1 et E2 prennent les textes d'Yvv du 03/11 par trois amendements gardés de
`seed_amend.rs` sur la Proposition seed elle-même (`Version::SeedProposal`), jamais sur un texte
en vigueur : `2026-11-03-i1-amorce` (suit `2026-10-30-i1-raison-d-etre`), `2026-11-03-e1-amorce`,
`2026-11-03-e2-amorce`. Même garde que tout amendement du seed (une trace de personne refuse,
avec sa raison) ; la ligne d'historique `seed_proposal`, qui ne change aucun texte, est admise
quand l'amendement de Proposition seed l'a écrite, et seulement elle. Les amendements de
Proposition seed (`seed_proposal_amend.rs`) sont dépassés par eux.
E12 entre par un ajout gardé (`crates/ld-server/src/article_amend.rs`, sur le modèle de
`module_amend`), une fois par document : écrit comme une base neuve l'écrit
(`seed::write_unit`), **entre E1 et E2** tant qu'aucun vote n'existe sur l'ordre de la section
(`quorum::voted_units`) et qu'ils s'y suivent — l'ordre en vigueur, qui lit les positions, le dit
aussitôt —, sinon **en fin de section**, comme tout nouvel article. Refus : `code_taken` (une
autre unité porte déjà ce code), `no_section`. Le code E12 suit la famille des engagements (E3 à
E11 existent) ; la place vient de l'ordre de la section, pas du numéro.
## Ce que dira l'interface (lot U3)
Les informations de fonctionnement se montrent **hors du vote** : la formule du seuil, les crans
d'inertie, le quorum, l'ordonnancement, à leur place dans l'écran (Yvv : « les infos doivent
trouver leur place dans l'ux »), d'après les paramètres du moteur et du document, pas d'après
un texte voté. Les vérités que F1.1, F1.2 et N1.1 portaient, chacune vérifiée par un test
(lots T à T3c, `t3c-liste-fermee.md`), en sont la référence ; leurs derniers textes restent dans
`crates/ld-server/tests/fixtures/seed-m8/` et, en production, dans leurs lignes. T4 ne touche pas
`web/`.
## La file de publication
Rien n'y est effacé. Les lignes écrites pour ces textes avant T4 (les amendements de M5 à M8,
« F1.2 », « N1.1 »…) restent telles quelles ; comme toute la file, elles attendent le premier
texte en vigueur (ADR 0011) et partent avec lui : leurs raisons sont des lignes du message de
commit, alors que le contenu publié (`document.json`, le Markdown) ne contient plus ces
articles ; la ligne du retrait, ajoutée à la même file, dit qu'ils sont sortis.
## Le retour arrière
L'image d'avant (`de1b7eb`) ne connaît pas `retired_at` : elle lit les unités sans cette colonne
et les montre de nouveau, **telles qu'elles étaient** (versions, révisions, traductions, ordres
intacts : le retrait n'a écrit que ses deux colonnes). Elle démarre sur la base migrée : les
migrations inconnues sont tolérées (`open_db`). Ce que le retour ne défait pas : E12 reste
(une Proposition seed, que l'image d'avant lit comme les autres), I1, E1 et E2 gardent leurs
textes de T4 (une révision de plus).
**Prouvé** par le test `an_image_that_ignores_the_column_shows_the_rules_of_operation_as_they_were`
(`tests/amorce.rs` : la colonne remise à vide, la vue est celle d'avant), et le 2026-11-03 avec
l'image de `de1b7eb` elle-même, hors du dépôt : une base née du seed de production du 02/11 puis
démarrée par `de1b7eb` (un vote, un article de membre) ; l'image de T4 démarre dessus ; puis
`de1b7eb` de nouveau. Les sept articles et les trois ordres se lisent à l'identique dans les deux
groupes ; aucune ligne d'aucune table n'a disparu ; T4 n'a modifié que `retired_at` et
`retired_reason` (20 unités), et les trois Propositions seed amendées (6 versions, 12
traductions) ; `de1b7eb` relancée n'a rien écrit (une session de lecture). **Sur une copie de la
production**, la même procédure : relever chaque ligne de chaque table (rowid compris) ; démarrer
l'image de T4 sur la copie, sans clé de publication ; relever de nouveau (aucune ligne absente,
aucune colonne changée hors de celles-là) ; démarrer `de1b7eb` sur la copie et comparer
`GET /api/docs/{id}` d'avant et d'après pour F1 à O1 et `ordre.formule`, `ordre.inertie`,
`ordre.ordonnancement`.
Limite : le retrait n'est décidé qu'une fois ; si, après un
retour arrière, quelqu'un agit sur ces articles puis T4 revient, `retired_at` les sort de
nouveau sans relire la garde. Les remettre serait alors une décision (`retired_at` à NULL : une
écriture, pas un effacement).
## Limites connues
- **Une base d'avant M6** (I1, E1, E2 en vigueur, pas Propositions seed) : l'amendement de
Proposition seed étant dépassé, ils restent en vigueur avec leur texte, et les trois
amendements d'amorce refusent (`no_seed_proposal`). Aucune base réelle n'est dans ce cas.
- Un article de membre prend le code `N<n>` (`proposals::new_unit`) d'après le nombre de codes
en `N` du document, unités sorties comprises : en production, N1 et N1.1 restent dans la base
et aucun code n'est repris ; dans une base neuve, le premier article de membre est N1, sans
rapport avec l'ancien « Réglage de l'inertie ».
+1
View File
@@ -18,3 +18,4 @@ pas une décision : on en écrit une nouvelle qui la remplace, et on le note dan
| [0011](0011-propositions-seed.md) | Les Propositions seed : rien en vigueur au départ, trois textes mis en avant au cran 2, la publication attend le premier texte (complète 0002) | 2026-11-02 | | [0011](0011-propositions-seed.md) | Les Propositions seed : rien en vigueur au départ, trois textes mis en avant au cran 2, la publication attend le premier texte (complète 0002) | 2026-11-02 |
| [0012](0012-tampon-des-votes.md) | Le tampon des votes : l'intention visible tout de suite, la preuve de la chaîne, la réconciliation a posteriori ; la simulation tant que la chaîne est fermée (complète 0008, révise 0010) | 2026-11-02 | | [0012](0012-tampon-des-votes.md) | Le tampon des votes : l'intention visible tout de suite, la preuve de la chaîne, la réconciliation a posteriori ; la simulation tant que la chaîne est fermée (complète 0008, révise 0010) | 2026-11-02 |
| [0013](0013-quorum.md) | Le quorum par cran (12 · 12 · 50 · 50 · 50), fixé par l'auteur avant le premier vote ; sous le quorum, les votants qui manquent comptent comme « non » (remplace le C de 0002 et 0007) | 2026-11-03 | | [0013](0013-quorum.md) | Le quorum par cran (12 · 12 · 50 · 50 · 50), fixé par l'auteur avant le premier vote ; sous le quorum, les votants qui manquent comptent comme « non » (remplace le C de 0002 et 0007) | 2026-11-03 |
| [0014](0014-informations-de-fonctionnement.md) | Les informations de fonctionnement ne se votent pas : formule, inertie, ordonnancement sortent du document sans rien effacer (`units.retired_at`) ; E12 « Responsabilité civique » ajoutée (complète 0009 et 0011) | 2026-11-03 |
@@ -17,13 +17,13 @@ pour une personne, ils coûtent 0,1 Ğ1 réels : c'est un acte « paye » d'Yvv.
|---|---|---|---| |---|---|---|---|
| C1 | L'accueil, sans session | ouvrir `/` sans être connectée | la clé de voûte en grand, jamais inclinée ; sous l'arche, centrés et dans cet ordre : « boîte à outils », « contexte et cadrage », « processus et modalités » ; puis le titre centré sur deux lignes, « Rendre possible » / « la décision collective » ; « Se connecter avec sa clé Ğ1 » et sa note ; pas de piliers ni de groupes ; le menu à gauche avec les quatre outils, trois éteints | | C1 | L'accueil, sans session | ouvrir `/` sans être connectée | la clé de voûte en grand, jamais inclinée ; sous l'arche, centrés et dans cet ordre : « boîte à outils », « contexte et cadrage », « processus et modalités » ; puis le titre centré sur deux lignes, « Rendre possible » / « la décision collective » ; « Se connecter avec sa clé Ğ1 » et sa note ; pas de piliers ni de groupes ; le menu à gauche avec les quatre outils, trois éteints |
| C2 | L'accueil, avec session | se connecter : on arrive sur `/` | le titre, le leitmotiv, puis directement le choix du groupe : Monnaie libre en grand, Axiom, Librodrome, Groupe local Vallée Drôme Crestois ; **pas** l'Atelier du canal ; `/groupes` et « Mes groupes » (menu) ramènent ici | | C2 | L'accueil, avec session | se connecter : on arrive sur `/` | le titre, le leitmotiv, puis directement le choix du groupe : Monnaie libre en grand, Axiom, Librodrome, Groupe local Vallée Drôme Crestois ; **pas** l'Atelier du canal ; `/groupes` et « Mes groupes » (menu) ramènent ici |
| C3 | Le texte au départ : les Propositions seed | Monnaie libre → Docs de référence → Acte d'engagement Certification | aucun article en vigueur (ADR 0011) : « Aucun article n'est encore en vigueur. Commence par les Propositions seed : elles y entrent par le vote, comme toute proposition. » ; puis, **en tête du texte**, en entier, Raison d'être (sous « Introduction »), Unicité du compte et Réciprocité (sous « Engagements fondamentaux »), chacune marquée « Proposition seed » (au survol : « Texte de départ mis en avant pour lancer le vote… »), sur un lavis d'eau, avec « 0 pour · 0 contre · 9 oui sur 12 » et « basse » (au lecteur d'écran : « inertie 2 / 5 · basse ») ; chaque section lue finit par une ligne d'ordre (C25) ; en dessous, « Propositions en cours » **repliées par section** (8 lignes : le nom, « 11 articles », un petit niveau d'eau par article) ; « Tout déplier » : 30 lignes, une par article (les trois Propositions seed ne s'y répètent pas) | | C3 | Le texte au départ : les Propositions seed | Monnaie libre → Docs de référence → Acte d'engagement Certification | aucun article en vigueur (ADR 0011) : « Aucun article n'est encore en vigueur. Commence par les Propositions seed : elles y entrent par le vote, comme toute proposition. » ; puis, **en tête du texte**, en entier, Raison d'être (sous « Introduction »), Unicité du compte, Responsabilité civique et Réciprocité (sous « Engagements fondamentaux »), chacune marquée « Proposition seed » (au survol : « Texte de départ mis en avant pour lancer le vote… »), sur un lavis d'eau, avec « 0 pour · 0 contre · 9 oui sur 12 » et « basse » (au lecteur d'écran : « inertie 2 / 5 · basse ») ; chaque section lue finit par une ligne d'ordre (C25) ; en dessous, « Propositions en cours » **repliées par section** (5 lignes : le nom, « 11 articles », un petit niveau d'eau par article ; formule, inertie et ordonnancement sont sortis du document, ADR 0014) ; « Tout déplier » : 23 lignes, une par article (les quatre Propositions seed ne s'y répètent pas) |
| C4 | Gestes contextuels | groupe d'essai, où la Raison d'être est entrée en vigueur par le vote : la survoler → « Le vote » | deux gestes sous l'article, « Le vote » et « Proposer une modification » (ses autres versions se lisent dans le vote) ; le vote se **déplie sous l'article**, sans fenêtre : « N oui sur Q votants pour passer » et les voix qui manquent ; « La formule du seuil » se déplie : « M — majorité à pleine participation : 50 % — inertie 2 / 5 · basse », et le lien « Réglages de la formule » ; l'URL garde le vote déplié (`?vote=`) ; « Le vote » de nouveau le replie | | C4 | Gestes contextuels | groupe d'essai, où la Raison d'être est entrée en vigueur par le vote : la survoler → « Le vote » | deux gestes sous l'article, « Le vote » et « Proposer une modification » (ses autres versions se lisent dans le vote) ; le vote se **déplie sous l'article**, sans fenêtre : « N oui sur Q votants pour passer » et les voix qui manquent ; « La formule du seuil » se déplie : « M — majorité à pleine participation : 50 % — inertie 2 / 5 · basse », et le lien « Réglages de la formule » ; l'URL garde le vote déplié (`?vote=`) ; « Le vote » de nouveau le replie |
| C5 | Entrée en vigueur | groupe d'essai (Raison d'être, Unicité du compte et Réciprocité entrées en vigueur par le vote) : déplier le vote de « Les deux garanties réciproques », « Pour » ; une deuxième personne si cette voix ne suffit pas | à la voix qui suffit, « … est entré en vigueur » ; le texte en vigueur compte quatre articles, le vote reste déplié sous le nouveau texte (autant de « pour » que de voix, 0 contre) | | C5 | Entrée en vigueur | groupe d'essai (Raison d'être, Unicité du compte et Réciprocité entrées en vigueur par le vote) : déplier le vote de « Les deux garanties réciproques », « Pour » ; une deuxième personne si cette voix ne suffit pas | à la voix qui suffit, « … est entré en vigueur » ; le texte en vigueur compte quatre articles, le vote reste déplié sous le nouveau texte (autant de « pour » que de voix, 0 contre) |
| C6 | Coquille sans vote | groupe d'essai, **en administratrice** (un texte du seed n'a pas d'auteur) : Unicité du compte → « Le vote » → « Coquilles, traductions, objections, historique » (le panneau « Détails », sans onglets) → « Corriger une coquille », remplacer les apostrophes droites par des apostrophes typographiques (« Je m’engage sur l’honneur ») | « Coquille corrigée, sans toucher aux votes. » ; un changement de sens est refusé : « Ce changement touche au sens : propose-le comme modification. » (sans être administratrice, la correction attend : C31) | | C6 | Coquille sans vote | groupe d'essai, **en administratrice** (un texte du seed n'a pas d'auteur) : Unicité du compte → « Le vote » → « Coquilles, traductions, objections, historique » (le panneau « Détails », sans onglets) → « Corriger une coquille », remplacer les apostrophes droites par des apostrophes typographiques (« Je m’engage sur l’honneur ») | « Coquille corrigée, sans toucher aux votes. » ; un changement de sens est refusé : « Ce changement touche au sens : propose-le comme modification. » (sans être administratrice, la correction attend : C31) |
| C7 | Une décision par proposition | groupe d'essai : « Proposer un nouvel article », deux paragraphes « Je m'engage à… » | l'assistant : « Ce texte semble porter 2 décisions » ; « Découper en 2 brouillons » ; « Tes brouillons » apparaît | | C7 | Une décision par proposition | groupe d'essai : « Proposer un nouvel article », deux paragraphes « Je m'engage à… » | l'assistant : « Ce texte semble porter 2 décisions » ; « Découper en 2 brouillons » ; « Tes brouillons » apparaît |
| C8 | Trois langues | choisir EN puis ES pour le texte | « Certification Commitment Act », « Acta de compromiso de Certificación » ; l'interface suit | | C8 | Trois langues | choisir EN puis ES pour le texte | « Certification Commitment Act », « Acta de compromiso de Certificación » ; l'interface suit |
| C9 | Les aperçus | « Si tout passe », puis « Si les bien cotées passent » | 33 articles avec la mention d'aperçu, puis aucun (rien en vigueur dans Monnaie libre, rien de bien coté sans « pour ») | | C9 | Les aperçus | « Si tout passe », puis « Si les bien cotées passent » | 27 articles avec la mention d'aperçu, puis aucun (rien en vigueur dans Monnaie libre, rien de bien coté sans « pour ») |
| C10 | trustinWallet | ouvrir `/acces` sans être administratrice | « La gestion des accès est réservée aux administrateurs de trustinWallet. » (côté admin : créer un lien d'invitation) | | C10 | trustinWallet | ouvrir `/acces` sans être administratrice | « La gestion des accès est réservée aux administrateurs de trustinWallet. » (côté admin : créer un lien d'invitation) |
| C11 | Une personne, une voix | avec un lien d'invitation et un portefeuille dont le compte n'est pas membre de la toile (Bob, chaîne simulée), voter « Pour » sur un article de Monnaie libre | le vote dit que la voix est celle de l'identité Ğ1 du portefeuille qui signe ; après signature : « Ton vote n'a pas été compté : le portefeuille qui a signé n'est pas celui d'un membre de la toile de confiance Ğ1. », et sous l'article « Ton dernier vote n'a pas été compté… », 0 pour ; dans le groupe d'essai, la même personne vote directement, sans portefeuille | | C11 | Une personne, une voix | avec un lien d'invitation et un portefeuille dont le compte n'est pas membre de la toile (Bob, chaîne simulée), voter « Pour » sur un article de Monnaie libre | le vote dit que la voix est celle de l'identité Ğ1 du portefeuille qui signe ; après signature : « Ton vote n'a pas été compté : le portefeuille qui a signé n'est pas celui d'un membre de la toile de confiance Ğ1. », et sous l'article « Ton dernier vote n'a pas été compté… », 0 pour ; dans le groupe d'essai, la même personne vote directement, sans portefeuille |
| C12 | Lien d'équipe | administrateur : `/acces` → « Liens d'équipe », cocher le groupe d'essai, créer ; l'ouvrir dans deux navigateurs, sous deux noms | chacun arrive sur ses groupes sous son nom ; dans `/acces`, « 2 / 30 personnes » et deux identités « venue par » le lien ; un nom déjà pris est refusé, même autrement écrit (« luna » pour « Luna ») ; sur un navigateur où quelqu'un est connecté, « Ce n'est pas moi » le déconnecte ; « Révoquer » ferme le lien | | C12 | Lien d'équipe | administrateur : `/acces` → « Liens d'équipe », cocher le groupe d'essai, créer ; l'ouvrir dans deux navigateurs, sous deux noms | chacun arrive sur ses groupes sous son nom ; dans `/acces`, « 2 / 30 personnes » et deux identités « venue par » le lien ; un nom déjà pris est refusé, même autrement écrit (« luna » pour « Luna ») ; sur un navigateur où quelqu'un est connecté, « Ce n'est pas moi » le déconnecte ; « Révoquer » ferme le lien |
@@ -33,7 +33,7 @@ pour une personne, ils coûtent 0,1 Ğ1 réels : c'est un acte « paye » d'Yvv.
| C14 | La page d'un groupe | Monnaie libre | le nom ; le pavé des quatre piliers (Docs de référence « ouvert », les trois autres « à venir ») ; « En cours » : l'Acte d'engagement Certification, qui ouvre son lecteur | | C14 | La page d'un groupe | Monnaie libre | le nom ; le pavé des quatre piliers (Docs de référence « ouvert », les trois autres « à venir ») ; « En cours » : l'Acte d'engagement Certification, qui ouvre son lecteur |
| C15 | Le menu | survoler les outils ; ouvrir Docs, puis Mandats ; revenir à l'accueil | « 1 » à côté de « Docs de référence » ; aucun outil surligné sur la page du groupe, seul celui où l'on est ensuite ; au survol, seul Docs réagit ; Mandats s'ouvre quand même (ses « À venir ») ; hors d'un groupe, les outils mènent au dernier groupe ouvert (ou à l'accueil s'il n'y en a pas) | | C15 | Le menu | survoler les outils ; ouvrir Docs, puis Mandats ; revenir à l'accueil | « 1 » à côté de « Docs de référence » ; aucun outil surligné sur la page du groupe, seul celui où l'on est ensuite ; au survol, seul Docs réagit ; Mandats s'ouvre quand même (ses « À venir ») ; hors d'un groupe, les outils mènent au dernier groupe ouvert (ou à l'accueil s'il n'y en a pas) |
| C16 | En cours, à venir | Monnaie libre → Docs, Mandats, Protocoles ; les anciennes adresses `/decisions`, `/mandats`, `/protocoles` | Docs : « En cours » (Acte d'engagement Certification) et « À venir » (Acte d'engagement forgerons) ; Mandats : Administration forum Duniter, Administration forum Monnaie libre ; Protocoles : Runtime upgrade — décision on-chain ; les « À venir » sont éteints, sans lien ; ils suivent la langue ; les anciennes adresses mènent aux outils du groupe courant | | C16 | En cours, à venir | Monnaie libre → Docs, Mandats, Protocoles ; les anciennes adresses `/decisions`, `/mandats`, `/protocoles` | Docs : « En cours » (Acte d'engagement Certification) et « À venir » (Acte d'engagement forgerons) ; Mandats : Administration forum Duniter, Administration forum Monnaie libre ; Protocoles : Runtime upgrade — décision on-chain ; les « À venir » sont éteints, sans lien ; ils suivent la langue ; les anciennes adresses mènent aux outils du groupe courant |
| C17 | Décisions | Monnaie libre → Décisions ; voter (par la chaîne : bulletin, transaction, confirmation) sur une version d'un article, recharger | une ligne par doc : « Acte d'engagement Certification · 41 modules à voter · dont 41 sans ton vote » (33 articles, le titre, l'ordre de 7 sections), puis « dont 40 » ; la ligne ouvre le lecteur | | C17 | Décisions | Monnaie libre → Décisions ; voter (par la chaîne : bulletin, transaction, confirmation) sur une version d'un article, recharger | une ligne par doc : « Acte d'engagement Certification · 33 modules à voter · dont 33 sans ton vote » (27 articles, le titre, l'ordre de 5 sections), puis « dont 32 » ; la ligne ouvre le lecteur |
| C18 | La Raison d'être | Monnaie libre → Acte d'engagement Certification → « Si tout passe », puis EN, puis ES | en tête du texte, « Raison d'être » : la première phrase en italique, puis deux paragraphes ; « Purpose », « Razón de ser » | | C18 | La Raison d'être | Monnaie libre → Acte d'engagement Certification → « Si tout passe », puis EN, puis ES | en tête du texte, « Raison d'être » : la première phrase en italique, puis deux paragraphes ; « Purpose », « Razón de ser » |
| C19 | Les versions d'un article | Monnaie libre → « Propositions en cours » → « Tout déplier » → « Connaissance suffisante » (au clavier : Tab jusqu'à la ligne, Entrée) | une seule ligne, « 2 versions » ; dépliée : « variante 1.0.0 » et « variante 0.4.0-draft », chacune avec son niveau et ce qui la distingue ; un clic sur une version déplie son vote sous elle (cran 3, quorum 50 : « 39 oui sur 50 votants pour passer »), sans « Autres versions » : l'autre version est juste là, dans la liste (lot U2) ; un nouveau clic sur la ligne la replie | | C19 | Les versions d'un article | Monnaie libre → « Propositions en cours » → « Tout déplier » → « Connaissance suffisante » (au clavier : Tab jusqu'à la ligne, Entrée) | une seule ligne, « 2 versions » ; dépliée : « variante 1.0.0 » et « variante 0.4.0-draft », chacune avec son niveau et ce qui la distingue ; un clic sur une version déplie son vote sous elle (cran 3, quorum 50 : « 39 oui sur 50 votants pour passer »), sans « Autres versions » : l'autre version est juste là, dans la liste (lot U2) ; un nouveau clic sur la ligne la replie |
| C20 | Réglages de la formule et cinq crans | Monnaie libre → Acte d'engagement : « Réglages de la formule » (en-tête) ; puis, en tête du texte, Unicité du compte (Proposition seed) → « Le vote » → « Réglages de la formule » ; dans le groupe d'essai, Réciprocité (entrée en vigueur par le vote) → « Le vote » → « Proposer un changement d'inertie » → 5 → « Soumettre au vote » | W 5 745 (toile de confiance Ğ1), B 0,1 ; « 100 votants sur 5 745 (1,74 %), deux fois 50, le quorum de référence : la participation de référence… (0 pour l'instant) » ; le tableau des cinq crans : très basse, basse, moyenne, haute, très haute ; M 50, 50, 55, 60, 66 % ; part exigée 60, 67, 75, 83, 90 % ; quorum 12, 12, 50, 50, 50 (ADR 0013) ; voix pour à 100 votants 60, 67, 75, 83, 90, « Voix pour : à 100 votants, comme d'habitude. », « Part exigée : la part de « pour » demandée, à 100 votants comme d'habitude. », « Quorum : en dessous, les votants qui manquent comptent comme « non ». … » ; depuis le vote déplié : « Inertie · 2 / 5 · basse », la ligne du cran 2 marquée « cet article », à 0 votant 8, 9, 39, 43, 46 voix, « Voix pour : à 0 votant, la participation de cette version. » ; le sélecteur montre les cinq crans, 2 « actuelle », atteignable au clavier mais jamais choisi ; un seul arrêt de tabulation ; les flèches passent d'un cran à l'autre et le choisissent, en boucle ; le vote de la proposition se déplie : « inertie vers 5 / 5 · très haute », votée à « inertie 2 / 5 · basse » | | C20 | Réglages de la formule et cinq crans | Monnaie libre → Acte d'engagement : « Réglages de la formule » (en-tête) ; puis, en tête du texte, Unicité du compte (Proposition seed) → « Le vote » → « Réglages de la formule » ; dans le groupe d'essai, Réciprocité (entrée en vigueur par le vote) → « Le vote » → « Proposer un changement d'inertie » → 5 → « Soumettre au vote » | W 5 745 (toile de confiance Ğ1), B 0,1 ; « 100 votants sur 5 745 (1,74 %), deux fois 50, le quorum de référence : la participation de référence… (0 pour l'instant) » ; le tableau des cinq crans : très basse, basse, moyenne, haute, très haute ; M 50, 50, 55, 60, 66 % ; part exigée 60, 67, 75, 83, 90 % ; quorum 12, 12, 50, 50, 50 (ADR 0013) ; voix pour à 100 votants 60, 67, 75, 83, 90, « Voix pour : à 100 votants, comme d'habitude. », « Part exigée : la part de « pour » demandée, à 100 votants comme d'habitude. », « Quorum : en dessous, les votants qui manquent comptent comme « non ». … » ; depuis le vote déplié : « Inertie · 2 / 5 · basse », la ligne du cran 2 marquée « cet article », à 0 votant 8, 9, 39, 43, 46 voix, « Voix pour : à 0 votant, la participation de cette version. » ; le sélecteur montre les cinq crans, 2 « actuelle », atteignable au clavier mais jamais choisi ; un seul arrêt de tabulation ; les flèches passent d'un cran à l'autre et le choisissent, en boucle ; le vote de la proposition se déplie : « inertie vers 5 / 5 · très haute », votée à « inertie 2 / 5 · basse » |
@@ -41,20 +41,20 @@ pour une personne, ils coûtent 0,1 Ğ1 réels : c'est un acte « paye » d'Yvv.
| C22 | Le vote groupé | groupe d'essai : « Propositions en cours » → « Engagements techniques » → « Voter cette section » ; « Tout pour » ; dans « Connaissance suffisante », « Pour » sur la variante 1.0.0 ; recharger ; « Voter (n) » | le panier s'ouvre sur la section ; « Tout pour » remplit les articles à une version, pas « Connaissance suffisante » ni « Rencontre physique… » (« Plusieurs versions : choisis la tienne. », et le compte des articles laissés) ; le panier reste après rechargement (« Voter en lot · n ») ; un seul envoi : « n votes enregistrés. », le panier vide, la variante choisie à 1 pour | | C22 | Le vote groupé | groupe d'essai : « Propositions en cours » → « Engagements techniques » → « Voter cette section » ; « Tout pour » ; dans « Connaissance suffisante », « Pour » sur la variante 1.0.0 ; recharger ; « Voter (n) » | le panier s'ouvre sur la section ; « Tout pour » remplit les articles à une version, pas « Connaissance suffisante » ni « Rencontre physique… » (« Plusieurs versions : choisis la tienne. », et le compte des articles laissés) ; le panier reste après rechargement (« Voter en lot · n ») ; un seul envoi : « n votes enregistrés. », le panier vide, la variante choisie à 1 pour |
| C23 | Le vote par la chaîne Ğ1 | Monnaie libre, un portefeuille dans le navigateur : « Voter en lot », « Pour » sur Unicité du compte et Réciprocité (Propositions seed), « Signer et envoyer (2) » ; puis, en tête du texte, sous Réciprocité, « Contre » (l'indexeur en retard) puis « Retirer mon vote » ; puis sans portefeuille : la Raison d'être → « Pour » → « Passer par Ğecko » | une seule signature pour les deux : 0,1 Ğ1 vers le compte des votes et une remarque `ld1:` + 64 chiffres, rien du vote en clair ; « Ton vote compte : il est inscrit sur la chaîne Ğ1. », « Compté pour l'identité Ğ1 « Alice ». » ; sous la proposition « Ton vote : pour · inscrit sur la chaîne Ğ1 », 1 pour ; « En attente de la chaîne Ğ1 : contre. » ; le retrait, plus récent sur la chaîne, fait foi même quand le « contre » est confirmé après lui (0 pour · 0 contre) ; Ğecko : un QR code et le lien `g1://<compte>?amount=0.1&comment=ld1:…`, puis la confirmation dès que la chaîne la montre | | C23 | Le vote par la chaîne Ğ1 | Monnaie libre, un portefeuille dans le navigateur : « Voter en lot », « Pour » sur Unicité du compte et Réciprocité (Propositions seed), « Signer et envoyer (2) » ; puis, en tête du texte, sous Réciprocité, « Contre » (l'indexeur en retard) puis « Retirer mon vote » ; puis sans portefeuille : la Raison d'être → « Pour » → « Passer par Ğecko » | une seule signature pour les deux : 0,1 Ğ1 vers le compte des votes et une remarque `ld1:` + 64 chiffres, rien du vote en clair ; « Ton vote compte : il est inscrit sur la chaîne Ğ1. », « Compté pour l'identité Ğ1 « Alice ». » ; sous la proposition « Ton vote : pour · inscrit sur la chaîne Ğ1 », 1 pour ; « En attente de la chaîne Ğ1 : contre. » ; le retrait, plus récent sur la chaîne, fait foi même quand le « contre » est confirmé après lui (0 pour · 0 contre) ; Ğecko : un QR code et le lien `g1://<compte>?amount=0.1&comment=ld1:…`, puis la confirmation dès que la chaîne la montre |
| C24 | Sans compte des votes | Monnaie libre sur un serveur sans `LD_VOTE_ACCOUNT`, puis le groupe d'essai | pas de « Voter en lot » ni « Voter cette section » ; sous la première Proposition seed : « Le vote par la chaîne Ğ1 n'est pas encore ouvert : le compte qui reçoit les votes reste à créer. Tu peux lire, proposer et faire une objection. », pas de bouton, les totaux et « 9 oui sur 12 votants pour passer » restent ; le panier ouvert par son adresse (`?onglet=panier`) dit la même chose, son bouton éteint, et **jamais** « Tes votes comptent dès l'envoi » ; dans le groupe d'essai, le panier et les boutons sont là | | C24 | Sans compte des votes | Monnaie libre sur un serveur sans `LD_VOTE_ACCOUNT`, puis le groupe d'essai | pas de « Voter en lot » ni « Voter cette section » ; sous la première Proposition seed : « Le vote par la chaîne Ğ1 n'est pas encore ouvert : le compte qui reçoit les votes reste à créer. Tu peux lire, proposer et faire une objection. », pas de bouton, les totaux et « 9 oui sur 12 votants pour passer » restent ; le panier ouvert par son adresse (`?onglet=panier`) dit la même chose, son bouton éteint, et **jamais** « Tes votes comptent dès l'envoi » ; dans le groupe d'essai, le panier et les boutons sont là |
| C25 | L'ordre des articles | groupe d'essai : « Tout déplier » ; en fin de « Conclusion », la ligne « Ordre de la section » → « Réordonner » ; cliquer « Monnaie G1 » puis la place 1 ; au clavier, flèche bas puis haut ; « Proposer cet ordre » ; « Pour » ; une deuxième personne vote « Pour » si cette voix ne suffit pas (quorum 1 dans le groupe d'essai : ADR 0013) ; puis, dans Monnaie libre, sur un téléphone, avec un portefeuille : « Voter en lot », « Pour » sur « Ordre des articles · Engagements fondamentaux », « Signer et envoyer (1) » | chaque section finit par **une ligne** « Ordre de la section » (7, aucune pour l'Ordonnancement, un seul article) : la poignée, les crans « basse », « seed a minima · 0 vote », **jamais la liste de ses articles** ; à la fin du texte quand la section s'y lit, sinon à la fin de sa section dans « Propositions en cours » ; le vote d'un ordre en vigueur déplié sous sa ligne montre la liste entière, et son inertie une fois, « Inertie · 2 / 5 · basse » (lot U2) ; « Réordonner » : les articles de la section, sur place, sans panneau ; l'article choisi marqué, puis à sa place, annoncé (« « Monnaie G1 » en place 1 sur 2. »), « Proposer cet ordre » éteint tant que c'est l'ordre en vigueur, et il le dit à côté (« C'est l'ordre en vigueur : déplace au moins un article. ») ; le vote de l'ordre proposé se déplie sous la ligne, l'ordre proposé en clair, « Ordre en vigueur » parmi ses « Autres versions », « 1 ordre proposé » sur la ligne ; aucune ligne d'ordre parmi les propositions ; il est dans le panier, à la fin de sa section ; à la voix qui suffit : « Le nouvel ordre de « Conclusion » est entré en vigueur. », la section se lit dans le nouvel ordre ; par la chaîne : « Ton vote compte : il est inscrit sur la chaîne Ğ1. », « seed a minima · 1 vote » ; sur un téléphone, les gestes du titre sans survol (réordonner sur un téléphone : C35) | | C25 | L'ordre des articles | groupe d'essai : « Tout déplier » ; en fin de « Conclusion », la ligne « Ordre de la section » → « Réordonner » ; cliquer « Monnaie G1 » puis la place 1 ; au clavier, flèche bas puis haut ; « Proposer cet ordre » ; « Pour » ; une deuxième personne vote « Pour » si cette voix ne suffit pas (quorum 1 dans le groupe d'essai : ADR 0013) ; puis, dans Monnaie libre, sur un téléphone, avec un portefeuille : « Voter en lot », « Pour » sur « Ordre des articles · Engagements fondamentaux », « Signer et envoyer (1) » | chaque section finit par **une ligne** « Ordre de la section » (5 ; aucune pour la formule, l'inertie, l'ordonnancement, sortis du document : ADR 0014) : la poignée, les crans « basse », « seed a minima · 0 vote », **jamais la liste de ses articles** ; à la fin du texte quand la section s'y lit, sinon à la fin de sa section dans « Propositions en cours » ; le vote d'un ordre en vigueur déplié sous sa ligne montre la liste entière, et son inertie une fois, « Inertie · 2 / 5 · basse » (lot U2) ; « Réordonner » : les articles de la section, sur place, sans panneau ; l'article choisi marqué, puis à sa place, annoncé (« « Monnaie G1 » en place 1 sur 2. »), « Proposer cet ordre » éteint tant que c'est l'ordre en vigueur, et il le dit à côté (« C'est l'ordre en vigueur : déplace au moins un article. ») ; le vote de l'ordre proposé se déplie sous la ligne, l'ordre proposé en clair, « Ordre en vigueur » parmi ses « Autres versions », « 1 ordre proposé » sur la ligne ; aucune ligne d'ordre parmi les propositions ; il est dans le panier, à la fin de sa section ; à la voix qui suffit : « Le nouvel ordre de « Conclusion » est entré en vigueur. », la section se lit dans le nouvel ordre ; par la chaîne : « Ton vote compte : il est inscrit sur la chaîne Ğ1. », « seed a minima · 1 vote » ; sur un téléphone, les gestes du titre sans survol (réordonner sur un téléphone : C35) |
| C26 | Le titre du document | groupe d'essai : sous le titre, « Proposer un autre titre » ; « Acte d'engagement de la certification » ; « Pour » ; une deuxième personne vote « Pour » si cette voix ne suffit pas ; lire en anglais | sous le titre, une ligne : « Titre du document · seed a minima · 0 vote », les crans « inertie 4 / 5 · haute », deux gestes ; le panneau nommé « Proposer un autre titre » ; le titre proposé se vote **sous le titre** (« 1 titre proposé »), jamais parmi les propositions ; à la voix qui suffit : « Le titre « … » est entré en vigueur. », le document change de titre, son vote reste déplié sous le titre, son inertie dite une fois (« Inertie · 4 / 5 · haute ») ; en anglais, l'ancien titre traduit, marqué « translation needs review » | | C26 | Le titre du document | groupe d'essai : sous le titre, « Proposer un autre titre » ; « Acte d'engagement de la certification » ; « Pour » ; une deuxième personne vote « Pour » si cette voix ne suffit pas ; lire en anglais | sous le titre, une ligne : « Titre du document · seed a minima · 0 vote », les crans « inertie 4 / 5 · haute », deux gestes ; le panneau nommé « Proposer un autre titre » ; le titre proposé se vote **sous le titre** (« 1 titre proposé »), jamais parmi les propositions ; à la voix qui suffit : « Le titre « … » est entré en vigueur. », le document change de titre, son vote reste déplié sous le titre, son inertie dite une fois (« Inertie · 4 / 5 · haute ») ; en anglais, l'ancien titre traduit, marqué « translation needs review » |
| C27 | La participation ramenée dans ses bornes | un groupe de 4 dont la médiane est 2,5 votants, ramenée à 50 % (l'automate fait répondre ces chiffres au serveur) : « Réglages de la formule » | « 3 votants sur 4 (62,5 %) : la médiane des 12 propositions votées depuis un an. » — la part de la mesure elle-même, jamais 3 sur 4 arrondi d'abord ; puis « Ramenée entre 5 % et 50 % de l'électorat : le groupe demande ses voix pour comme si 2 personnes votaient (50 %). » ; « Part exigée : la part de « pour » demandée, à 2 votants comme d'habitude. » | | C27 | La participation ramenée dans ses bornes | un groupe de 4 dont la médiane est 2,5 votants, ramenée à 50 % (l'automate fait répondre ces chiffres au serveur) : « Réglages de la formule » | « 3 votants sur 4 (62,5 %) : la médiane des 12 propositions votées depuis un an. » — la part de la mesure elle-même, jamais 3 sur 4 arrondi d'abord ; puis « Ramenée entre 5 % et 50 % de l'électorat : le groupe demande ses voix pour comme si 2 personnes votaient (50 %). » ; « Part exigée : la part de « pour » demandée, à 2 votants comme d'habitude. » |
| C28 | Objection « redit » ; sur la version retenue, « contre » et retrait, jamais « pour » | groupe d'essai, à trois (Aude, Oscar, Vera) : Aude propose un nouvel article qui répète « Unicité du compte » ; Oscar, dans « Détails » de cette proposition → « Faire une objection » → « Redit », « En vigueur — Unicité du compte », un motif → « Envoyer l'objection » ; Vera déplie son vote → « Contre », puis « Retirer mon vote » ; Vera ouvre « Voter en lot » → « Tout le document » : « Tout pour », puis « Tout contre », puis « Vider » ; Aude ouvre « Messages » → « Modifier l'article visé », complète le texte et soumet ; Oscar ouvre « Messages » → « Lever l'objection » ; Vera déplie de nouveau son vote | « Objection enregistrée : jusqu'à sa levée, personne ne peut plus voter pour la dernière arrivée des deux versions. » ; chez Oscar, « « … » redit « Unicité du compte » », « personne ne peut plus voter pour cette version », « Lever l'objection » ; chez Vera, « Une objection retient cette version : jusqu'à sa levée, personne ne peut plus voter pour. Tu peux voter contre ou retirer ton vote ; à la levée, elle n'entre en vigueur qu'avec les voix encore là. », « Elle redit « Unicité du compte ». », pas de « Pour », mais « Contre », la ligne marquée « retenue par une objection » ; après « Contre » : « Vote enregistré. », « Ton vote : contre », « 0 pour · 1 contre », et « Retirer mon vote » ; après le retrait : « Vote retiré. », « 0 pour · 0 contre », toujours pas de « Pour » ; dans le panier, la version retenue montre « Contre » sans « Pour », avec « une objection la retient : contre ou retrait, pas de « pour » » ; « Tout pour » la laisse de côté et le dit (« Tu as tout mis pour, sauf 1 version qu'une objection retient : sur elle, tu peux voter contre ou retirer ton vote. », le nombre suivant les versions retenues du document) ; « Tout contre » la prend (« Contre » enfoncé) ; chez Aude, « Messages, 1 non lu », le message « Oscar fait une objection : ta version « … » redit « Unicité du compte »… Pour répondre, modifie l'article visé. », puis le panneau « Proposer » sur Unicité du compte, partant de son texte, avec « Cette proposition répond à une objection… » ; chez Oscar, « Ton objection sur « … » a reçu une réponse. », une échéance, « Lever l'objection » et « Réitérer l'objection » ; levée : « Objection levée. », le message dit « objection levée » sans plus aucun geste ; Vera peut de nouveau voter, « Pour » compris | | C28 | Objection « redit » ; sur la version retenue, « contre » et retrait, jamais « pour » | groupe d'essai, à trois (Aude, Oscar, Vera) : Aude propose un nouvel article qui répète « Unicité du compte » ; Oscar, dans « Détails » de cette proposition → « Faire une objection » → « Redit », « En vigueur — Unicité du compte », un motif → « Envoyer l'objection » ; Vera déplie son vote → « Contre », puis « Retirer mon vote » ; Vera ouvre « Voter en lot » → « Tout le document » : « Tout pour », puis « Tout contre », puis « Vider » ; Aude ouvre « Messages » → « Modifier l'article visé », complète le texte et soumet ; Oscar ouvre « Messages » → « Lever l'objection » ; Vera déplie de nouveau son vote | « Objection enregistrée : jusqu'à sa levée, personne ne peut plus voter pour la dernière arrivée des deux versions. » ; chez Oscar, « « … » redit « Unicité du compte » », « personne ne peut plus voter pour cette version », « Lever l'objection » ; chez Vera, « Une objection retient cette version : jusqu'à sa levée, personne ne peut plus voter pour. Tu peux voter contre ou retirer ton vote ; à la levée, elle n'entre en vigueur qu'avec les voix encore là. », « Elle redit « Unicité du compte ». », pas de « Pour », mais « Contre », la ligne marquée « retenue par une objection » ; après « Contre » : « Vote enregistré. », « Ton vote : contre », « 0 pour · 1 contre », et « Retirer mon vote » ; après le retrait : « Vote retiré. », « 0 pour · 0 contre », toujours pas de « Pour » ; dans le panier, la version retenue montre « Contre » sans « Pour », avec « une objection la retient : contre ou retrait, pas de « pour » » ; « Tout pour » la laisse de côté et le dit (« Tu as tout mis pour, sauf 1 version qu'une objection retient : sur elle, tu peux voter contre ou retirer ton vote. », le nombre suivant les versions retenues du document) ; « Tout contre » la prend (« Contre » enfoncé) ; chez Aude, « Messages, 1 non lu », le message « Oscar fait une objection : ta version « … » redit « Unicité du compte »… Pour répondre, modifie l'article visé. », puis le panneau « Proposer » sur Unicité du compte, partant de son texte, avec « Cette proposition répond à une objection… » ; chez Oscar, « Ton objection sur « … » a reçu une réponse. », une échéance, « Lever l'objection » et « Réitérer l'objection » ; levée : « Objection levée. », le message dit « objection levée » sans plus aucun geste ; Vera peut de nouveau voter, « Pour » compris |
| C29 | Objection « contredit », levée à l'échéance | groupe d'essai : Aude propose un article qui contredit « Réciprocité » ; Oscar fait une objection « Contredit » ; Aude déplie le vote de sa proposition → « Reformuler », change le fond, « Enregistrer la correction » ; Oscar ne fait rien ; trois jours passent (l'automate avance l'horloge du serveur : `POST /api/dev/clock`, connexion de développement seulement) | chez Aude : « Elle contredit « Réciprocité ». », « Pour qu'elle se vote à nouveau, reformule-la… », « Reformuler » ouvre « Détails » avec le formulaire de modification ; « Nouvelle version enregistrée : les votants devront reconfirmer. », puis « Une réponse est arrivée : Oscar lève ou réitère l'objection d'ici le … » ; trois jours après : l'objection dit « levée : 3 jours sans suite », la proposition se vote de nouveau, le message d'Oscar dit « objection levée : 3 jours sans suite », sans geste | | C29 | Objection « contredit », levée à l'échéance | groupe d'essai : Aude propose un article qui contredit « Réciprocité » ; Oscar fait une objection « Contredit » ; Aude déplie le vote de sa proposition → « Reformuler », change le fond, « Enregistrer la correction » ; Oscar ne fait rien ; trois jours passent (l'automate avance l'horloge du serveur : `POST /api/dev/clock`, connexion de développement seulement) | chez Aude : « Elle contredit « Réciprocité ». », « Pour qu'elle se vote à nouveau, reformule-la… », « Reformuler » ouvre « Détails » avec le formulaire de modification ; « Nouvelle version enregistrée : les votants devront reconfirmer. », puis « Une réponse est arrivée : Oscar lève ou réitère l'objection d'ici le … » ; trois jours après : l'objection dit « levée : 3 jours sans suite », la proposition se vote de nouveau, le message d'Oscar dit « objection levée : 3 jours sans suite », sans geste |
| C30 | La coquille d'un autre, validée par l'auteur | groupe d'essai : Aude propose « Clé unique et vivante » ; Vera, dans « Détails » → « Corriger une coquille », apostrophes typographiques → « Enregistrer la correction » ; Aude ouvre « Messages » → « Valider » | chez Vera : « Ta correction attend l'auteur du texte : elle s'applique quand il la valide, ou d'elle-même le … » ; le texte ne change pas ; « Coquilles proposées » montre le diff, « proposée par Vera », « en attente : s'applique d'elle-même le … » ; chez Aude : « Vera propose une correction de coquille dans ta version « Clé unique et vivante ». », le diff, une échéance, « Valider » / « Refuser » ; « Correction appliquée. », le message dit « correction appliquée » ; le texte porte la correction, l'historique « coquille corrigée · par Vera · validée par Aude » | | C30 | La coquille d'un autre, validée par l'auteur | groupe d'essai : Aude propose « Clé unique et vivante » ; Vera, dans « Détails » → « Corriger une coquille », apostrophes typographiques → « Enregistrer la correction » ; Aude ouvre « Messages » → « Valider » | chez Vera : « Ta correction attend l'auteur du texte : elle s'applique quand il la valide, ou d'elle-même le … » ; le texte ne change pas ; « Coquilles proposées » montre le diff, « proposée par Vera », « en attente : s'applique d'elle-même le … » ; chez Aude : « Vera propose une correction de coquille dans ta version « Clé unique et vivante ». », le diff, une échéance, « Valider » / « Refuser » ; « Correction appliquée. », le message dit « correction appliquée » ; le texte porte la correction, l'historique « coquille corrigée · par Vera · validée par Aude » |
| C31 | Coquille sur un texte en vigueur | groupe d'essai : une administratrice (Ada) ouvre le groupe ; Vera, sur « Raison d'être » → « Le vote » → « Coquilles, traductions, objections, historique » → « Corriger une coquille », « C'est le seul » → « C’est le seul » ; Ada ouvre « Messages » → « Valider » | chez Vera : « Ta correction attend un administrateur, ce texte venant du seed… » ; le texte en vigueur ne change pas (« C'est le seul ») ; la correction en attente se lit dans « Détails » ; chez Ada : « Vera propose une correction de coquille dans « Raison d'être », un texte du seed : un administrateur la valide. » ; après « Valider », le texte en vigueur porte « C’est le seul » et l'historique « validée par Ada » | | C31 | Coquille sur un texte en vigueur | groupe d'essai : une administratrice (Ada) ouvre le groupe ; Vera, sur « Raison d'être » → « Le vote » → « Coquilles, traductions, objections, historique » → « Corriger une coquille », « C'est l'unique » → « C’est l’unique » ; Ada ouvre « Messages » → « Valider » | chez Vera : « Ta correction attend un administrateur, ce texte venant du seed… » ; le texte en vigueur ne change pas (« C'est l'unique enjeu ») ; la correction en attente se lit dans « Détails » ; chez Ada : « Vera propose une correction de coquille dans « Raison d'être », un texte du seed : un administrateur la valide. » ; après « Valider », le texte en vigueur porte « C’est l’unique enjeu » et l'historique « validée par Ada » |
| C32 | Lâcher ou garder un bulletin | Monnaie libre, un portefeuille dans le navigateur (Eve, chaîne simulée), « Propositions en cours » → Document de révocation : « Contre » le nœud éteint ; puis « Contre », fermer la fenêtre pendant que le portefeuille demande, refuser dans le portefeuille ; puis « Contre », fermer, signer dans le portefeuille ; une autre personne, sans portefeuille : « Contre » → « Passer par Ğecko », fermer, payer depuis un téléphone | nœud éteint : « La chaîne Ğ1 ne répond pas. Réessaie dans un moment. », le bulletin lâché aussitôt, rien « en attente » sous l'article ; fenêtre fermée puis refus : lâché ; fenêtre fermée puis signature : gardé, et la chaîne le confirme sans la page (« Ton vote : contre · inscrit sur la chaîne Ğ1 ») ; Ğecko, fenêtre fermée : « En attente de la chaîne Ğ1 : contre. », puis confirmé sans la page | | C32 | Lâcher ou garder un bulletin | Monnaie libre, un portefeuille dans le navigateur (Eve, chaîne simulée), « Propositions en cours » → Document de révocation : « Contre » le nœud éteint ; puis « Contre », fermer la fenêtre pendant que le portefeuille demande, refuser dans le portefeuille ; puis « Contre », fermer, signer dans le portefeuille ; une autre personne, sans portefeuille : « Contre » → « Passer par Ğecko », fermer, payer depuis un téléphone | nœud éteint : « La chaîne Ğ1 ne répond pas. Réessaie dans un moment. », le bulletin lâché aussitôt, rien « en attente » sous l'article ; fenêtre fermée puis refus : lâché ; fenêtre fermée puis signature : gardé, et la chaîne le confirme sans la page (« Ton vote : contre · inscrit sur la chaîne Ğ1 ») ; Ğecko, fenêtre fermée : « En attente de la chaîne Ğ1 : contre. », puis confirmé sans la page |
| C33 | Le reçu de ton vote | Monnaie libre, un portefeuille : « Contre » sur Ne jamais certifier seul (« Propositions en cours »), « Télécharger ton reçu », « Tes bulletins » ; sur « Tes bulletins », « Fichier du reçu » : le reçu ; puis coller le reçu avec un choix changé, « Vérifier » ; une autre personne ouvre « Tes bulletins » | le reçu `recu-vote-<date>-<id>.json` : les votes, le sel, la remarque `ld1:…`, « confirmed », l'identité « Alice » ; « Tes bulletins de vote » : « Compté pour l'identité Ğ1 « Alice » » et la remarque ; « Le reçu tient : ses votes et son sel donnent bien ce commentaire. », « Ne jamais certifier seul : contre » ; changé : « Le reçu ne tient pas » ; l'autre personne : « Tu n'as encore envoyé aucun bulletin par la chaîne Ğ1. », et le reçu lui est refusé | | C33 | Le reçu de ton vote | Monnaie libre, un portefeuille : « Contre » sur Ne jamais certifier seul (« Propositions en cours »), « Télécharger ton reçu », « Tes bulletins » ; sur « Tes bulletins », « Fichier du reçu » : le reçu ; puis coller le reçu avec un choix changé, « Vérifier » ; une autre personne ouvre « Tes bulletins » | le reçu `recu-vote-<date>-<id>.json` : les votes, le sel, la remarque `ld1:…`, « confirmed », l'identité « Alice » ; « Tes bulletins de vote » : « Compté pour l'identité Ğ1 « Alice » » et la remarque ; « Le reçu tient : ses votes et son sel donnent bien ce commentaire. », « Ne jamais certifier seul : contre » ; changé : « Le reçu ne tient pas » ; l'autre personne : « Tu n'as encore envoyé aucun bulletin par la chaîne Ğ1. », et le reçu lui est refusé |
| C34 | Le vote simulé, la chaîne fermée (ADR 0012) | Monnaie libre sur un serveur sans compte des votes (l'automate ferme la chaîne du serveur jetable, puis la rouvre) : « Propositions en cours » → Logiciel auditable → « Contre », sans portefeuille ; puis « Voter en lot », « Contre » encore, « Voter (1) » ; puis « Tes bulletins » | « Voter en lot » est là, marqué « vote simulé » ; aucune fenêtre de portefeuille ; « Vote simulé. », **jamais** « Vote enregistré. » ; « Ton vote : contre · simulé » aussitôt, et un « contre » de plus dans les totaux ; dans l'API, `myVoteState` « simulated » et `tallySimulated` ; le panier : « 1 vote simulé. », jamais « enregistré » ; dans « Tes bulletins » : « Simulé : compté pour « Sacha » tant que les votes simulés ne sont pas effacés », sans bloc (l'ouverture de la chaîne n'efface rien : c'est un acte humain, sans date promise) | | C34 | Le vote simulé, la chaîne fermée (ADR 0012) | Monnaie libre sur un serveur sans compte des votes (l'automate ferme la chaîne du serveur jetable, puis la rouvre) : « Propositions en cours » → Logiciel auditable → « Contre », sans portefeuille ; puis « Voter en lot », « Contre » encore, « Voter (1) » ; puis « Tes bulletins » | « Voter en lot » est là, marqué « vote simulé » ; aucune fenêtre de portefeuille ; « Vote simulé. », **jamais** « Vote enregistré. » ; « Ton vote : contre · simulé » aussitôt, et un « contre » de plus dans les totaux ; dans l'API, `myVoteState` « simulated » et `tallySimulated` ; le panier : « 1 vote simulé. », jamais « enregistré » ; dans « Tes bulletins » : « Simulé : compté pour « Sacha » tant que les votes simulés ne sont pas effacés », sans bloc (l'ouverture de la chaîne n'efface rien : c'est un acte humain, sans date promise) |
| C35 | Réordonner une section, par poignées, puis voter (lot U) | groupe d'essai : à la fin des « Engagements fondamentaux », la ligne « Ordre de la section » → « Réordonner » ; glisser la poignée de Réciprocité sur Unicité du compte ; au clavier, flèche haut puis bas ; « Descendre « Réciprocité » » ; cliquer Réciprocité puis la place 2 ; « Annuler », puis « Réordonner » et « Monter « Réciprocité » » ; « Proposer cet ordre » ; « Pour » (une deuxième voix si la sienne ne suffit pas) ; puis, sur un téléphone, dans Monnaie libre : « Tout déplier », « Ordre des articles · Engagements techniques » → « Réordonner » | la ligne ne répète aucun article ; « Réordonner » : les articles de la section, en vigueur ou seulement proposés (« Engagements fondamentaux » marqué « proposé »), sur place (pas de panneau), une poignée devant chacun, les articles en vigueur de la section repliés dans la liste (pas deux fois) ; chaque geste annonce la place (« « Réciprocité » en place 2 sur 3. ») ; « Proposer cet ordre » éteint sur l'ordre en vigueur, et il le dit à côté, lu aussi comme sa description (« C'est l'ordre en vigueur : déplace au moins un article. ») : la phrase s'en va dès qu'un article bouge et revient quand l'ordre redevient celui en vigueur (lot U2) ; « Annuler » rend la section telle qu'elle se lisait ; « Ordre proposé au vote. », son vote déplié aussitôt sous la ligne, l'ordre proposé en clair, « 1 ordre proposé » ; « Vote enregistré. » ; en vigueur, la section se lit dans le nouvel ordre, « adopté le … » ; sur un téléphone : 11 articles, rien ne déborde de la page, l'article, sa poignée et ses flèches font au moins 44 px | | C35 | Réordonner une section, par poignées, puis voter (lot U) | groupe d'essai : à la fin des « Engagements fondamentaux », la ligne « Ordre de la section » → « Réordonner » ; glisser la poignée de Réciprocité sur Responsabilité civique ; au clavier, flèche haut puis bas ; « Descendre « Réciprocité » » ; cliquer Réciprocité puis la place 2 ; « Annuler », puis « Réordonner » et deux fois « Monter « Réciprocité » » ; « Proposer cet ordre » ; « Pour » (une deuxième voix si la sienne ne suffit pas) ; puis, sur un téléphone, dans Monnaie libre : « Tout déplier », « Ordre des articles · Engagements techniques » → « Réordonner » | la ligne ne répète aucun article ; « Réordonner » : les articles de la section, en vigueur ou seulement proposés (« Engagements fondamentaux » marqué « proposé »), sur place (pas de panneau), une poignée devant chacun, les articles en vigueur de la section repliés dans la liste (pas deux fois) ; chaque geste annonce la place (« « Réciprocité » en place 3 sur 4. ») ; « Proposer cet ordre » éteint sur l'ordre en vigueur, et il le dit à côté, lu aussi comme sa description (« C'est l'ordre en vigueur : déplace au moins un article. ») : la phrase s'en va dès qu'un article bouge et revient quand l'ordre redevient celui en vigueur (lot U2) ; « Annuler » rend la section telle qu'elle se lisait ; « Ordre proposé au vote. », son vote déplié aussitôt sous la ligne, l'ordre proposé en clair, « 1 ordre proposé » ; « Vote enregistré. » ; en vigueur, la section se lit dans le nouvel ordre, « adopté le … » ; sur un téléphone : 11 articles, rien ne déborde de la page, l'article, sa poignée et ses flèches font au moins 44 px |
| C36 | Combien de oui pour passer, combien de non pour bloquer (ADR 0013 ; Yvv, 02/11) | Monnaie libre : la Raison d'être (en tête) → « Le vote » ; « Tout déplier » ; puis, l'automate donnant à une proposition du groupe d'essai les totaux 9 pour · 4 contre (cran 2, quorum 12), puis 3 pour · 0 contre | avant tout vote, sous l'article : « 9 oui sur 12 votants pour passer », au survol « Quorum : 12 votants. En dessous, les votants qui manquent comptent comme « non ». » ; la ligne de la Proposition seed, juste au-dessus, ne redit plus les totaux ni les oui (lot U2) ; dans la liste, en bref : « 39 oui sur 50 » (cran 3) ; à 9 pour · 4 contre : « 11 oui pour passer · 4 non pour bloquer » sous l'article, « passe à 11 oui · bloquée à 4 non » dans la liste, « Il manque 2 voix pour. » ; à 3 pour · 0 contre : « 9 oui pour passer · le quorum la bloque », « passe à 9 oui » | | C36 | Combien de oui pour passer, combien de non pour bloquer (ADR 0013 ; Yvv, 02/11) | Monnaie libre : la Raison d'être (en tête) → « Le vote » ; « Tout déplier » ; puis, l'automate donnant à une proposition du groupe d'essai les totaux 9 pour · 4 contre (cran 2, quorum 12), puis 3 pour · 0 contre | avant tout vote, sous l'article : « 9 oui sur 12 votants pour passer », au survol « Quorum : 12 votants. En dessous, les votants qui manquent comptent comme « non ». » ; la ligne de la Proposition seed, juste au-dessus, ne redit plus les totaux ni les oui (lot U2) ; dans la liste, en bref : « 39 oui sur 50 » (cran 3) ; à 9 pour · 4 contre : « 11 oui pour passer · 4 non pour bloquer » sous l'article, « passe à 11 oui · bloquée à 4 non » dans la liste, « Il manque 2 voix pour. » ; à 3 pour · 0 contre : « 9 oui pour passer · le quorum la bloque », « passe à 9 oui » |
| C37 | Le quorum d'un article, par son autrice, avant le premier vote (ADR 0013) | groupe d'essai : proposer un article, puis son vote → « Quorum » : 3 → « Fixer ce quorum » ; « Revenir au défaut (1) » ; 100000 → « Fixer ce quorum » ; une autre personne ouvre le même vote, puis vote « contre » ; l'autrice tente 2 | le réglage n'apparaît qu'à l'autrice (`canSetQuorum`) : « Quorum · 1 votant », « Par défaut, celui de son cran : 1 votant. », le champ « Quorum de l'article » ; « Quorum fixé : 3 votants. », la ligne dit « … oui sur 3 votants pour passer » ; « Quorum revenu au défaut : 1 votant. » ; hors bornes (400) : « Ce quorum sort des bornes : au moins 2 votants (1 dans le groupe d'essai), au plus … » ; l'autre personne ne voit pas le réglage ; après son vote (409) : « Quelqu'un a déjà voté sur cet article : son quorum ne change pas. » (lot T2), puis le réglage disparaît | | C37 | Le quorum d'un article, par son autrice, avant le premier vote (ADR 0013) | groupe d'essai : proposer un article, puis son vote → « Quorum » : 3 → « Fixer ce quorum » ; « Revenir au défaut (1) » ; 100000 → « Fixer ce quorum » ; une autre personne ouvre le même vote, puis vote « contre » ; l'autrice tente 2 | le réglage n'apparaît qu'à l'autrice (`canSetQuorum`) : « Quorum · 1 votant », « Par défaut, celui de son cran : 1 votant. », le champ « Quorum de l'article » ; « Quorum fixé : 3 votants. », la ligne dit « … oui sur 3 votants pour passer » ; « Quorum revenu au défaut : 1 votant. » ; hors bornes (400) : « Ce quorum sort des bornes : au moins 2 votants (1 dans le groupe d'essai), au plus … » ; l'autre personne ne voit pas le réglage ; après son vote (409) : « Quelqu'un a déjà voté sur cet article : son quorum ne change pas. » (lot T2), puis le réglage disparaît |
| C38 | Ce que compte l'en-tête ; un changement d'inertie d'un ordre ou du titre (lot U2) | Monnaie libre : lire la ligne de faits sous le résumé ; « Tout déplier », compter les versions de la liste ; puis, dans le groupe d'essai, proposer un changement d'inertie de l'ordre de « Conclusion » et du titre (l'automate passe par `POST /api/units/{id}/inertia`, puis les retire) | « 0 article en vigueur · 3 Propositions seed · N propositions en cours », N le nombre de versions que montre la liste : les Propositions seed lues en tête sont dites à part, les ordres et titres proposés ne sont pas comptés (ils se votent à la ligne de leur module) ; sous le titre, la pastille « 1 changement d'inertie proposé », qui déplie son vote sous le titre ; à la fin de « Conclusion », la même pastille sur la ligne d'ordre, qui déplie son vote là ; aucun « inertie vers … » dans « Propositions en cours », et l'en-tête compte toujours ce que la liste montre | | C38 | Ce que compte l'en-tête ; un changement d'inertie d'un ordre ou du titre (lot U2) | Monnaie libre : lire la ligne de faits sous le résumé ; « Tout déplier », compter les versions de la liste ; puis, dans le groupe d'essai, proposer un changement d'inertie de l'ordre de « Conclusion » et du titre (l'automate passe par `POST /api/units/{id}/inertia`, puis les retire) | « 0 article en vigueur · 4 Propositions seed · N propositions en cours », N le nombre de versions que montre la liste : les Propositions seed lues en tête sont dites à part, les ordres et titres proposés ne sont pas comptés (ils se votent à la ligne de leur module) ; sous le titre, la pastille « 1 changement d'inertie proposé », qui déplie son vote sous le titre ; à la fin de « Conclusion », la même pastille sur la ligne d'ordre, qui déplie son vote là ; aucun « inertie vers … » dans « Propositions en cours », et l'en-tête compte toujours ce que la liste montre |
## Au-delà de la liste ## Au-delà de la liste
@@ -0,0 +1,296 @@
# Textes d'amorce et structure de l'Acte d'engagement (lot T4)
> Préparé le 2026-11-03 pour ta relecture, Yvv (lot T4, branche `lot/t4-amorce`), d'après ta
> demande du 03/11 vers 20 h 38 : « Modif des textes Acte engagement » (I1, E1, un article
> nouveau « Responsabilité civique », E2) et « les 3 derniers modules ne sont pas de votes :
> ordonnancement, inertie, et formule de vote sont des infos de fonctionnement […] Vire les 3 du
> bas de la liste. » Les textes sont dans `seeds/acte-engagement-certification.json` et dans des
> amendements gardés pour la production ; la décision durable est l'ADR 0014. **Rien n'est en
> ligne.** L'interface des informations de fonctionnement est le lot U3.
## À confirmer : les choix faits pour toi
Chacun est appliqué ; dis lequel tu changes.
1. **« il y a une et une seule clé certifiante ».** Ta phrase disait « derrière un être humain,
il n'y a une et une seule clé certifiante ». Lu comme une coquille, sur le parallèle avec
« il y a un et un seul être humain vivant ». L'autre lecture serait « il n'y a qu'une seule
clé » (le texte d'avant).
2. **I1 en trois paragraphes**, le premier en italique entre « », comme aujourd'hui, avec les
espaces insécables du texte d'avant (à l'intérieur des guillemets, devant le point-virgule).
3. **Tes virgules, gardées telles quelles** : « de nature contractuelle, qui fonde l'usage »
(I1) et « qui s'engagent elles-mêmes, à scrupuleusement respecter » (E2). La seconde sépare
le verbe de son complément ; sans elle : « qui s'engagent elles-mêmes à scrupuleusement
respecter ». En anglais et en espagnol, la première est rendue, la seconde non (elle n'y
aurait pas de sens).
4. **Le deuxième paragraphe d'I1** est le tien mot pour mot : « C'est l'unique enjeu de la
certification et de votre engagement, il donne à notre toile fiduciaire sa valeur : … ».
5. **« ces trois principes fondamentaux »** (E2) se lit, comme « ces deux présents engagements »
avant, sur les articles de la section : E1, E12 et E2.
6. **L'article nouveau** : code **E12**, Proposition seed (ouverte, mise en avant, 0 vote), au
**cran 2** comme I1, E1 et E2, section « fondamental », **entre E1 et E2**. Titres : « Civic
responsibility », « Responsabilidad cívica ». Le code : E3 à E11 existent, E12 est le premier
libre de la famille des engagements ; c'est un identifiant, la place vient de l'ordre de la
section (ADR 0009), pas du numéro. Aucune unité ne porte E12, en production non plus (les
articles de membre prennent des codes en N).
7. **Les titres restent** : « Raison d'être », « Unicité du compte », « Réciprocité ».
8. **Les traductions** : l'anglais britannique et les guillemets “ ” des textes d'aujourd'hui ;
l'espagnol avec «» serrés. « votre engagement » est rendu « your commitment » et « su
compromiso » (le vouvoiement, comme le français). « l'unique enjeu » : « the one thing at
stake », « lo único que está en juego ».
9. **En production, rien n'est effacé** (ADR 0014) : les sept articles et les trois ordres
sortent du document par une marque (`units.retired_at`), et seulement si personne n'y a
laissé de trace. L'ordre de « fondamental » prend E12 entre E1 et E2 tant que personne n'a
voté sur cet ordre ; sinon E12 va en fin de section, comme tout nouvel article.
## Le document après T4
Cinq sections, 27 articles : introduction (I1, I2) ; fondamental (T1, E1, **E12**, E2) ;
technique (T2, E3 à E7, T3, E8 à E11) ; conclusion (K1, K2) ; annexe (X1 à X2.3). Quatre Propositions
seed au cran 2 : I1, E1, E12, E2. Aucun article en vigueur au départ (ADR 0011). « Modules à
voter » : 33 (27 articles, le titre, l'ordre de 5 sections), contre 41 avant.
## Les textes, avant et après
Les blocs sont les textes exacts du seed (Markdown : `*…*` est l'italique), espaces insécables compris. « Avant » : le texte en ligne aujourd'hui, celui du seed de M8.
### I1 — Raison d'être
#### I1 · Français (fait foi)
Titre : **Raison d'être**
Avant :
```markdown
*« Derrière une clé il n'y a qu'un seul être humain vivant ; derrière un être humain, il n'y a qu'une seule clé certifiante. »*
C'est le seul et unique propos de la certification, qui donne à notre toile fiduciaire sa valeur. Nous pouvons nous fier à l'unicité et l'intégrité de tout geste signé par cette clé. C'est l'enjeu de la certification.
Cet acte d'engagement est par ailleurs le seul acte de nature contractuelle qui fonde l'usage de la première monnaie libre.
```
Après :
```markdown
*« Derrière une clé il y a un et un seul être humain vivant ; derrière un être humain, il y a une et une seule clé certifiante. »*
C'est l'unique enjeu de la certification et de votre engagement, il donne à notre toile fiduciaire sa valeur : pouvoir nous fier à l'unicité et l'intégrité de tout geste signé par cette clé.
Cet acte d'engagement est par ailleurs le seul acte de nature contractuelle, qui fonde l'usage de la première monnaie libre.
```
#### I1 · English
Titre : **Purpose**
Avant :
```markdown
*“Behind a key there is only one living human being; behind a human being, there is only one certifying key.”*
This is the one and only purpose of certification, which gives our fiduciary web its value. We can rely on the uniqueness and integrity of every action signed with this key. That is what is at stake in certification.
This commitment act is, moreover, the only act of a contractual nature on which the use of the first libre currency is founded.
```
Après :
```markdown
*“Behind a key there is one and only one living human being; behind a human being, there is one and only one certifying key.”*
This is the one thing at stake in certification and in your commitment; it gives our fiduciary web its value: being able to rely on the uniqueness and integrity of every action signed with this key.
This commitment act is, moreover, the only act of a contractual nature, which founds the use of the first libre currency.
```
#### I1 · Español
Titre : **Razón de ser**
Avant :
```markdown
*«Detrás de una clave no hay más que un solo ser humano vivo; detrás de un ser humano, no hay más que una sola clave certificadora.»*
Este es el propósito único y exclusivo de la certificación, que da su valor a nuestra red fiduciaria. Podemos fiarnos de la unicidad y la integridad de toda acción firmada con esta clave. Eso es lo que está en juego en la certificación.
Esta acta de compromiso es, además, el único acto de naturaleza contractual en el que se funda el uso de la primera moneda libre.
```
Après :
```markdown
*«Detrás de una clave hay un solo y único ser humano vivo; detrás de un ser humano, hay una sola y única clave certificadora.»*
Es lo único que está en juego en la certificación y en su compromiso; da su valor a nuestra red fiduciaria: poder fiarnos de la unicidad y la integridad de toda acción firmada con esta clave.
Esta acta de compromiso es, además, el único acto de naturaleza contractual, que funda el uso de la primera moneda libre.
```
### E1 — Unicité du compte
#### E1 · Français (fait foi)
Titre : **Unicité du compte**
Avant :
```markdown
Je m'engage sur l'honneur à n'avoir et n'avoir jamais qu'un seul et unique compte cocréateur de monnaie G1.
```
Après :
```markdown
Je m'engage sur l'honneur à n'avoir et n'avoir jamais qu'un seul et unique compte certifiant.
```
#### E1 · English
Titre : **Uniqueness of the account**
Avant :
```markdown
I commit on my honour to have, now and ever, no more than one single and unique account co-creating G1 money.
```
Après :
```markdown
I commit on my honour to have, now and ever, no more than one single and unique certifying account.
```
#### E1 · Español
Titre : **Unicidad de la cuenta**
Avant :
```markdown
Me comprometo por mi honor a no tener, ahora ni nunca, más que una sola y única cuenta cocreadora de moneda G1.
```
Après :
```markdown
Me comprometo por mi honor a no tener, ahora ni nunca, más que una sola y única cuenta certificadora.
```
### E12 — Responsabilité civique (nouveau)
#### E12 · Français (fait foi)
Titre : **Responsabilité civique**
```markdown
Je déclare sur l'honneur avoir la capacité légale et physique de signer un contrat et d'en assumer la responsabilité civique, pour certifier à mon tour.
```
#### E12 · English
Titre : **Civic responsibility**
```markdown
I declare on my honour that I have the legal and physical capacity to sign a contract and to assume its civic responsibility, in order to certify in my turn.
```
#### E12 · Español
Titre : **Responsabilidad cívica**
```markdown
Declaro por mi honor tener la capacidad legal y física de firmar un contrato y de asumir su responsabilidad cívica, para certificar a mi vez.
```
### E2 — Réciprocité
#### E2 · Français (fait foi)
Titre : **Réciprocité**
Avant :
```markdown
Je m'engage sur l'honneur à ne certifier que des personnes physiques qui respectent scrupuleusement ces deux présents engagements fondamentaux.
```
Après :
```markdown
Je m'engage sur l'honneur à ne certifier que des personnes physiques qui s'engagent elles-mêmes, à scrupuleusement respecter ces trois principes fondamentaux.
```
#### E2 · English
Titre : **Reciprocity**
Avant :
```markdown
I commit on my honour to certify only natural persons who scrupulously respect these two fundamental commitments.
```
Après :
```markdown
I commit on my honour to certify only natural persons who themselves commit to scrupulously respecting these three fundamental principles.
```
#### E2 · Español
Titre : **Reciprocidad**
Avant :
```markdown
Me comprometo por mi honor a certificar únicamente a personas físicas que respeten escrupulosamente estos dos compromisos fundamentales.
```
Après :
```markdown
Me comprometo por mi honor a certificar únicamente a personas físicas que se comprometan ellas mismas a respetar escrupulosamente estos tres principios fundamentales.
```
## Ce qui sort du document
| Section | Article | Titre |
|---|---|---|
| formule | F1 | Formule de vote |
| formule | F1.1 | Formule du seuil WoT |
| formule | F1.2 | Paramètres par défaut |
| formule | F1.3 | Processus de dépôt officiel |
| inertie | N1 | Réglage de l'inertie |
| inertie | N1.1 | Niveaux d'inertie |
| ordonnancement | O1 | Ordonnancement du document |
Et l'ordre des articles de chacune de ces trois sections (`ordre.formule`, `ordre.inertie`,
`ordre.ordonnancement`). Ils ne sont plus ni listés, ni votables (vote, proposition, coquille,
objection, inertie, quorum : refusés), ni comptés, ni publiés. Aucun autre article ne les
cite.
**Leurs textes ne se perdent pas.** Ce qu'ils disaient de vrai (la formule, les crans, le
quorum, chaque phrase vérifiée par un test des lots T à T3c, `t3c-liste-fermee.md`) est la
référence de l'écran du lot U3, qui les montrera hors du vote, à leur place dans l'interface.
Leurs derniers textes restent dans `crates/ld-server/tests/fixtures/seed-m8/` et, en
production, dans leurs lignes.
## En production
- **I1, E1, E2** : trois amendements gardés (`2026-11-03-i1-amorce`, `-e1-amorce`,
`-e2-amorce`) réécrivent la Proposition seed, une fois par document, seulement si le texte en
place est celui qu'on attend (son empreinte) et que personne n'y a touché : un vote, un
bulletin, une coquille, une traduction de membre, une objection suffisent à garder le texte,
avec sa raison. L'ancien texte reste dans l'historique de la version.
- **E12** : un ajout gardé (`2026-11-03-e12-responsabilite-civique`), une fois par document.
- **Formule, inertie, ordonnancement** : le retrait `2026-11-03-fonctionnement-hors-vote`,
une fois par document, tous ou aucun.
- **La file de publication** (suspendue jusqu'au premier texte en vigueur) : rien n'y est
effacé. Les lignes déjà écrites pour F1.2, N1.1… restent et partiront avec le premier texte,
comme lignes du message de commit ; les textes publiés ne contiennent plus ces articles. T4
ajoute ses propres lignes (les trois textes, E12, le retrait).
- **Un retour arrière** vers l'image d'avant remet les sept articles et les trois ordres tels
qu'ils étaient (vérifié avec l'image `de1b7eb`) ; E12 et les nouveaux textes d'I1, E1, E2
restent.
+6 -6
View File
@@ -142,10 +142,10 @@ test('C17 — Décisions : une ligne par doc, les modules à voter, dont sans to
const rows = page.locator('ul.lines > li'); const rows = page.locator('ul.lines > li');
await expect(rows).toHaveCount(1); await expect(rows).toHaveCount(1);
await expect(rows.first()).toContainText("Acte d'engagement Certification"); await expect(rows.first()).toContainText("Acte d'engagement Certification");
// 33 articles, the title of the document and the order of 7 sections (ADR 0009; the // 27 articles, the title of the document and the order of its 5 sections (ADR 0009; since
// section of a single article has no order to decide). // lot T4, the rules of operation are out of the document, ADR 0014).
await expect(rows.first()).toContainText('41 modules à voter'); await expect(rows.first()).toContainText('33 modules à voter');
await expect(rows.first()).toContainText('dont 41 sans ton vote'); await expect(rows.first()).toContainText('dont 33 sans ton vote');
// A vote on one version of E3 (it has a variant): one module fewer without her vote. « Contre » // A vote on one version of E3 (it has a variant): one module fewer without her vote. « Contre »
// counts as much, and leaves the previews of C9 unchanged (the server is shared). In Monnaie // counts as much, and leaves the previews of C9 unchanged (the server is shared). In Monnaie
// libre the vote goes through the Ğ1 chain: the ballot, then what her wallet (Charlie's // libre the vote goes through the Ğ1 chain: the ballot, then what her wallet (Charlie's
@@ -165,8 +165,8 @@ test('C17 — Décisions : une ligne par doc, les modules à voter, dont sans to
.poll(async () => (await (await page.request.get(`/api/ballots/${ballot.id}`)).json()).ballot.status, { timeout: 15_000 }) .poll(async () => (await (await page.request.get(`/api/ballots/${ballot.id}`)).json()).ballot.status, { timeout: 15_000 })
.toBe('confirmed'); .toBe('confirmed');
await page.reload(); await page.reload();
await expect(rows.first()).toContainText('41 modules à voter'); await expect(rows.first()).toContainText('33 modules à voter');
await expect(rows.first()).toContainText('dont 40 sans ton vote'); await expect(rows.first()).toContainText('dont 32 sans ton vote');
await rows.first().getByRole('link').click(); await rows.first().getByRole('link').click();
await expect(page).toHaveURL(path(DOC)); await expect(page).toHaveURL(path(DOC));
}); });
+2 -1
View File
@@ -119,7 +119,8 @@ export async function testDoc(page: Page): Promise<{
* force in the test group, as the vote does it: voices for until each enters, then those * force in the test group, as the vote does it: voices for until each enters, then those
* voices withdrawn. A version in force stays so (a permanent vote: only a rival displaces * voices withdrawn. A version in force stays so (a permanent vote: only a rival displaces
* it), at zero votes, as the controls written before the seed proposals found it. Never in * it), at zero votes, as the controls written before the seed proposals found it. Never in
* Monnaie libre, whose vote goes through the chain; nothing done twice. * Monnaie libre, whose vote goes through the chain; nothing done twice. E12 « Responsabilité
* civique », the fourth (lot T4), stays a seed proposal: open, as C35 reads it.
*/ */
export async function seedsInForce(browser: Browser) { export async function seedsInForce(browser: Browser) {
const voices = [await person(browser, 'Amorce A'), await person(browser, 'Amorce B')]; const voices = [await person(browser, 'Amorce A'), await person(browser, 'Amorce B')];
+4 -3
View File
@@ -42,9 +42,10 @@ test('C25 — l’ordre des articles : une ligne en fin de section, réordonnée
await signIn(page, 'Chiara'); await signIn(page, 'Chiara');
await page.goto(TEST_DOC); await page.goto(TEST_DOC);
await unfold(page); await unfold(page);
// Each section ends with its order, in one line; a section of one article has nothing to decide. // Each section ends with its order, in one line: five sections (formule, inertie and
// ordonnancement are out of the document, ADR 0014).
const modules = page.getByRole('group', { name: /^Ordre des articles · / }); const modules = page.getByRole('group', { name: /^Ordre des articles · / });
await expect(modules).toHaveCount(7); await expect(modules).toHaveCount(5);
await expect(page.getByRole('group', { name: 'Ordre des articles · Ordonnancement' })).toHaveCount(0); await expect(page.getByRole('group', { name: 'Ordre des articles · Ordonnancement' })).toHaveCount(0);
const order = page.getByRole('group', { name: 'Ordre des articles · Conclusion' }); const order = page.getByRole('group', { name: 'Ordre des articles · Conclusion' });
await expect(order).toContainText('Ordre de la section'); await expect(order).toContainText('Ordre de la section');
@@ -62,7 +63,7 @@ test('C25 — l’ordre des articles : une ligne en fin de section, réordonnée
const fondVote = page.getByRole('region', { name: 'Le vote de « Ordre des articles · Engagements fondamentaux »' }); const fondVote = page.getByRole('region', { name: 'Le vote de « Ordre des articles · Engagements fondamentaux »' });
// Its inertia, said once, in its own place (lot U2). // Its inertia, said once, in its own place (lot U2).
await expect(fondVote.getByRole('heading', { name: 'Inertie · 2 / 5 · basse' })).toBeVisible(); await expect(fondVote.getByRole('heading', { name: 'Inertie · 2 / 5 · basse' })).toBeVisible();
await expect(fondVote.getByRole('list', { name: 'Ordre en vigueur' }).locator('li')).toHaveText(['Engagements fondamentaux', 'Unicité du compte', 'Réciprocité']); await expect(fondVote.getByRole('list', { name: 'Ordre en vigueur' }).locator('li')).toHaveText(['Engagements fondamentaux', 'Unicité du compte', 'Responsabilité civique', 'Réciprocité']);
await fond.getByRole('button', { name: 'Le vote' }).click(); await fond.getByRole('button', { name: 'Le vote' }).click();
// Another order: « Réordonner », the article, then its new place — in place, no panel. // Another order: « Réordonner », the article, then its new place — in place, no panel.
+3 -3
View File
@@ -243,11 +243,11 @@ test('C31 — une coquille sur un texte en vigueur attend sa validation, puis s
const panel = vera.locator('aside.panel'); const panel = vera.locator('aside.panel');
await panel.getByText('Corriger une coquille').click(); await panel.getByText('Corriger une coquille').click();
const body = panel.getByLabel('Texte', { exact: true }); const body = panel.getByLabel('Texte', { exact: true });
await body.fill((await body.inputValue()).replace("C'est le seul", 'C’est le seul')); await body.fill((await body.inputValue()).replace("C'est l'unique", 'C’est l’unique'));
await panel.getByRole('button', { name: 'Enregistrer la correction' }).click(); await panel.getByRole('button', { name: 'Enregistrer la correction' }).click();
await expect(vera.getByText(/^Ta correction attend un administrateur, ce texte venant du seed/)).toBeVisible(); await expect(vera.getByText(/^Ta correction attend un administrateur, ce texte venant du seed/)).toBeVisible();
// In force, only a validated fix changes the text. // In force, only a validated fix changes the text.
await expect(purpose).toContainText("C'est le seul et unique propos"); await expect(purpose).toContainText("C'est l'unique enjeu");
await expect(panel.locator('li.fix')).toContainText("en attente : s'applique d'elle-même le"); await expect(panel.locator('li.fix')).toContainText("en attente : s'applique d'elle-même le");
await ada.reload(); await ada.reload();
@@ -258,7 +258,7 @@ test('C31 — une coquille sur un texte en vigueur attend sa validation, puis s
await expect(ada.getByText('Correction appliquée.')).toBeVisible(); await expect(ada.getByText('Correction appliquée.')).toBeVisible();
await vera.reload(); await vera.reload();
await expect(purpose).toContainText('C’est le seul et unique propos'); await expect(purpose).toContainText('C’est l’unique enjeu');
const doc = await testDoc(vera); const doc = await testDoc(vera);
const unit = doc.units.find((u) => u.inForce?.title === "Raison d'être"); const unit = doc.units.find((u) => u.inForce?.title === "Raison d'être");
const after = await details(vera, unit?.inForce?.id ?? ''); const after = await details(vera, unit?.inForce?.id ?? '');
+21 -17
View File
@@ -10,6 +10,8 @@ test.beforeAll(async ({ browser }) => seedsInForce(browser));
const EF = 'Engagements fondamentaux'; const EF = 'Engagements fondamentaux';
const E1 = 'Unicité du compte'; const E1 = 'Unicité du compte';
// Lot T4 (Yvv, 2026-11-03): between the two, a seed proposal, left open by `seedsInForce`.
const EC = 'Responsabilité civique';
const E2 = 'Réciprocité'; const E2 = 'Réciprocité';
const ORDER = `Ordre des articles · ${EF}`; const ORDER = `Ordre des articles · ${EF}`;
const CSRF = { 'x-requested-with': 'libredecision' }; const CSRF = { 'x-requested-with': 'libredecision' };
@@ -41,11 +43,11 @@ test('C35 — réordonner une section : les poignées sur ses articles, au gliss
await expect(page.locator('aside.panel')).toHaveCount(0); await expect(page.locator('aside.panel')).toHaveCount(0);
const list = page.locator('section.text').getByRole('list', { name: 'Nouvel ordre des articles' }); const list = page.locator('section.text').getByRole('list', { name: 'Nouvel ordre des articles' });
const names = list.locator('button.item .name'); const names = list.locator('button.item .name');
await expect(names).toHaveText([EF, E1, E2]); await expect(names).toHaveText([EF, E1, EC, E2]);
// The articles in force of the section are in the list now, not twice; the one only proposed says so. // The articles in force of the section are in the list now, not twice; the one only proposed says so.
await expect(page.locator('section.text article.unit', { hasText: E1 })).toHaveCount(0); await expect(page.locator('section.text article.unit', { hasText: E1 })).toHaveCount(0);
await expect(list.locator('li', { hasText: EF })).toContainText('proposé'); await expect(list.locator('li', { hasText: EF })).toContainText('proposé');
await expect(list.locator('.grip')).toHaveCount(3); await expect(list.locator('.grip')).toHaveCount(4);
const submit = page.getByRole('button', { name: 'Proposer cet ordre' }); const submit = page.getByRole('button', { name: 'Proposer cet ordre' });
await expect(submit).toBeDisabled(); await expect(submit).toBeDisabled();
// Off, and it says why (UX-lecteur.md: « le bouton reste éteint et le dit » — lot U2). // Off, and it says why (UX-lecteur.md: « le bouton reste éteint et le dit » — lot U2).
@@ -54,43 +56,45 @@ test('C35 — réordonner une section : les poignées sur ses articles, au gliss
await expect(submit).toHaveAccessibleDescription(why); await expect(submit).toHaveAccessibleDescription(why);
await shot(page, 'c35-2-poignees'); await shot(page, 'c35-2-poignees');
// By dragging its handle: Réciprocité onto the place of Unicité du compte. // By dragging its handle: Réciprocité onto the place of the article above it, Responsabilité
await list.locator('li', { hasText: E2 }).locator('.grip').dragTo(list.locator('li', { hasText: E1 })); // civique (lot T4; a drag over two rows is not announced, see the report of lot T4 for U3).
await expect(names).toHaveText([EF, E2, E1]); await list.locator('li', { hasText: E2 }).locator('.grip').dragTo(list.locator('li', { hasText: EC }));
await expect(page.getByText(`« ${E2} » en place 2 sur 3.`)).toBeAttached(); await expect(names).toHaveText([EF, E1, E2, EC]);
await expect(page.getByText(`« ${E2} » en place 3 sur 4.`)).toBeAttached();
await expect(submit).toBeEnabled(); await expect(submit).toBeEnabled();
await expect(page.getByText(why)).toHaveCount(0); await expect(page.getByText(why)).toHaveCount(0);
// With the keyboard: the article keeps the focus, the arrows move it. // With the keyboard: the article keeps the focus, the arrows move it.
const items = list.locator('button.item'); const items = list.locator('button.item');
await items.nth(1).focus(); await items.nth(2).focus();
await page.keyboard.press('ArrowUp'); await page.keyboard.press('ArrowUp');
await expect(names).toHaveText([E2, EF, E1]); await expect(names).toHaveText([EF, E2, E1, EC]);
await expect(items.nth(0)).toBeFocused(); await expect(items.nth(1)).toBeFocused();
await page.keyboard.press('ArrowDown'); await page.keyboard.press('ArrowDown');
await expect(names).toHaveText([EF, E2, E1]); await expect(names).toHaveText([EF, E1, E2, EC]);
// Without dragging: its arrows, or an article then its new place. // Without dragging: its arrows, or an article then its new place.
await list.getByRole('button', { name: `Descendre « ${E2} »` }).click(); await list.getByRole('button', { name: `Descendre « ${E2} »` }).click();
await expect(names).toHaveText([EF, E1, E2]); await expect(names).toHaveText([EF, E1, EC, E2]);
await expect(submit).toBeDisabled(); await expect(submit).toBeDisabled();
await expect(page.getByText(why)).toBeVisible(); await expect(page.getByText(why)).toBeVisible();
await items.nth(2).click(); await items.nth(3).click();
await expect(items.nth(2)).toHaveAttribute('aria-pressed', 'true'); await expect(items.nth(3)).toHaveAttribute('aria-pressed', 'true');
await items.nth(1).click(); await items.nth(1).click();
await expect(names).toHaveText([EF, E2, E1]); await expect(names).toHaveText([EF, E2, E1, EC]);
// « Annuler » gives the section back as it read. // « Annuler » gives the section back as it read.
await page.getByRole('button', { name: 'Annuler' }).click(); await page.getByRole('button', { name: 'Annuler' }).click();
await expect(list).toHaveCount(0); await expect(list).toHaveCount(0);
await expect(page.locator('section.text article.unit', { hasText: E1 })).toHaveCount(1); await expect(page.locator('section.text article.unit', { hasText: E1 })).toHaveCount(1);
await line.getByRole('button', { name: 'Réordonner' }).click(); await line.getByRole('button', { name: 'Réordonner' }).click();
await list.getByRole('button', { name: `Monter « ${E2} »` }).click(); await list.getByRole('button', { name: `Monter « ${E2} »` }).click();
await expect(names).toHaveText([EF, E2, E1]); await list.getByRole('button', { name: `Monter « ${E2} »` }).click();
await expect(names).toHaveText([EF, E2, E1, EC]);
// Then the vote: the order goes to the vote, and its vote unfolds at once, in the same place. // Then the vote: the order goes to the vote, and its vote unfolds at once, in the same place.
await submit.click(); await submit.click();
await expect(page.getByText('Ordre proposé au vote.')).toBeVisible(); await expect(page.getByText('Ordre proposé au vote.')).toBeVisible();
const fold = line.locator('section.fold'); const fold = line.locator('section.fold');
await expect(fold).toHaveAttribute('aria-label', `Le vote de « ${ORDER} »`); await expect(fold).toHaveAttribute('aria-label', `Le vote de « ${ORDER} »`);
await expect(fold.getByRole('list', { name: 'Ordre proposé' }).locator('li')).toHaveText([EF, E2, E1]); await expect(fold.getByRole('list', { name: 'Ordre proposé' }).locator('li')).toHaveText([EF, E2, E1, EC]);
await expect(line).toContainText('1 ordre proposé'); await expect(line).toContainText('1 ordre proposé');
const pid = ((await fold.getAttribute('id')) ?? '').replace(/^vote-/, ''); const pid = ((await fold.getAttribute('id')) ?? '').replace(/^vote-/, '');
await fold.getByRole('button', { name: 'Pour', exact: true }).click(); await fold.getByRole('button', { name: 'Pour', exact: true }).click();
@@ -257,7 +261,7 @@ test('C38 — l’en-tête compte ce que montre la liste ; un changement d’ine
await page.goto(DOC); await page.goto(DOC);
await unfold(page); await unfold(page);
const facts = page.locator('.facts'); const facts = page.locator('.facts');
await expect.soft(facts).toContainText('0 article en vigueur · 3 Propositions seed · '); await expect.soft(facts).toContainText('0 article en vigueur · 4 Propositions seed · ');
await expect.soft(facts).toContainText(new RegExp(`· ${await listed()} propositions en cours`)); await expect.soft(facts).toContainText(new RegExp(`· ${await listed()} propositions en cours`));
// A change of inertia on the order of a section and on the title (test group): each is found at // A change of inertia on the order of a section and on the title (test group): each is found at
+13 -10
View File
@@ -37,7 +37,7 @@ test('C2 — l’accueil avec session : le choix du groupe, ceux de la même cl
await expect(page).toHaveURL((u) => u.pathname === '/'); await expect(page).toHaveURL((u) => u.pathname === '/');
}); });
test('C3 — au départ, aucun texte en vigueur : la raison d’être et les deux engagements, Propositions seed, ouvrent le texte', async ({ page }) => { test('C3 — au départ, aucun texte en vigueur : la raison d’être et les trois engagements, Propositions seed, ouvrent le texte', async ({ page }) => {
await signIn(page, 'Chiara'); await signIn(page, 'Chiara');
await page.goto(DOC); await page.goto(DOC);
await expect(page.getByRole('heading', { level: 1 })).toHaveText("Acte d'engagement Certification"); await expect(page.getByRole('heading', { level: 1 })).toHaveText("Acte d'engagement Certification");
@@ -45,20 +45,22 @@ test('C3 — au départ, aucun texte en vigueur : la raison d’être et les deu
// read whole at the head of the text (lot U), each marked: never the bare page of a text in force. // read whole at the head of the text (lot U), each marked: never the bare page of a text in force.
await expect(page.getByText("Aucun article n'est encore en vigueur. Commence par les Propositions seed : elles y entrent par le vote, comme toute proposition.")).toBeVisible(); await expect(page.getByText("Aucun article n'est encore en vigueur. Commence par les Propositions seed : elles y entrent par le vote, comme toute proposition.")).toBeVisible();
const seeds = page.locator('section.text article.unit'); const seeds = page.locator('section.text article.unit');
await expect(seeds.locator('h2')).toHaveText(["Raison d'être", 'Unicité du compte', 'Réciprocité']); // Lot T4 (Yvv, 2026-11-03): « Responsabilité civique » between the two engagements.
await expect(seeds.locator('.tag', { hasText: 'Proposition seed' })).toHaveCount(3); await expect(seeds.locator('h2')).toHaveText(["Raison d'être", 'Unicité du compte', 'Responsabilité civique', 'Réciprocité']);
await expect(seeds.getByTitle("Texte de départ mis en avant pour lancer le vote. Il n'est pas en vigueur : il y entre par le vote, comme toute proposition.")).toHaveCount(3); await expect(seeds.locator('.tag', { hasText: 'Proposition seed' })).toHaveCount(4);
await expect(seeds.getByTitle("Texte de départ mis en avant pour lancer le vote. Il n'est pas en vigueur : il y entre par le vote, comme toute proposition.")).toHaveCount(4);
// At the low level they start at, how far each is from passing. // At the low level they start at, how far each is from passing.
for (const seed of await seeds.all()) await expect(seed).toContainText('0 pour · 0 contre · 9 oui sur 12'); for (const seed of await seeds.all()) await expect(seed).toContainText('0 pour · 0 contre · 9 oui sur 12');
for (const seed of await seeds.all()) await expect(seed).toContainText('inertie 2 / 5 · basse'); for (const seed of await seeds.all()) await expect(seed).toContainText('inertie 2 / 5 · basse');
// Below, the open proposals, folded by section; the seed proposals are not said twice. // Below, the open proposals, folded by section; the seed proposals are not said twice.
await expect(page.getByRole('heading', { name: 'Propositions en cours' })).toBeVisible(); await expect(page.getByRole('heading', { name: 'Propositions en cours' })).toBeVisible();
await expect(page.locator('ul.deep li.section')).toHaveCount(8); // Five sections: formule, inertie and ordonnancement are out of the document (ADR 0014).
await expect(page.locator('ul.deep li.section')).toHaveCount(5);
await expect(page.locator('ul.deep button.row')).toHaveCount(0); await expect(page.locator('ul.deep button.row')).toHaveCount(0);
await expect(page.locator('ul.deep li.section', { hasText: 'Engagements techniques' })).toContainText('11 articles'); await expect(page.locator('ul.deep li.section', { hasText: 'Engagements techniques' })).toContainText('11 articles');
await unfold(page); await unfold(page);
// One line per article: the 33 less the 3 at the head, E3 and E7 holding their two variants inside. // One line per article: the 27 less the 4 at the head, E3 and E7 holding their two variants inside.
await expect(page.locator('ul.deep button.row')).toHaveCount(30); await expect(page.locator('ul.deep button.row')).toHaveCount(23);
await expect(page.locator('ul.deep .tag', { hasText: 'Proposition seed' })).toHaveCount(0); await expect(page.locator('ul.deep .tag', { hasText: 'Proposition seed' })).toHaveCount(0);
}); });
@@ -172,7 +174,7 @@ test('C9 — les aperçus : bien cotées, et tout', async ({ page }) => {
await page.goto(DOC); await page.goto(DOC);
await page.getByRole('radio', { name: 'Si tout passe' }).click(); await page.getByRole('radio', { name: 'Si tout passe' }).click();
await expect(page.getByText("Aperçu : le texte tel qu'il serait si toutes les propositions", { exact: false })).toBeVisible(); await expect(page.getByText("Aperçu : le texte tel qu'il serait si toutes les propositions", { exact: false })).toBeVisible();
await expect(page.locator('section.text article.unit')).toHaveCount(33); await expect(page.locator('section.text article.unit')).toHaveCount(27);
// Nothing in force in Monnaie libre, and nothing well rated yet (no « pour » there so far). // Nothing in force in Monnaie libre, and nothing well rated yet (no « pour » there so far).
await page.getByRole('radio', { name: 'Si les bien cotées passent' }).click(); await page.getByRole('radio', { name: 'Si les bien cotées passent' }).click();
await expect(page.locator('section.text article.unit')).toHaveCount(0); await expect(page.locator('section.text article.unit')).toHaveCount(0);
@@ -267,8 +269,9 @@ test('C18 — la Raison d’être ouvre le texte, en trois langues', async ({ pa
// The first sentence in italics, then two paragraphs. // The first sentence in italics, then two paragraphs.
const paragraphs = first.locator('.prose p'); const paragraphs = first.locator('.prose p');
await expect(paragraphs).toHaveCount(3); await expect(paragraphs).toHaveCount(3);
await expect(paragraphs.nth(0).locator('em')).toContainText("Derrière une clé il n'y a qu'un seul être humain vivant"); // The text of Yvv of 2026-11-03 (lot T4).
await expect(paragraphs.nth(1)).toContainText("C'est le seul et unique propos de la certification"); await expect(paragraphs.nth(0).locator('em')).toContainText('Derrière une clé il y a un et un seul être humain vivant');
await expect(paragraphs.nth(1)).toContainText("C'est l'unique enjeu de la certification et de votre engagement");
await expect(paragraphs.nth(2)).toContainText('la première monnaie libre'); await expect(paragraphs.nth(2)).toContainText('la première monnaie libre');
await page.getByRole('radiogroup', { name: 'Langue du texte' }).getByRole('radio', { name: 'EN' }).click(); await page.getByRole('radiogroup', { name: 'Langue du texte' }).getByRole('radio', { name: 'EN' }).click();
await expect(first.locator('h2')).toHaveText('Purpose'); await expect(first.locator('h2')).toHaveText('Purpose');