Fusion de la tête du chantier (924a40d : lots B2 et F) dans le lot D

Les deux côtés gardés partout. Aux coutures :
- une objection (redit / contredit) porte sur deux articles, jamais sur un module ;
  un ordre ne se corrige pas, ni par son auteur ni par un autre ; une coquille du
  titre suit le chemin de F (l'auteur du titre, un administrateur pour le titre
  de départ, ou 3 jours), et documents.title suit à l'application ;
- votable() couvre les modules ; leurs totaux passent par shown_tally, à l'écran
  et dans document.json ;
- « Modules à voter » ne compte plus une version retenue par une objection (test
  vu rouge) ; la liste du groupe la compte toujours parmi les propositions en cours ;
- le panier : une fonction pour les articles et les modules, avec les versions
  retenues de F ; un nouvel article se propose dans une section, à sa fin, et peut
  répondre à une objection ;
- migrations 0007 (modules) puis 0008 (objections) ;
- C25 et C26 supportent un groupe d'essai où une voix suffit (dès 16 membres).

Boucle : fmt, clippy -D warnings, cargo test (227), svelte-check 0, vitest 55,
build, e2e 35 / 35 (C1–C33 et M1).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Yvv
2026-10-31 09:41:30 +01:00
co-authored by Claude Opus 5.5
82 changed files with 8285 additions and 677 deletions
+5 -1
View File
@@ -1,5 +1,9 @@
# 0003 — Corriger n'est pas voter
> Complétée par [0010](0010-objections-et-coquilles-validees.md) (2026-10-31) : la règle de la
> coquille ne change pas ; la coquille d'un autre attend son auteur (un administrateur pour un
> texte du seed), ou 3 jours, et en vigueur seule une coquille validée change le texte.
**Contexte.** « Ça ne peut pas devenir un système qui nécessite un vote pour corriger une
coquille. » Mais une correction ne doit pas pouvoir changer le sens d'un texte voté — et tout
membre peut corriger un texte en vigueur, qui est republié aussitôt.
@@ -24,7 +28,7 @@ ou de fond), jamais contre la correction précédente :
ligne et tabulation) sont refusés partout où l'on écrit ; un titre tient sur une ligne.
Sinon c'est **du fond** : nouvelle révision d'une proposition ouverte (par son auteur), votes
antérieurs « à reconfirmer », signalements levés ; refusé sur un texte en vigueur ou de départ.
antérieurs « à reconfirmer », réponse aux objections qui l'attendent (0010) ; refusé sur un texte en vigueur ou de départ.
L'écriture ne vaut que sur le texte jugé : un texte entré en vigueur ou changé entre-temps
donne un conflit. Les brouillons s'éditent librement.
@@ -1,5 +1,11 @@
# 0004 — Contradictions : signalées par les personnes, bloquantes
> **Remplacée** par [0010](0010-objections-et-coquilles-validees.md) (2026-10-31) : le
> signalement devient l'objection « contredit », à côté de « redit » ; elle retient la dernière
> arrivée des deux versions, qui ne se vote plus jusqu'à sa levée ; l'auteur répond, la personne
> qui objecte lève ou réitère, et sans réponse de sa part sous 3 jours elle est levée. Les
> signalements existants sont devenus des « contredit » (migration 0008).
**Contexte.** « Il faut que 2 unités modulaires ne puissent pas passer en vigueur si elles se
contredisent. » La contradiction est une question de sens : aucune règle ne la détecte sans
se tromper, et l'IA est écartée pour l'instant.
+3 -1
View File
@@ -66,7 +66,9 @@ s_k = M_k + (1 − M_k)·(1 − p̃^G_k) ⇔ G_k = ln(1 − (s_k − M_k)/(1
- **C reste un plancher** : à T ≤ C, R = C + B^W ; une seule voix ne fait jamais passer un
texte dans Monnaie libre ;
- le groupe d'essai (W = 2, C = 1) : la référence vaut 100 %, ramenée à 50 % ; G reste fini ;
il faut les deux voix, à tout cran.
il faut les deux voix, à tout cran. Cette garde tient à B^W : dès 16 membres, 0,1^W passe sous
la précision du calcul (1 + 10⁻¹⁶ = 1), et une voix seule suffit alors, C valant 1. Monnaie
libre n'est pas concernée (C = 50).
Les réglages de la formule disent les deux, dans cet ordre (lot D) : la mesure telle quelle — sa
part est celle de la valeur elle-même, une médiane de 2,5 votants sur 4 fait 62,5 %, jamais
+123 -24
View File
@@ -3,7 +3,9 @@
> Complète [0002](0002-vote-permanent.md) (vote permanent) et [0006](0006-acces-connect-trustinwallet.md)
> (accès). Décision d'Yvv du 2026-10-30 (revue, L9) ; le format du bulletin, la voie du
> portefeuille et les réglages sont les choix par défaut d'orch (Q5, Q6, Q7), isolés pour être
> changés sans toucher au reste.
> changés sans toucher au reste. Corrigé le 2026-10-31 après la relecture indépendante de
> `74f96be` (lot B2) : finalité, recherche filtrée et paginée, tâche de fond, plafond, bulletin
> Ğecko, bulletins lâchés, reçu.
**Contexte.** Jusqu'ici, un vote était une ligne écrite par le serveur pour la session connectée.
Dans Monnaie libre, l'électorat W est la toile de confiance, mais la connexion Ğ1
@@ -77,27 +79,55 @@ fait signer par l'extension de portefeuille du navigateur (interface standard `i
l'offrent), avec **polkadot-api chargé au seul moment de signer**, et l'envoie à un nœud Ğ1
(`LD_VOTE_NODES`). Sans portefeuille dans le navigateur : **Ğecko**, par un lien et un QR code
`g1://<compte>?amount=0.1&comment=ld1:<H>` (un virement commenté, ce que Ğecko sait faire) ;
ce bulletin-là n'est lié à aucun compte, et la page attend.
ce bulletin-là n'est lié à aucun compte : seul un commentaire **payé** le tranche (voir la
confirmation), et le serveur le guette, la page ouverte ou non.
La page joint un nœud **avant** de demander la signature (comme polkadot-api, qui lit le nonce
et le runtime) : un nœud muet ne reçoit jamais rien, la page le dit et lâche le bulletin.
### La confirmation — `crates/ld-server/src/ballots.rs`, `indexer.rs`
Le serveur lit l'indexeur (duniter-squid, `LD_INDEXERS`) :
Le serveur lit l'indexeur (duniter-squid, PostGraphile, `LD_INDEXERS`) :
```graphql
query Ballot($hash: String!) {
txComments(condition: {hash: $hash}, orderBy: BLOCK_NUMBER_ASC, first: 20) {
query Ballot($hash: String!, $filter: TxCommentFilter, $after: Cursor) {
squidStatus { height }
txComments(condition: {hash: $hash}, filter: $filter,
orderBy: [BLOCK_NUMBER_ASC, ID_ASC], first: 50, after: $after) {
pageInfo { hasNextPage endCursor }
nodes { id blockNumber remark
author { id identity { index name isMember } }
transfersByCommentId { nodes { fromId toId amount } } } }
}
```
`hash` = `0x` + blake2b-256 des octets de la remarque. Il garde la première occurrence, dans
l'ordre de la chaîne, qui ne vient pas d'un autre compte que celui lié, puis exige :
`hash` = `0x` + blake2b-256 des octets de la remarque. Le `filter` ne demande que ce qui peut
trancher : pour un bulletin lié, `{authorId: {equalTo: <compte lié>}}` ; pour un bulletin Ğecko,
`{transfersByCommentId: {some: {toId: {equalTo: <compte des votes>}, amount:
{greaterThanOrEqualTo: "<montant>"}}}}`. Les commentaires viennent dans l'ordre de la chaîne,
**50 par page, page après page** (au plus 20 pages par lecture), jusqu'à celui qui tranche :
des copies ne masquent jamais le vrai commentaire (l'ancienne requête s'arrêtait à 20 ; la
remarque « Merci » en compte déjà 26 sur la chaîne).
**La finalité.** L'indexeur sert la meilleure chaîne, blocs pas encore définitifs compris.
`squidStatus` n'expose que `name`, `height` et `hash` (pas de `finalizedHeight`) ; `height` est
le dernier bloc définitif traité. Relevé le 2026-10-31 sur indexer.duniter.org, par
`{ squidStatus { height } blocks(orderBy: HEIGHT_DESC, first: 1) { nodes { height } } }` :
`height` reste **3 blocs** derrière le plus récent bloc servi (3 407 340 contre 3 407 343, puis
3 407 342 contre 3 407 345…), les 2 à 3 blocs de la finalité de Duniter v2. Seul un commentaire
d'un bloc ≤ `height` compte, ou refuse ; au-dessus, le bulletin attend.
Le moteur (`ld_engine::ballot::judge`) juge à nouveau ce qui revient. Un indexeur qui ignorerait
le filtre ne change d'abord que le nombre de pages, mais au-delà de 1 000 copies nues placées
avant le vrai commentaire (20 pages de 50), celui-ci n'est plus lu et le bulletin reste en attente
(relecture de `7ffa4fd`) : cas théorique, un PostGraphile sans ce filtre répond par une erreur. Il garde le premier commentaire, dans l'ordre de la
chaîne, qui n'est pas une copie : pour un bulletin lié, un commentaire d'un autre compte est une
copie ; pour un bulletin Ğecko, **un commentaire sans le virement est une copie** (une remarque
seule ne coûte rien à envoyer). Puis il exige :
1. la remarque exacte ;
2. dans la même transaction, un virement **du signataire vers le compte des votes**, d'au moins
le montant ;
le montant (`transfer` sinon — seulement pour un bulletin lié : son propre compte s'est trompé) ;
3. une identité Ğ1 au signataire (`no_identity` sinon) ;
4. que cette identité soit **membre maintenant** (`not_member` sinon) — par la règle de
trustinWallet.
@@ -107,12 +137,20 @@ avec le bloc et le rang de l'évènement ; le balayage d'adoption tourne aussit
demandé le bulletin voit ces votes comme « ton vote » — et seulement ceux de ses bulletins : une
autre session ne voit jamais ce qu'a voté la même identité ailleurs.
Le serveur relit l'indexeur pour chaque bulletin en attente toutes les 10 secondes (tâche de
fond) et quand la page demande (au plus une lecture toutes les 3 secondes par bulletin). Un
bulletin non vu en **24 heures** est lâché. Cas d'erreur, chacun testé : indexeur muet (le
bulletin reste en attente), signataire non membre ou sans identité (refusé, et dit), mauvais
montant ou mauvais destinataire (refusé), déjà confirmé (rien ne change), révision changée entre
temps (le vote porte sur la révision votée : « à reconfirmer »).
**La tâche de fond** passe toutes les 10 secondes et lit **50 bulletins en attente au plus, le
moins récemment lu d'abord** (jamais lu, puis la plus ancienne lecture) : chaque bulletin en
attente est lu au moins toutes les ⌈n / 50⌉ passes, que la page l'attende ou non (un code Ğecko,
une fenêtre fermée). Une lecture de l'indexeur prend 0,5 à 2,1 s (mesuré le 31/10), donc une passe
de 50 bulletins dure 25 à 100 s : il faudrait de l'ordre de 40 000 à 170 000 bulletins en attente
pour qu'un seul ne soit pas lu dans ses 24 heures. La page, elle, fait lire son bulletin au plus toutes les 3 secondes.
Un bulletin non vu en **24 heures** est **lu une dernière fois à son échéance**, puis lâché ;
s'aucun indexeur ne répond, ou si son commentaire attend un bloc définitif, il reste en attente
et relu, une heure au plus. Cas d'erreur, chacun testé : indexeur muet (le bulletin reste en
attente), signataire non membre ou sans identité (refusé, et dit), mauvais montant ou mauvais
destinataire (refusé si lié, ignoré si Ğecko), copie nue ou mal payée d'un bulletin Ğecko
(ignorée), bloc pas encore définitif (en attente), déjà confirmé (rien ne change), révision
changée entre temps (le vote porte sur la révision votée : « à reconfirmer »).
### Le dernier fait foi
@@ -122,9 +160,24 @@ un bulletin plus récent sur la chaîne. « Retirer mon vote » est un bulletin
`none`. Les transactions d'un même compte gardent l'ordre de ses envois (le nonce) ; le désordre
ne vient que de l'ordre de lecture de l'indexeur, et la règle l'absorbe.
Un bulletin que le portefeuille n'a pas signé (refus, fonds insuffisants, compte absent) est lâché
aussitôt par la page (`DELETE /api/ballots/{id}` : `expired`, raison `dropped`), pour ne pas
rester « en attente » une journée. Jamais un bulletin confirmé.
### Lâcher ou garder un bulletin
**Rien n'est parti** : la page lâche le bulletin aussitôt (`DELETE /api/ballots/{id}` :
`expired`, raison `dropped`), pour ne pas le montrer « en attente » une journée. C'est le cas :
- d'un refus du portefeuille, d'un compte absent, de fonds insuffisants ;
- d'un nœud muet **avant** la signature (la page joint le nœud d'abord) ;
- d'une fenêtre fermée avant la signature ; si le portefeuille demande encore à ce moment (sa
propre fenêtre peut rester ouverte), le bulletin attend sa réponse : refusé, il est lâché ;
- d'un refus de la chaîne : rejet du nœud (transaction invalide), ou transaction incluse mais
défaite (le virement a échoué, `batchAll` défait tout : aucune remarque).
**La transaction a pu partir** — signée, puis le nœud ou le portefeuille se tait — : le bulletin
est gardé, et la tâche de fond le guette jusqu'à son échéance. Un **code Ğecko** montré est gardé
aussi, fenêtre fermée : on peut payer plus tard, depuis le téléphone. Jamais un bulletin confirmé
n'est lâché.
« Ton vote », sous l'article : un bulletin en attente demandé **avant** un vote confirmé sur la
même ligne ne s'y montre plus ; un bulletin demandé après, si.
### Le vote groupé
@@ -132,7 +185,14 @@ Un panier : article par article ; « tout pour » / « tout contre » pour une s
document — jamais pour un article dont plusieurs versions sont en concurrence : l'interface le
montre, on choisit sa version. Puis **un geste** : une écriture (groupe géré), ou **une
transaction** (chaîne) pour toutes les lignes, au même prix qu'une seule (0,1 Ğ1 par transaction,
pas par ligne ; 200 lignes au plus, 20 bulletins en attente par session).
pas par ligne ; 200 lignes au plus).
**Le plafond vaut par identité, quelle que soit la session** : 20 bulletins au plus à la fois,
en attente **ou lâchés depuis moins d'une heure** — lâcher un bulletin ne libère pas sa place
aussitôt (la relecture avait créé 100 bulletins et 3 500 lignes en une session, par `DELETE`).
La tâche de fond **purge** les bulletins lâchés, lignes comprises : un jour après qu'un
portefeuille ne les a pas signés, une semaine après qu'ils n'ont pas été vus à temps (sous
l'article, il le dit d'ici là). Un bulletin lâché n'a jamais compté : rien d'un vote ne se perd.
### Ce que voit la chaîne
@@ -140,13 +200,39 @@ Qu'un compte (et son identité) a envoyé 0,1 Ğ1 au compte des votes avec une r
tel bloc : **qui a voté et quand, jamais quoi** — ni le document, ni le nombre de lignes, ni les
choix. Le solde du compte des votes est public : il dit combien de votes ont été envoyés.
Recoupée avec les totaux affichés en direct, la chaîne peut laisser deviner un choix (un total
qui bouge juste après un vote) : une décision d'Yvv attend (secret par paliers, ou totaux en
direct). En attendant, les totaux affichés passent par une seule fonction,
`DocState::shown_tally` (et `shown_evaluation`), où une publication par paliers se branchera ;
l'adoption lit `tally`. Deux lectures n'y passent pas encore et lisent les totaux en direct :
l'aperçu des propositions bien cotées (`docs.rs`, `unit_states` et `proposal_states`) et les
textes publiés (`publish.rs`). Elles s'y brancheront avec la décision d'Yvv.
### Ce que sait le serveur
Les bulletins, leurs lignes, leurs sels, la session qui les a demandés et l'identité qui les a
signés : il sait qui a voté quoi, comme pour un vote direct, et ne montre que les totaux. Il ne
peut pas inventer un vote d'une identité (il faudrait sa signature sur la chaîne) ; il pourrait en
taire un. Chaque vote compté se vérifie contre la chaîne en recalculant H depuis les lignes et le
sel — ce que personne d'autre ne peut faire tant que les sels restent au serveur.
sel.
### Le reçu
La note de recherche promet que chacun peut vérifier son propre vote avec son sel. Le serveur
rend donc le bulletin **à l'identité qui l'a demandé, et à elle seule** (404 pour toute autre) :
- `GET /api/ballots/{id}/receipt` — le reçu, à télécharger (`recu-vote-<date>-<id>.json`) : le
document, le compte lié, les lignes (version, révision, choix, et pour lire : l'article et son
titre), le sel, la forme canonique, H, la remarque, son empreinte pour l'indexeur, et où en est
le bulletin (état, bloc, évènement, signataire, identité comptée) ;
- `GET /api/ballots` — son historique, le plus récent d'abord (sans les bulletins jamais signés).
L'interface les montre dans la fenêtre de vote (« Télécharger ton reçu », « Tes bulletins ») et
sur la page **« Tes bulletins »** (`/bulletins`), qui **vérifie un reçu dans le navigateur**, sans
rien demander au serveur : elle recalcule la forme canonique et H (`web/src/lib/receipt.ts`, mêmes
vecteurs que le moteur) et dit si le reçu donne bien sa remarque — à chercher dans l'historique
de son portefeuille, ou sur la chaîne au bloc indiqué. Garder son reçu pour soi : avec le sel,
n'importe qui recalculerait le choix.
### Les réglages (Q7) — `crates/ld-server/src/config.rs`
@@ -166,7 +252,9 @@ Migration `0006`, additive : `ballots` (le bulletin, son sel, H, `0x`+blake2b-25
le compte et le montant du moment, l'état `pending | confirmed | refused | expired`, la raison,
l'identité qui a voté, le signataire, le bloc, le rang, l'évènement, ce qui est entré en vigueur,
les dates) et `ballot_lines` (version, révision, choix). `votes` gagne `source` (`server` par
défaut : tous les votes d'avant restent tels quels), `block`, `event_index`, `ballot_id`.
défaut : tous les votes d'avant restent tels quels), `block`, `event_index`, `ballot_id`. Les
corrections du 2026-10-31 n'ajoutent pas de migration ; la purge efface les bulletins lâchés
(`expired`) passé leur délai, jamais un bulletin confirmé ni refusé, jamais un vote.
## Coût
@@ -178,10 +266,21 @@ défaut : tous les votes d'avant restent tels quels), `block`, `event_index`, `b
indexeurs se configurent ; lire les évènements sur un nœud serait l'étape suivante.
- Le droit de vote se vérifie **au moment de la confirmation sur la chaîne** : un membre sorti
de la toile ensuite garde ses voix.
- Par Ğecko, le bulletin n'est lié à aucun compte : un autre compte qui recopierait la remarque
et la ferait inclure avant (en payant 0,1 Ğ1) prendrait ce bulletin — ses lignes compteraient
pour lui. Par l'extension, le bulletin est lié au compte et la copie est ignorée.
- Un paiement Ğecko fait après 24 heures ne compte pas (il est perdu pour le vote).
- Par Ğecko, le bulletin n'est lié à aucun compte. **Une copie nue de la remarque** (sans
virement, gratuite) **est ignorée** : elle ne refuse plus le bulletin. Seul un commentaire payé
le tranche. **Reste possible, la variante « prise par une copie payée »** : un autre compte qui
voit la remarque (dans la file des transactions, ou sur l'écran) et fait inclure avant une
copie **payée** (0,1 Ğ1 vers le compte des votes) prend ce bulletin — ses lignes comptent pour
lui, le paiement de la personne arrive après et ne compte plus. Elle coûte 0,1 Ğ1 à qui la tente
et se voit sur la chaîne ; un compte sans identité qui paie la copie fait refuser le bulletin
(`no_identity`). Par l'extension, le bulletin est lié au compte et toute copie est ignorée.
- Par Ğecko, un virement d'un mauvais montant ou vers un autre compte laisse le bulletin en
attente (au lieu d'un refus), jusqu'à son échéance : on ne distingue pas une erreur d'une copie.
- Un bulletin est lu une dernière fois à son échéance (24 heures) : ce qui est alors sur la
chaîne, en bloc définitif, compte encore ; un paiement Ğecko plus tardif est perdu pour le vote.
- Une identité Ğ1 créée par un vote sur la chaîne, jamais connectée ici, ne retient pas son nom
face à une personne qui arrive par un lien d'équipe (comme tout membre de la toile qui n'est
jamais venu) ; une identité Ğ1 qui s'est connectée le garde.
- polkadot-api : environ 180 Ko (66 Ko compressés) chargés au moment de signer seulement ;
`node_modules` grossit d'environ 77 Mo (son outillage).
- La chaîne montre la participation de chacun (qui a voté, quand, combien de fois).
+17
View File
@@ -85,6 +85,23 @@ personne traduise le nouveau. Le titre du document dans les autres langues suit
fraîches ou à revoir (`doc_title::sync`, rejoué aussi à chaque mise en file de publication : une
coquille ou une traduction du titre en vigueur s'y reporte).
### Face aux objections et aux coquilles des autres (ADR 0010)
- **Une objection** (« redit », « contredit ») porte sur deux versions d'articles, jamais sur un
module : un titre ou un ordre ne se répète ni ne se contredit au sens d'un article
(`objections::raise` n'admet que des textes ; test
`the_generic_writing_stops_at_a_module_and_an_order_is_never_corrected`).
- **Un ordre ne se corrige pas** (`409 order_fixed`), ni par son auteur ni par un autre : pas de
coquille d'un autre sur un ordre. **Une coquille du titre** suit le chemin de toute coquille :
celle d'un autre attend l'auteur du titre (un administrateur pour le titre de départ) ou
3 jours ; appliquée, elle republie, et `documents.title` suit.
- `DocState::votable` couvre les modules comme les articles ; les totaux d'un module se lisent
par `shown_tally`, à l'écran et dans `document.json`.
- **« Modules à voter »** ne compte pas une version retenue par une objection : personne ne peut
la voter tant qu'elle est retenue (un article dont la seule version ouverte est retenue sort
du compte, et y revient à la levée). La liste du groupe la compte toujours parmi les
propositions en cours, ouvertes.
### Publication
`fr.md` ne change pas de forme : les articles dans leur ordre en vigueur, sous le titre en
@@ -0,0 +1,124 @@
# 0010 — Objections « redit » / « contredit », coquilles validées, messagerie
> Remplace [0004](0004-contradictions-signalees.md) (contradictions signalées) et complète
> [0003](0003-corriger-n-est-pas-voter.md) (corriger n'est pas voter), dont la règle de la coquille
> ne change pas. Décisions d'Yvv du 2026-10-30 (revue) ; la messagerie dans l'application et la
> coquille d'un texte du seed validée par un administrateur sont les choix par défaut d'orch.
> Lot F, 2026-10-31.
**Contexte.** Le signalement de contradiction (0004) bloquait l'entrée en vigueur sans dire à
qui revenait le geste suivant, et une coquille corrigée par n'importe qui changeait le texte
d'un autre sans lui demander. Yvv, 2026-10-30 :
- « Faudrait un "redit" en option avec "contredit" → faut rendre plus explicite que l'objection
doit être levée par l'auteur de la dernière arrivée pour être une proposition votable. Pour ce
qui constitue une répétition → modifier l'article cible ; pour une contradiction → reformuler.
→ ping messagerie TrustinWallet → Lever l'objection ou Réitérer l'objection ; si pas de
réponse sous 3j, alors "levée". »
- « Corriger coquille → ping auteur pour valid → idem 3j ça passe auto, mais auteur a toujours
la main tant que c'est pas le texte en vote. Sinon seule une coquille validée corrige le texte
en vote. » (« le texte en vote » : le texte en vigueur.)
## Décision
### Les objections — `crates/ld-engine/src/objection.rs`
- Une objection dit qu'une version **redit** une autre (elle la répète) ou la **contredit**,
motif à l'appui (10 à 600 signes). Elle porte sur deux versions de texte de deux articles
différents, ouvertes ou en vigueur — jamais deux textes en vigueur (`both_in_force`).
- Elle retient **la dernière arrivée** des deux (date de soumission, à défaut de création, puis
l'ordre d'écriture) ; **jamais un texte en vigueur** : si la dernière arrivée est en vigueur,
c'est l'autre qui est retenue. La version retenue est fixée quand l'objection est faite.
- Tant que l'objection tient, la version retenue **ne se vote plus** (vote direct, vote groupé,
bulletin de la chaîne : `409 objection`) et **n'entre pas en vigueur**. Les votes déjà faits
restent ; un bulletin scellé avant l'objection et confirmé après compte, sans la faire entrer.
- Une personne n'a qu'une objection debout sur une même paire (`objection_exists`).
- **L'auteur de la version retenue répond** : pour une redite, il **modifie l'article visé**
(une proposition liée à l'objection, sur l'article de l'autre version, partie de son texte) ;
pour une contradiction, il **reformule** (une révision de fond de sa version, ou une
proposition liée sur son propre article). Une révision de fond de l'une ou l'autre des deux
versions vaut réponse ; une coquille, non. Une version du seed n'a pas d'auteur : tout membre
du groupe peut y répondre par une proposition liée.
- Une réponse donne la main à **la personne qui objecte** : un message lui demande de **lever**
ou de **réitérer** dans les **3 jours** ; sans geste de sa part, l'objection est **levée** à
l'échéance. Un seul tour à la fois : une autre réponse pendant son tour ne change ni le
message ni l'échéance. Réitérer rend la main à l'auteur (tour suivant, sans échéance pour lui).
- Lever : la personne qui a fait l'objection, à tout moment, ou un administrateur de
trustinWallet. Réitérer : elle seule. Retirer une des deux versions met fin à l'objection.
Une levée relance l'adoption : la version libérée entre en vigueur si ses voix suffisent.
- Règles d'accès : `trustin_access::lifts_objection`, `reiterates_objection`.
| Qui | Quoi | Effet | Échéance |
|---|---|---|---|
| tout membre du groupe | faire une objection « redit » ou « contredit » | la dernière arrivée (jamais un texte en vigueur) ne se vote plus ; message à son auteur | — |
| l'auteur de la version retenue (tout membre pour une version du seed) | modifier l'article visé (redit) ou reformuler (contredit) | la main passe à la personne qui objecte ; message « lever ou réitérer » | 3 jours pour elle |
| la personne qui objecte | lever | la version se vote de nouveau, et entre en vigueur si ses voix suffisent | — |
| la personne qui objecte | réitérer | la main revient à l'auteur ; message « réponds à nouveau » | aucune pour l'auteur |
| personne | (3 jours sans geste après une réponse) | levée « 3 jours sans suite » | — |
| un administrateur | lever | levée « par un administrateur » | — |
| l'auteur | retirer sa version | l'objection prend fin | — |
### Les coquilles validées — `crates/ld-engine/src/correction.rs`
La règle de la coquille (0003, `edit.rs`) ne change pas ; ce qui change, c'est qui la laisse
entrer.
- Sur **son propre texte** (l'auteur de la version ; un administrateur pour un texte du seed),
la correction s'applique tout de suite, comme avant.
- Sur **celui d'un autre**, elle **attend** : un message à l'auteur de la version (aux
administrateurs qui ouvrent le groupe, pour un texte du seed) avec **valider / refuser** ; sans
réponse sous **3 jours**, elle s'applique d'elle-même.
- **Tant que le texte n'est pas en vigueur, l'auteur garde la main** : il peut revenir sur une
correction appliquée (révision « correction retirée ») ou appliquer finalement une correction
refusée, tant que le texte est celui sur lequel elle a été écrite.
- **En vigueur, seule une correction validée change le texte** : elle attend la validation (ou
l'échéance, qui vaut validation), et un refus est définitif.
- Deux corrections en attente sur un même texte : chacune est jugée contre le texte voté ; à
l'application, la correction doit tomber sur le texte qu'elle a lu — sinon (une autre
correction, une révision de fond ou un retrait est passé entre-temps) elle est **périmée**
et l'interface demande de recharger.
- Les traductions restent éditoriales : elles ne passent pas par une validation.
- L'historique dit qui a écrit la correction et qui l'a validée (ou qu'elle est passée à
l'échéance) ; la correction en attente se lit, avec son diff, dans « Détails ».
- Règle d'accès : `trustin_access::answers_typo`.
| Qui | Quoi | Effet | Échéance |
|---|---|---|---|
| l'auteur de la version (un administrateur pour un texte du seed) | corriger une coquille | appliquée tout de suite, les votes restent | — |
| tout autre membre | corriger une coquille | en attente ; message à l'auteur (aux administrateurs pour un texte du seed) | 3 jours, puis appliquée |
| l'auteur (ou un administrateur pour le seed) | valider / refuser | appliquée / laissée de côté | — |
| l'auteur, texte pas encore en vigueur | revenir au texte d'avant, ou appliquer finalement | la main reste à l'auteur | — |
| texte en vigueur | — | seule une correction validée (ou passée à l'échéance) le change ; un refus est définitif | — |
### La messagerie — `crates/ld-server/src/messages.rs`
Une boîte **« Messages »** dans l'application, au menu, avec le nombre de non-lus (une pastille
sur le bouton du menu en mobile) ; pas de courriel. Un message porte un objet (une objection, une
coquille), son texte — dit par l'interface, dans la langue de la personne —, les gestes que
l'objet lui demande **maintenant** (répondre, lever ou réitérer, valider ou refuser) et son
échéance ; un message traité n'offre plus de geste et dit ce qu'il est devenu. Chacun ne lit
que les siens (`trustin_access::reads_message`) ; agir sur l'objet lit ses messages. Un message
ne se montre que tant que la personne ouvre le groupe dont il parle.
### Les échéances — `crates/ld-server/src/deadlines.rs`
Trois jours (`ANSWER_DAYS`). Le balayage d'adoption (toutes les 5 minutes) passe les
échéances, et une fois au démarrage : une échéance passée pendant un arrêt est prise dès la
reprise. L'horloge du serveur est injectable (`AppState::clock`) : les tests l'avancent, sans
attendre ; la route `/api/dev/clock` n'existe qu'avec la connexion de développement.
### La migration 0008
Additive. Les signalements gardent leur table (`signals`) et y gagnent le genre, la version
retenue, le tour, l'échéance, la réponse et la cause de la levée ; chaque signalement existant
devient un **« contredit »** sans perte : levé, il le reste (par son auteur, un administrateur
ou une révision, selon `lifted_by`) ; debout, il retient la dernière arrivée selon la règle
ci-dessus (s'il visait deux textes aujourd'hui tous deux en vigueur, il ne retient rien et se
lève à la main). Aucun message n'est créé pour le passé. S'y ajoutent les tables `typos` (les
corrections des autres) et `messages`, et sur les révisions la correction d'origine et qui l'a
validée.
**Coût.** Une version retenue attend son auteur aussi longtemps qu'il ne répond pas : c'est la
dernière arrivée, c'est à elle de s'expliquer. Une personne qui réitère sans fin garde une
version hors du vote : un administrateur peut lever. Une coquille d'un autre met jusqu'à trois
jours à paraître, et sur un texte du seed elle attend un administrateur.
+2 -1
View File
@@ -8,9 +8,10 @@ pas une décision : on en écrit une nouvelle qui la remplace, et on le note dan
| [0001](0001-rust-svelte.md) | Rust + Svelte, une image, SQLite | 2026-10-21 |
| [0002](0002-vote-permanent.md) | Vote permanent : marge du texte en place et plancher C | 2026-10-21 |
| [0003](0003-corriger-n-est-pas-voter.md) | Corriger n'est pas voter | 2026-10-21 |
| [0004](0004-contradictions-signalees.md) | Contradictions : signalées par les personnes, bloquantes | 2026-10-21 |
| [0004](0004-contradictions-signalees.md) | Contradictions : signalées par les personnes, bloquantes (remplacée par 0010) | 2026-10-21 |
| [0005](0005-publication-git.md) | Publication par file d'envoi vers un dépôt git | 2026-10-21 |
| [0006](0006-acces-connect-trustinwallet.md) | Accès : connect.monnaie-libre.fr, invitations, trustinWallet | 2026-10-21 |
| [0007](0007-inertie-cinq-crans.md) | Inertie à cinq crans, calée sur la participation du groupe (complète 0002) | 2026-10-30 |
| [0008](0008-vote-par-transaction.md) | Le vote par transaction sur la chaîne Ğ1 : bulletin scellé, confirmation par l'indexeur, le dernier fait foi | 2026-10-30 |
| [0009](0009-modules-ordre-et-titre.md) | Les modules : l'ordre des articles de chaque section (inertie 2), le titre du document (inertie 4) | 2026-10-31 |
| [0010](0010-objections-et-coquilles-validees.md) | Objections « redit » / « contredit », coquilles validées, messagerie (remplace 0004, complète 0003) | 2026-10-31 |
+71 -20
View File
@@ -9,7 +9,7 @@
La communauté Monnaie libre tient son Acte d'engagement Certification comme un **texte vivant** :
lisible d'abord, modifiable par article, chaque modification passant par un vote dont le seuil
suit la formule inertielle de la Ğ1 — sans qu'une coquille demande un vote, sans que deux
articles contradictoires soient en vigueur ensemble, et avec une publication automatique que
articles qui se répètent ou se contredisent soient en vigueur ensemble, et avec une publication automatique que
les applications clientes (Cesium, Ğecko…) peuvent suivre.
## Ce que voit la personne
@@ -48,7 +48,7 @@ les applications clientes (Cesium, Ğecko…) peuvent suivre.
(enregistré, inscrit sur la chaîne Ğ1, en attente de la chaîne, à reconfirmer, non compté et
pourquoi), puis l'inertie et la formule. Les autres gestes ouvrent un panneau latéral (une
feuille sur mobile), lui aussi dans l'URL : **Panier**, **Propositions**, **Proposer**,
**Détails** d'une version (coquilles, traductions, signalements, historique) et
**Détails** d'une version (coquilles, traductions, objections, historique) et
**« Réglages de la formule »** (W, C, B, la participation habituelle du groupe et les cinq
crans), atteints depuis l'en-tête du document et depuis chaque vote.
5. **En dessous**, les propositions en cours — les 30 autres articles du texte source, à zéro
@@ -71,6 +71,11 @@ les applications clientes (Cesium, Ğecko…) peuvent suivre.
7. **Deux aperçus** : « si les bien cotées passent » et « si tout passe ».
8. **Trois langues** : fr · en · es, pour l'interface comme pour le texte. Le français fait foi ;
une traduction devenue ancienne (le français a changé depuis) est signalée.
9. **Messages** (lot F, ADR 0010) : au menu, une boîte avec le nombre de non-lus (une pastille
sur le bouton du menu en mobile) ; ce qui attend un geste de la personne — une objection à
laquelle répondre, à lever ou à réitérer, une correction de coquille à valider —, chaque
message avec son objet, son texte, ses gestes et son échéance. Une version retenue par une
objection le dit sous l'article, à chacun selon son rôle.
## Les règles
@@ -149,7 +154,14 @@ titre d'un article reste voté avec son texte.
ensuite, par l'ordre de la section.
- **Le titre du document** : à l'entrée d'un autre titre, le document change de titre en
français ; ses traductions restent éditoriales et passent « à revoir » jusqu'à ce qu'on les
reprenne. Une coquille du titre se corrige sans vote.
reprenne. Une coquille du titre se corrige sans vote, par le chemin de toute coquille : celle
d'un autre attend l'auteur du titre (un administrateur pour le titre de départ) ou 3 jours.
- **Face aux objections (ADR 0010)** : « redit » et « contredit » portent sur deux articles,
jamais sur un module. Un ordre ne se corrige pas, ni par son auteur ni par un autre.
- **« Modules à voter »** ne compte pas une version retenue par une objection : personne ne peut
la voter tant qu'elle est retenue. Un article dont la seule version ouverte est retenue sort du
compte, et y revient à la levée. La liste du groupe la compte toujours parmi les propositions en
cours : elle est ouverte.
- Dans une base existante, chaque document reçoit ses modules **une fois**, depuis son état
présent (titre actuel, ordre actuel de chaque section), sans toucher un article ni un vote
(`crates/ld-server/src/module_amend.rs`, journal `module_amendments`, migration `0007`).
@@ -163,11 +175,19 @@ mot (« certifcation » → « certification »). Tout le reste passe par une pr
ponctuation, les chiffres, les signes, l'emphase, les formules, les adresses, et tout changement
de sens.
| Geste | Qui | Effet sur les votes |
|---|---|---|
| Corriger une **coquille** | tout membre sur un texte de départ ou en vigueur ; l'auteur sur sa proposition | aucun — les votes restent, les traductions restent à jour |
| Modifier **le fond** d'une proposition | son auteur | nouvelle révision : les votes antérieurs sont « à reconfirmer », les signalements tombent |
| Modifier le fond d'un texte **en vigueur** ou d'un texte de départ | personne | refusé : on propose une nouvelle version |
| Geste | Qui | Effet | Échéance |
|---|---|---|---|
| Corriger une **coquille** sur son propre texte | l'auteur de la version ; un administrateur sur un texte du seed | appliquée tout de suite : les votes restent, les traductions restent à jour | — |
| Corriger une **coquille** sur le texte d'un autre | tout membre du groupe | **en attente** : un message à l'auteur (aux administrateurs pour un texte du seed), qui valide ou refuse ; la correction se lit, avec son diff, dans « Détails » | 3 jours sans réponse : appliquée |
| Revenir sur une correction (ou l'appliquer finalement) | l'auteur, tant que le texte **n'est pas en vigueur** | le texte d'avant revient (ou la correction passe) | — |
| Corriger un texte **en vigueur** | tout membre ; l'auteur (un administrateur pour le seed) valide | **seule une correction validée** change le texte ; un refus est définitif | 3 jours sans réponse : appliquée |
| Modifier **le fond** d'une proposition | son auteur | nouvelle révision : les votes antérieurs sont « à reconfirmer », les corrections en attente sont périmées ; elle répond aux objections qui attendent l'auteur | — |
| Modifier le fond d'un texte **en vigueur** ou d'un texte de départ | personne | refusé : on propose une nouvelle version | — |
Deux corrections en attente sur un même texte : chacune est jugée contre le texte voté ; à
l'application, celle qui ne tombe plus sur le texte qu'elle a lu est **périmée** (« recharge,
puis recommence »). Les traductions restent éditoriales, sans validation. L'historique dit qui a
écrit chaque correction et qui l'a validée, ou qu'elle est passée à l'échéance (ADR 0010).
Pourquoi si strict : six relectures indépendantes ont montré qu'une ponctuation laissée libre
finit toujours par porter un sens — un signe moins devant un nombre en gras, deux conditions
@@ -205,14 +225,37 @@ change la portée d'une exception. La règle est donc construite à l'envers d'u
- une correction ne s'écrit que sur le texte qui a été jugé : si le texte est entré en vigueur
ou a changé entre-temps, c'est un conflit (« recharge, puis recommence »).
Moteur : `crates/ld-engine/src/edit.rs` ; règle d'écriture : `crates/ld-server/src/proposals.rs`.
Moteur : `crates/ld-engine/src/edit.rs` (la coquille) et `crates/ld-engine/src/correction.rs` (qui
la laisse entrer) ; écriture : `crates/ld-server/src/proposals.rs` et `crates/ld-server/src/typos.rs`.
### Deux articles qui se contredisent
### Deux articles qui se répètent ou se contredisent
Tout membre peut **signaler une contradiction** entre deux propositions, motif à l'appui. Tant
que le signalement tient, celle des deux qui n'est pas en vigueur **ne peut pas entrer en
vigueur**. Il se lève par son auteur (ou un administrateur), ou tombe quand la proposition
signalée est révisée sur le fond.
Tout membre peut faire une **objection** à une version : elle **redit** un autre article (elle le
répète) ou elle le **contredit**, motif à l'appui. **Une objection rend la dernière arrivée des
deux versions non votable jusqu'à sa levée** — jamais un texte en vigueur : si la dernière
arrivée est en vigueur, c'est l'autre qui est retenue. Les votes déjà faits restent ; la version
retenue ne reçoit plus de vote (ni sous l'article, ni dans le panier, ni par la chaîne) et
n'entre pas en vigueur. Pour qu'elle se vote de nouveau, **son auteur répond** : pour une redite,
il **modifie l'article visé** ; pour une contradiction, il **reformule**. La personne qui a fait
l'objection reçoit alors un message : **lever** ou **réitérer** ; sans réponse de sa part sous
**3 jours**, l'objection est levée.
| Qui | Quoi | Effet | Échéance |
|---|---|---|---|
| tout membre du groupe | faire une objection « redit » ou « contredit », motif à l'appui | la dernière arrivée des deux versions (jamais un texte en vigueur) ne se vote plus ; message à son auteur | — |
| l'auteur de la version retenue (tout membre pour une version du seed) | « Modifier l'article visé » (redit) : une proposition liée, sur l'autre article, partie de son texte ; « Reformuler » (contredit) : une révision de fond de sa version | la main passe à la personne qui objecte : message « lever ou réitérer » | 3 jours pour elle |
| la personne qui a fait l'objection | lever | la version se vote de nouveau, et entre en vigueur si ses voix suffisent | — |
| la personne qui a fait l'objection | réitérer | la main revient à l'auteur : message « réponds à nouveau » | aucune pour l'auteur |
| personne | (3 jours sans geste après une réponse) | levée : « 3 jours sans suite » | — |
| un administrateur de trustinWallet | lever | levée « par un administrateur » | — |
| l'auteur | retirer sa version | l'objection prend fin | — |
Une révision de fond de l'une ou l'autre des deux versions vaut réponse, une coquille non ; un
seul tour à la fois (une autre réponse pendant le tour de la personne qui objecte ne change ni le
message ni l'échéance) ; une personne n'a qu'une objection debout sur une même paire. Les
signalements de contradiction d'avant sont devenus des « contredit » (migration 0008). Moteur :
`crates/ld-engine/src/objection.rs` ; serveur : `crates/ld-server/src/objections.rs`,
`messages.rs`, `deadlines.rs` (les échéances, au balayage de 5 minutes et au démarrage) ; ADR 0010.
### Une décision par proposition
@@ -242,7 +285,7 @@ du dépôt. Le groupe d'essai ne publie jamais. `document.json` dit aussi les mo
Un document seedé n'est jamais réinstancié : quand le seed change un texte de départ (le
Préambule devenu Raison d'être), un **amendement de seed** le remplace dans une base existante,
une seule fois, et seulement sur un article que personne n'a touché (*seed a minima* d'origine,
révision 1, aucun vote, aucune correction, aucune traduction modifiée, aucun signalement, texte
révision 1, aucun vote, aucune correction (ni en attente), aucune traduction modifiée, aucune objection, texte
identique à l'empreinte attendue). Chaque décision est consignée (`seed_amendments`, et dans les
journaux quand l'article garde son texte) ; appliqué, l'amendement se lit dans l'historique de
l'article (« texte de départ remplacé », avec le diff) et le texte est republié
@@ -251,7 +294,7 @@ l'article (« texte de départ remplacé », avec le diff) et le texte est repub
### Accès — trustinWallet
Tout le monde connecté peut tout faire dans les groupes qu'il ouvre (lire, proposer, voter,
corriger, signaler) **sauf la gestion des accès**, réservée aux administrateurs de trustinWallet
corriger, faire une objection) **sauf la gestion des accès**, réservée aux administrateurs de trustinWallet
(`/acces`) : membres des groupes, invitations, administrateurs, retours, clé de publication.
Le nom trustinWallet remplace trustWallet (déjà pris). Règles : `crates/trustin-access`.
@@ -265,7 +308,9 @@ du bulletin (`ld1:` + 64 chiffres hexadécimaux). La voix est celle de **l'ident
qui signe**, membre au moment où le serveur confirme la transaction sur l'indexeur ; quelle que
soit la session (invitation ou connexion Ğ1), la même identité n'a qu'une voix par version, et
**le dernier vote fait foi**, dans l'ordre de la chaîne. La chaîne montre qui a voté et quand,
jamais quoi ; chacun ne voit que les totaux. Sans compte des votes configuré
jamais quoi ; chacun ne voit que les totaux. Chacun reçoit **le reçu de son bulletin** (ses votes
et son sel), le retrouve sur « Tes bulletins » et le vérifie dans son navigateur ; personne
d'autre ne le reçoit (ADR 0008, « Le reçu »). Sans compte des votes configuré
(`LD_VOTE_ACCOUNT`), le vote par la chaîne est fermé et l'interface le dit. Dans les groupes
gérés (essai, Axiom…), tout membre vote directement, sans portefeuille.
@@ -295,9 +340,11 @@ Les raisons longues sont dans `docs/adr/`.
de la toile, ou dont l'accès est révoqué, garde les voix déjà confirmées.
- Le serveur fait confiance à l'indexeur pour lire la transaction (remarque, virement, identité,
appartenance à la toile) ; plusieurs indexeurs se configurent (ADR 0008).
- Par Ğecko, le bulletin n'est lié à aucun compte : une copie de son sceau incluse avant lui par
un autre compte le prendrait. Par l'extension, il est lié au compte qui signe.
- Un bulletin non vu sur la chaîne en 24 heures est lâché : un paiement plus tardif ne compte pas.
- Par Ğecko, le bulletin n'est lié à aucun compte : une copie nue de son sceau est ignorée, mais
une copie **payée** (0,1 Ğ1) incluse avant lui par un autre compte le prendrait. Par
l'extension, il est lié au compte qui signe.
- Un bulletin non vu sur la chaîne en 24 heures est lu une dernière fois, puis lâché : un
paiement plus tardif ne compte pas.
- Dans un groupe géré (essai, Axiom…), une même personne admise sous une identité d'invitation
**et** sous sa clé Ğ1 aurait deux voix : c'est à l'administration de n'en admettre qu'une.
- Un administrateur peut créer un nouveau lien pour une identité d'invitation existante
@@ -310,6 +357,10 @@ Les raisons longues sont dans `docs/adr/`.
dans l'historique de l'article.
- Les traductions (en, es) sont éditoriales : tout membre les corrige sans vote, et elles sont
republiées — le français fait foi.
- Une version retenue par une objection attend son auteur aussi longtemps qu'il ne répond pas ;
une personne qui réitère sans fin la garde hors du vote : un administrateur peut lever (ADR 0010).
- Les messages sont dans l'application, sans courriel : qui ne passe pas ne les voit pas, et la
correction ou l'objection qui l'attendait passe à l'échéance de 3 jours.
- Les aperçus (« si les bien cotées passent », « si tout passe ») montrent les articles seuls :
un ordre ou un titre proposé n'y change pas encore la place des articles ni le titre (ADR 0009).
+16 -6
View File
@@ -4,9 +4,9 @@ Chaque contrôle existe en deux versions : **automatique** (Playwright, `web/e2e
`npm run e2e`) et **humaine** (Chiara, sur la production ou en local). Une remarque de Chiara
sur un contrôle vaut échec du contrôle tant qu'elle n'est pas traitée.
Où tester : les contrôles qui écrivent (C5, C6, C7, C21, C22, C25, C26) se font dans le **groupe
Où tester : les contrôles qui écrivent (C5, C6, C7, C21, C22, C25, C26, C28–C31) se font dans le **groupe
d'essai** (caché, plancher C = 1, jamais publié) — jamais sur le texte de la communauté. Les
votes par la chaîne Ğ1 (C11, C17, C23, C25) ne se jouent, pour l'automate, que sur une **chaîne
votes par la chaîne Ğ1 (C11, C17, C23, C25, C32, C33) ne se jouent, pour l'automate, que sur une **chaîne
simulée** (`web/e2e/chain-mock.mjs` : un faux nœud, un faux indexeur, un faux portefeuille) ;
pour une personne, ils coûtent 0,1 Ğ1 réels : c'est un acte « paye » d'Yvv.
@@ -17,7 +17,7 @@ pour une personne, ils coûtent 0,1 Ğ1 réels : c'est un acte « paye » d'Yvv.
| C3 | Le texte en vigueur | Monnaie libre → Docs de référence → Acte d'engagement Certification | trois articles seulement (Raison d'être, Unicité du compte, Réciprocité), chacun « seed a minima · 0 vote » — le nombre réel de ses votes, qui change quand on vote —, sous le titre du document et à la fin de chaque section ses modules (C25, C26) ; en dessous, « Propositions en cours » (30 lignes, une par article) |
| C4 | Gestes contextuels | survoler la Raison d'être → « Le vote » | le vote se **déplie sous l'article**, sans fenêtre : seuil 50 voix pour, il en manque 50 ; « La formule du seuil » se déplie : « M — majorité à pleine participation : 55 % — inertie 3 / 5 · moyenne », 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 : à deux, déplier le vote de « Les deux garanties réciproques », « Pour » | au second vote, « … est entré en vigueur » ; le texte en vigueur compte quatre articles, le vote reste déplié sous le nouveau texte (2 pour · 0 contre) |
| C6 | Coquille sans vote | groupe d'essai : Unicité du compte → « Le vote » → « Coquilles, traductions, signalements, historique » (onglet « Détails ») → « 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. » |
| 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 » (onglet « Détails ») → « 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 |
| 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 3 |
@@ -36,10 +36,16 @@ pour une personne, ils coûtent 0,1 Ğ1 réels : c'est un acte « paye » d'Yvv.
| C21 | Le vote déplié | groupe d'essai : Unicité du compte → « Le vote », puis « Pour » ; une autre personne ouvre le même vote | sous l'article : le niveau d'eau, « 0 pour · 0 contre », « Seuil : … voix pour », « Il manque … », « Tu n'as pas voté sur cette version. » ; après « Pour » : « Ton vote : pour · enregistré », « 1 pour · 0 contre », le bouton enfoncé, « Ton vote ne se montre à personne : seuls les totaux sont visibles. » ; l'autre personne voit 1 pour, jamais qui ; « Le vote » replie ; « Retirer mon vote » remet 0 |
| 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é, « Signer et envoyer (2) » ; puis sous Réciprocité, « Contre » (l'indexeur en retard) puis « Retirer mon vote » ; puis sans portefeuille : « 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 l'article « 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 l'article : « 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 signaler une contradiction. », pas de bouton, les totaux et le seuil restent ; dans le groupe d'essai, le panier et les boutons sont là |
| C25 | L'ordre des articles | groupe d'essai : en fin de « Conclusion », « Proposer un autre ordre » ; cliquer « Monnaie G1 » puis la place 1 ; au clavier, flèche bas puis haut ; « Proposer cet ordre » ; « Pour » ; une deuxième personne vote « Pour » ; 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 « Ordre des articles · <section> » (7, aucun pour l'Ordonnancement, un seul article), ses articles numérotés, « 2 articles · inertie 2 / 5 · basse », « seed a minima · 0 vote » (1 vote après un « Pour », 0 après le retrait) ; la liste où l'on clique : 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 ; le vote de l'ordre proposé se déplie dans la liste des propositions, l'ordre proposé en clair ; il est dans le panier, à la fin de sa section ; à la deuxième voix : « 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, rien ne déborde, chaque ligne fait au moins 44 px |
| 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 » ; lire en anglais | sous le titre : « Titre du document · inertie 4 / 5 · haute · seed a minima · 0 vote » et les trois gestes ; le titre proposé se vote dans la liste des propositions (« Titre du document ») ; à la deuxième voix : « Le titre « … » est entré en vigueur. », le document change de titre, son vote reste déplié sous le titre (2 pour) ; en anglais, l'ancien titre traduit, marqué « translation needs review » |
| 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 l'article : « 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 le seuil 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 : en fin de « Conclusion », « Proposer un autre ordre » ; 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 (dès 16 membres, une voix suffit dans le groupe d'essai : ADR 0007) ; 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 « Ordre des articles · <section> » (7, aucun pour l'Ordonnancement, un seul article), ses articles numérotés, « 2 articles · inertie 2 / 5 · basse », « seed a minima · 0 vote » ; le vote d'un ordre en vigueur déplié montre la liste entière ; la liste où l'on clique : 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 ; le vote de l'ordre proposé se déplie dans la liste des propositions, l'ordre proposé en clair ; 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, rien ne déborde, chaque ligne fait au moins 44 px |
| 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 : « Titre du document · inertie 4 / 5 · haute · seed a minima · 0 vote » et les trois gestes ; le titre proposé se vote dans la liste des propositions (« Titre du document ») ; à la voix qui suffit : « Le titre « … » est entré en vigueur. », le document change de titre, son vote reste déplié sous le titre ; 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 : les « pour » demandés au-delà de C, à 2 votants comme d'habitude. » |
| C28 | Objection « redit » | 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 ; Aude ouvre « Messages » → « Modifier l'article visé », complète le texte et soumet ; Oscar ouvre « Messages » → « Lever l'objection » ; Vera recharge | « Objection enregistrée : la dernière arrivée des deux versions ne se vote plus jusqu'à sa levée. » ; chez Oscar, « « … » redit « Unicité du compte » », « cette version ne se vote plus », « Lever l'objection » ; chez Vera, « Une objection retient cette version : elle ne se vote plus jusqu'à sa levée. Les votes déjà faits restent. », « Elle redit « Unicité du compte ». », pas de « Pour », la ligne marquée « non votable : objection » ; 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 |
| 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 » |
| 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 » |
| 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é |
## Au-delà de la liste
@@ -69,4 +75,8 @@ page, la langue et la taille de l'écran. Les retours se traitent dans trustinWa
| 2026-10-30 | automate | local, lot A (entrée, logo, ambiances, menu, listes, Décisions) | C1–C17, M1 | 18 / 18 verts |
| 2026-10-30 | automate | local, lot C (inertie à cinq crans, réglages de la formule) | C1–C20, M1 | 21 / 21 verts |
| 2026-10-31 | automate | local, lot B (le vote déplié, le panier, le vote par la chaîne Ğ1 simulée) | C1–C24, M1 | 25 / 25 verts |
| 2026-10-31 | automate | local, lot B2 (vote par la chaîne : corrections de la relecture de `74f96be`, reçu), `c7d2791` | C1–C24, C32, C33, M1 | 27 / 27 verts |
| 2026-10-31 | automate | local, lot F (objections « redit » / « contredit », coquilles validées, messages ; horloge du serveur avancée pour l'échéance) | C1–C24, C28–C31, M1 | 29 / 29 verts |
| 2026-10-31 | automate | local, fusion de F avec B2 (`cd7e683`) ; C22 ne suppose plus un groupe d'essai de moins de 16 membres | C1–C24, C28–C33, M1 | 31 / 31 verts |
| 2026-10-31 | automate | local, lot D (l'ordre des articles, le titre du document, la participation ramenée) | C1–C27, M1 | 29 / 29 verts |
| 2026-10-31 | automate | local, fusion de la tête du chantier (`924a40d` : B2, F) dans le lot D ; C25 et C26 supportent un groupe d'essai où une voix suffit | C1–C33, M1 | 34 / 34 verts (35 tests) |
+17 -8
View File
@@ -7,9 +7,11 @@
Orch seul sur le dépôt (sous-agents en copies de travail). **M1 (L1–L8) en ligne** depuis le
2026-10-30 à 15 h 45 (`8727315`, acte `actes/2026-10-30-m1-mise-en-ligne.md`) ; Raison d'être
publiée (commit `35864eb` du dépôt des textes). Lot C fusionné et relu, acte M3a préparé (`actes/2026-10-30-m3-inertie-cinq-crans.md`). Lot B lancé
avec les défauts de Q5–Q7 (recherche : `docs/recherche/vote-g1-chaine.md`). D après C, F
après B. Restes mineurs de la relecture M1 : focus et flèches des pastilles d'ambiance (lot B).
publiée (commit `35864eb` du dépôt des textes). Actes M3a et M2 figés, ils attendent « déploie ».
Sur `chantier/acte-certification` : B2 (`7ffa4fd`, repris en `9c8f4cc`), F (`cd7e683`) et `924a40d`
(C22) ; boucle verte, e2e 31 / 31 ; relecture indépendante en cours. Le lot D, fini sur sa branche,
fusionne chantier dans `lot/d-modules` (17 fichiers en conflit). Puis : relecture de la fusion D,
répétition des migrations 0007 et 0008 sur une copie de la base de production, dossier d'acte.
## Critère de livraison (liste fermée)
@@ -38,10 +40,11 @@ chaîne (question stratégique, `docs/recherche/vote-g1-chaine.md`) ; l'affichag
|---|---|---|---|---|
| A | L1–L6 : entrée, DA, menu, listes, Décisions | high | **en ligne** 30/10 15 h 45 | `lot/a-entree` |
| R | L7–L8 : Raison d'être (amendement de seed gardé), versions groupées | high | **en ligne** 30/10 15 h 45 | `lot/r-texte` |
| B | L9 : vote déplié, vote groupé, vote par transaction de 0,1 Ğ1 | xhigh | fusionné (`74f96be`), boucle verte, image construite ; relecture en cours | `lot/b-vote` |
| B | L9 : vote déplié, vote groupé, vote par transaction de 0,1 Ğ1 | xhigh | fusionné et relu (`74f96be`) ; acte M2 figé (vote par la chaîne éteint) | `lot/b-vote` |
| B2 | Corrections du vote avant de l'ouvrir (relecture de `74f96be`, points 2 à 8) | xhigh | fusionné (`7ffa4fd`) ; relu « à reprendre », repris en `9c8f4cc`, en relecture | `lot/b2-vote-sur` |
| C | L10 : cinq crans, échelle, réglages | xhigh | fusionné et relu (`a576b68`, `71819f9`) ; acte M3a figé | `lot/c-inertie` |
| D | L11 + titre du doc en module (4) + restes mineurs des relectures | high | lancé le 31/10 | `lot/d-modules` |
| F | L12–L13 : objections, coquilles validées, messages, délai de 3 jours | xhigh | lancé le 31/10 | `lot/f-objections` |
| D | L11 + titre du doc en module (4) + restes mineurs des relectures | high | fini sur sa branche (e2e 29 / 29) ; fusionne chantier dans sa branche | `lot/d-modules` |
| F | L12–L13 : objections, coquilles validées, messages, délai de 3 jours | xhigh | fusionné (`cd7e683`), boucle verte ; en relecture | `lot/f-objections` |
## Questions (réponse par défaut appliquée tant qu'Yvv n'a pas tranché)
@@ -54,6 +57,7 @@ chaîne (question stratégique, `docs/recherche/vote-g1-chaine.md`) ; l'affichag
| Q5 | Secret du vote (Q2) et transaction publique (Q1) : le commentaire porte le choix en clair, ou une empreinte scellée ? | défaut : empreinte scellée (la chaîne montre qui a voté et quand, pas quoi) |
| Q6 | Ğ1Companion ne signe pas encore une transaction construite par une page : quelle extension pour le geste unique ? | défaut : duniter-connect maintenant (Ğ1Companion et trustinWallet se brancheront sur la même interface), lien et QR Ğecko sur mobile |
| Q7 | Le compte qui reçoit les 0,1 Ğ1 : à qui, et que deviennent les sommes ? | défaut : un compte libreDecision créé par Yvv dans Ğecko, les sommes restent au collectif |
| Q8 | Le secret du vote tombe par recoupement : la chaîne montre qui vient de voter, et les totaux bougent aussitôt (relecture de `74f96be`) | à trancher avant d'ouvrir le vote ; pas de défaut posé |
Défauts posés par orch, sans question (Yvv peut les corriger) :
- Décisions : « modules restant à voter » = les modules du doc pas encore adoptés par un vote
@@ -69,9 +73,14 @@ Défauts posés par orch, sans question (Yvv peut les corriger) :
## Actes
- M1 : **exécuté** le 30/10/2026, 15 h 29 – 15 h 52 (`actes/2026-10-30-m1-mise-en-ligne.md`).
- M3a (L10) : **figé** sur `71819f9` (`actes/2026-10-30-m3-inertie-cinq-crans.md`), relectures inscrites, attend « déploie ».
- M3a (L10) : **figé** sur `71819f9` (`actes/2026-10-30-m3-inertie-cinq-crans.md`), attend « déploie ».
- M2 + M3a (L9 et L10) : **figé** sur `74f96be` (`actes/2026-10-31-m2-vote.md`), le vote par la chaîne éteint ; remplace M3a s'il est armé.
Restes mineurs pour le lot D (relecture de `71819f9`, captures du lot B) : « seed a minima · 0 vote » affiché à côté des totaux ; pourcentage des réglages calculé sur le nombre arrondi ; liste explicite des statuts comptés dans la médiane ; affichage de la participation ramenée couvert par un e2e ; formulation « les seuils se calculent sur » (mettre le groupe en sujet) ; flèches du sélecteur de crans.
Restes mineurs de `71819f9` et du lot B : faits dans le lot D.
À dire à Yvv : dans le groupe d'essai (C = 1), dès 16 membres une voix seule fait passer un texte,
la garde B^W passant sous la précision du calcul (ADR 0007). Monnaie libre (C = 50) n'est pas
concernée.
Ensuite : Chaque mise en ligne (M1 à M4) attend « déploie » d'Yvv et une relecture
indépendante inscrite. La migration « Raison d'être » touche la base de production : elle ne