v3 : déploiement (image unique, produit à la racine, maquette en sous-domaine) et documentation du chantier
- docker/app.Dockerfile : une image Rust + Svelte, la construction rejoue toute la boucle (fmt, clippy -D warnings, tests, svelte-check, vitest) ; utilisateur non-root, volume /data. docker/app-compose.yml pour sonic (fabio). - .woodpecker/app.yml : produit sur decision.librodrome.org, attend la maquette, écarte tout conteneur qui revendique encore la racine, healthcheck du commit. - .woodpecker/maquette.yml (ex .woodpecker.yml) : la maquette v2 telle quelle, sur maquette.decision.librodrome.org, mêmes volumes. - .env.example de la maquette rangé dans maquette/ ; celui de la v3 à la racine. - Docs : README, CONTRIBUTING (travail à deux), CLAUDE.md v3, HANDOFF, docs/chantiers (feuille de route, fiche, contrôles, onboarding de Chiara, demande à poka), docs/adr 0001–0006. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
# Chantier 1 — Acte d'engagement Certification
|
||||
|
||||
> Binôme : **Yvv** (porteur) · **Chiara** (testeuse et codeuse — ses tests d'usage valent
|
||||
> contrôles). Branche commune : `chantier/acte-certification`. Ouvert le 2026-10-21.
|
||||
> Production : https://decision.librodrome.org
|
||||
|
||||
## Le besoin, en une phrase
|
||||
|
||||
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
|
||||
les applications clientes (Cesium, Ğecko…) peuvent suivre.
|
||||
|
||||
## Ce que voit la personne
|
||||
|
||||
1. **Accueil sobre** : « Rendre possible la décision collective » / « en fonction du contexte,
|
||||
processus et modalités, boîte à outils », les quatre outils en une ligne chacun, puis la
|
||||
connexion. Le menu complet à gauche : Décisions · Docs de référence · Mandats · Protocoles
|
||||
(seul Docs de référence est actif).
|
||||
2. **Connexion Ğ1** — la même que le forum Monnaie libre (connect.monnaie-libre.fr). En attendant
|
||||
l'inscription du client OAuth2, des **liens d'invitation** à usage unique.
|
||||
3. **Groupes** : avec une clé Ğ1, on voit Monnaie libre, Axiom, Librodrome et le Groupe local
|
||||
Vallée Drôme Crestois — pas l'Atelier du canal. Un groupe et son contenu ne s'ouvrent qu'à
|
||||
ses membres ; Monnaie libre s'ouvre à tout membre de la toile de confiance, les autres
|
||||
groupes sur accord dans trustinWallet.
|
||||
4. **Le texte en vigueur**, seul, en grand, typographie de lecture (Literata) : au départ le
|
||||
Préambule et les deux engagements fondamentaux (Unicité du compte, Réciprocité), marqués
|
||||
*seed a minima · 0 vote*. Au survol (ou toujours visibles sur mobile), trois gestes discrets :
|
||||
**Le vote** (en cours, inertie, formule, annexes) · **Les propositions** · **Proposer**. Ils
|
||||
ouvrent un panneau latéral (une feuille sur mobile) dont l'état vit dans l'URL.
|
||||
5. **En dessous**, les propositions en cours — les 30 autres articles du texte source, à zéro
|
||||
vote, inertie standard — rangées par section (introduction, fondamental, technique,
|
||||
conclusion, annexes, formule, inertie, ordonnancement), les variantes signalées.
|
||||
6. **Deux aperçus** : « si les bien cotées passent » et « si tout passe ».
|
||||
7. **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.
|
||||
|
||||
## Les règles
|
||||
|
||||
### Le seuil — formule inertielle Ğ1
|
||||
|
||||
```
|
||||
R = C + B^W + (M + (1 − M)·(1 − (T/W)^G)) · max(0, T − C)
|
||||
```
|
||||
|
||||
W = électorat (Monnaie libre : taille de la toile, lue sur la chaîne toutes les 6 h ; un groupe
|
||||
géré : ses membres), T = votes exprimés, M = majorité, G = gradient, B = 0,1, **C = plancher de
|
||||
votants « pour »** (Monnaie libre : **50** ; groupe d'essai : 1). Adoptée si « pour » ≥ ⌈R⌉.
|
||||
|
||||
| Inertie | M | G |
|
||||
|---|---|---|
|
||||
| basse | 50 % | 0,1 |
|
||||
| standard (au départ, partout) | 50 % | 0,2 |
|
||||
| haute | 60 % | 0,4 |
|
||||
| maximale | 66 % | 0,6 |
|
||||
|
||||
Moteur : `crates/ld-engine/src/threshold.rs` (testé : 7224 / 120 votants → 94 voix requises).
|
||||
|
||||
### Le vote permanent
|
||||
|
||||
- Toute version d'un article (proposition ou texte en vigueur) se vote à tout moment.
|
||||
- Une proposition **remonte en vigueur** dès qu'elle atteint son seuil **et** tient une marge
|
||||
(pour − requis) plus large que la version en place. La version déplacée redevient une
|
||||
proposition, avec ses votes. Un *seed a minima* a pour marge −C : la première proposition qui
|
||||
atteint son seuil le remplace.
|
||||
- Retirer un article est une proposition comme une autre (« retirer cet article »).
|
||||
- Le balayage tourne à chaque vote et toutes les 5 minutes (la taille de la toile bouge).
|
||||
|
||||
### L'inertie se vote aussi
|
||||
|
||||
Chaque article porte son inertie. La changer est une proposition, **votée elle-même à
|
||||
l'inertie du cran au-dessus** (« inertie + ») : alourdir ou alléger demande plus que modifier.
|
||||
|
||||
### Corriger n'est pas voter
|
||||
|
||||
| Geste | Qui | Effet sur les votes |
|
||||
|---|---|---|
|
||||
| Corriger une **coquille** (accents, casse, ponctuation, espaces ; ou jusqu'à 2 mots à 2 lettres près) | 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 |
|
||||
|
||||
Le classement est prudent : un chiffre ou un mot de négation (ne, pas, jamais, personne…)
|
||||
touché rend la modification « de fond ». Moteur : `crates/ld-engine/src/edit.rs`.
|
||||
|
||||
### Deux articles qui 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.
|
||||
|
||||
### Une décision par proposition
|
||||
|
||||
L'éditeur a un **assistant à règles** (pas d'IA pour l'instant ; plus tard, une IA locale, sans
|
||||
abonnement) : il repère un texte qui porte plusieurs décisions et propose de le **découper en
|
||||
brouillons**, signale une proposition très proche d'une existante, et un texte long. Moteur :
|
||||
`crates/ld-engine/src/assist.rs`.
|
||||
|
||||
### Brouillon → proposition
|
||||
|
||||
On écrit en brouillon (libre, invisible des autres), on soumet ; la proposition est alors
|
||||
ouverte au vote. Son auteur peut la retirer.
|
||||
|
||||
### Publication
|
||||
|
||||
Chaque entrée en vigueur (et la publication initiale) passe par une file d'envoi : le serveur
|
||||
écrit `fr.md`, `en.md`, `es.md` (front matter : document, langue, source, mise à jour ; les
|
||||
traductions marquées éditoriales) et `document.json`, commit et pousse sur
|
||||
`git.duniter.org/Yvv/libredecision-textes`, chemin `monnaie-libre/acte-engagement-certification/`.
|
||||
Échec → nouvel essai avec délai croissant. La clé de publication est générée par le serveur ;
|
||||
sa partie publique s'affiche dans trustinWallet, à ajouter comme clé de déploiement (écriture)
|
||||
du dépôt. Le groupe d'essai ne publie jamais.
|
||||
|
||||
### 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
|
||||
(`/acces`) : membres des groupes, invitations, administrateurs, retours, clé de publication.
|
||||
Le nom trustinWallet remplace trustWallet (déjà pris). Règles : `crates/trustin-access`.
|
||||
|
||||
## Le groupe d'essai
|
||||
|
||||
Caché, plancher C = 1, sans publication : on y éprouve tout (adoption, coquilles, découpage)
|
||||
sans toucher au texte de la communauté. Chiara et Yvv en sont membres.
|
||||
|
||||
## Décisions prises (2026-10-21, avec Yvv)
|
||||
|
||||
| Question | Décision |
|
||||
|---|---|
|
||||
| Stack | Rust (serveur, moteur) + Svelte (interface), pour la durée, la performance, la modularité |
|
||||
| Domaine | le produit à la racine `decision.librodrome.org` ; la maquette sur `maquette.decision.librodrome.org` |
|
||||
| Connexion | client OAuth2 de connect.monnaie-libre.fr (demande à poka) ; liens d'invitation en attendant |
|
||||
| Dépôt des textes | `git.duniter.org/Yvv/libredecision-textes` (compte d'Yvv) |
|
||||
| Garde-fou du vote permanent | nombre minimal de votants « pour » (C) |
|
||||
| Langues | fr, en, es ; le français est voté, les traductions sont éditoriales |
|
||||
| Chiara | testeuse et codeuse |
|
||||
| Assistant | à règles d'abord ; IA locale plus tard, sans dépendance d'abonnement |
|
||||
|
||||
Les raisons longues sont dans `docs/adr/`.
|
||||
|
||||
## Questions ouvertes (à Yvv)
|
||||
|
||||
- **Licence** du code — non choisie.
|
||||
- **Texte « Paramètres par défaut » du seed** (F1.2) : il annonce C = 0 et une durée de 30 jours,
|
||||
alors que le vote est permanent avec C = 50. À reformuler par proposition (c'est leur rôle),
|
||||
ou à corriger dans le seed avant la première publication si c'est une erreur de transcription.
|
||||
- Anglais : l'interface est en anglais américain, le seed en anglais britannique.
|
||||
|
||||
## Ce qui reste après la livraison
|
||||
|
||||
- L'inscription du client OAuth2 (poka) : `DEMANDE-CONNECT.md`, puis les deux secrets dans la CI.
|
||||
- Les retours de Chiara → contrôles → corrections, sur la branche du chantier.
|
||||
- Ensuite : chantier 2, l'Acte d'engagement forgeron (qualification d'une compétence).
|
||||
@@ -0,0 +1,42 @@
|
||||
# Contrôles d'usage — Acte d'engagement Certification
|
||||
|
||||
Chaque contrôle existe en deux versions : **automatique** (Playwright, `web/e2e/`, rejoué par
|
||||
`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) se font dans le **groupe d'essai**
|
||||
(caché, plancher C = 1, jamais publié) — jamais sur le texte de la communauté.
|
||||
|
||||
| # | Contrôle | Geste humain | Attendu |
|
||||
|---|---|---|---|
|
||||
| C1 | L'accueil | ouvrir `/` sans être connectée | « Rendre possible la décision collective », la phrase d'outils, les quatre sections ; le menu à gauche avec les quatre outils, trois grisés ; « Se connecter avec sa clé Ğ1 » |
|
||||
| C2 | Les groupes | se connecter, ouvrir « Groupes » | Monnaie libre, Axiom, Librodrome, Groupe local Vallée Drôme Crestois ; **pas** l'Atelier du canal |
|
||||
| C3 | Le texte en vigueur | Monnaie libre → Docs de référence → Acte d'engagement Certification | trois articles seulement (Préambule, Unicité du compte, Réciprocité), chacun « seed a minima · 0 vote » ; en dessous, « Propositions en cours » (32 lignes) |
|
||||
| C4 | Gestes contextuels | survoler le Préambule → « Le vote » | un panneau : seuil 50 voix pour, il en manque 50 ; « La formule du seuil » se déplie ; l'URL garde le panneau ; Échap le ferme |
|
||||
| C5 | Entrée en vigueur | groupe d'essai : à deux, voter « Pour » sur « Les deux garanties réciproques » | au second vote, « … est entré en vigueur » ; le texte en vigueur compte quatre articles |
|
||||
| C6 | Coquille sans vote | groupe d'essai : Préambule → « Le vote » → « Corriger une coquille », remplacer « latransmission » par « la transmission » | « Coquille corrigée, sans toucher aux votes. » ; un changement de sens est refusé : « Ce changement touche au sens : propose-le comme modification. » |
|
||||
| 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 |
|
||||
| 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) |
|
||||
| M1 | Mobile | téléphone (ou fenêtre étroite) | menu en tiroir, les trois gestes visibles sans survol, le panneau s'ouvre en feuille |
|
||||
|
||||
## Au-delà de la liste
|
||||
|
||||
Ce que l'automate ne voit pas et que Chiara regarde :
|
||||
|
||||
- **la lecture** : le texte est-il beau, aéré, sans bruit ? lit-on un article sans effort ?
|
||||
- **la fatigue** : un geste de trop, une étape inutile, un mot qui arrête ;
|
||||
- **le vocabulaire** : un libellé qui parle du système au lieu de parler de toi ou du groupe ;
|
||||
- **les deux ambiances** (pierre / nuit) et le clavier seul (Tab, Entrée, Échap) ;
|
||||
- **les langues** : une traduction maladroite, une chaîne restée en français.
|
||||
|
||||
Chaque remarque passe par « Faire un retour » (menu de gauche) : elle arrive datée, avec la
|
||||
page, la langue et la taille de l'écran. Les retours se traitent dans trustinWallet
|
||||
(Vu → Traité) et, s'ils changent une règle, dans `CHANTIER.md`.
|
||||
|
||||
## Journal des passages
|
||||
|
||||
| Date | Qui | Où | Contrôles | Résultat |
|
||||
|---|---|---|---|---|
|
||||
| 2026-10-21 | automate | local, serveur jetable :8092 | C1–C10, M1 | 11 / 11 verts |
|
||||
@@ -0,0 +1,42 @@
|
||||
# Demande à poka — client OAuth2 sur connect.monnaie-libre.fr
|
||||
|
||||
Brouillon prêt à envoyer (par Yvv, en message privé à poka sur forum.monnaie-libre.fr ou par
|
||||
le canal habituel). Rien de secret dedans ; la réponse, elle, contiendra un secret.
|
||||
|
||||
---
|
||||
|
||||
Bonjour poka,
|
||||
|
||||
On ouvre libreDecision en production sur **https://decision.librodrome.org** : la communauté
|
||||
y tient l'**Acte d'engagement Certification** comme un texte vivant, voté article par article
|
||||
(formule inertielle Ğ1). On voudrait la même connexion que le forum : connect.monnaie-libre.fr.
|
||||
|
||||
Peux-tu inscrire un client OAuth2 ?
|
||||
|
||||
- **Nom affiché** : libreDecision
|
||||
- **Site** : https://decision.librodrome.org
|
||||
- **URI de redirection** : `https://decision.librodrome.org/api/auth/g1/callback`
|
||||
- **Flux** : authorization code (`/oauth/authorize` → `/oauth/token` en basic auth →
|
||||
`/oauth/userinfo`), sans scope particulier
|
||||
- **Ce qu'on lit de `/oauth/userinfo`** : `id` (idty:N), `username`, `address`, `member` —
|
||||
rien d'autre n'est stocké ; seuls les membres de la toile ouvrent le groupe Monnaie libre.
|
||||
|
||||
Il nous faudrait en retour le `client_id` et le `client_secret` (le secret par un canal privé,
|
||||
pas sur le forum).
|
||||
|
||||
Merci !
|
||||
Yvv
|
||||
|
||||
---
|
||||
|
||||
## À la réponse
|
||||
|
||||
1. Ne pas coller le secret dans une conversation : protocole `/tmp/pwd.txt` (l'assistant crée
|
||||
et ouvre le fichier, Yvv colle).
|
||||
2. Ajouter dans Woodpecker (dépôt LPK/decision) deux secrets : `connect_client_id`,
|
||||
`connect_client_secret`.
|
||||
3. **Ensuite seulement** (un `from_secret` absent fait refuser tout le pipeline) : dans
|
||||
`.woodpecker/app.yml`, étape `deploy`, écrire `/opt/libredecision-app/secrets.env` avec
|
||||
`LD_CONNECT_CLIENT_ID` et `LD_CONNECT_CLIENT_SECRET` (chmod 600) — le compose le lit déjà.
|
||||
4. Contrôle : « Se connecter avec sa clé Ğ1 » mène à connect.monnaie-libre.fr et revient
|
||||
connecté ; un membre de la toile ouvre Monnaie libre.
|
||||
@@ -0,0 +1,72 @@
|
||||
# Bienvenue sur le chantier — Chiara
|
||||
|
||||
Tu es **testeuse et codeuse** sur ce chantier : tes tests d'usage sont nos contrôles (une
|
||||
remarque de toi = un contrôle à repasser), et tu peux corriger ou construire toi-même.
|
||||
|
||||
## 1. Ce qu'on construit
|
||||
|
||||
Lis d'abord `CHANTIER.md` (10 minutes) : le texte vivant, le vote permanent, coquille ≠ vote,
|
||||
les contradictions, l'inertie votée, la publication. Puis `CONTROLES.md` : ce que tu vérifies.
|
||||
|
||||
## 2. Tes accès (préparés par Yvv)
|
||||
|
||||
| Quoi | Pour quoi | Qui le fait |
|
||||
|---|---|---|
|
||||
| Un **lien d'invitation** à decision.librodrome.org (groupes Monnaie libre + groupe d'essai) | tester en production avant la connexion Ğ1 | Yvv, dans trustinWallet (`/acces`) |
|
||||
| Ta **clé Ğ1** | une fois connect.monnaie-libre.fr branché, tu te connectes comme sur le forum | — |
|
||||
| Un compte sur **git.open.us.org**, collaboratrice de `yvv/decision` | pousser tes branches, ouvrir des demandes de fusion | Yvv |
|
||||
|
||||
Le lien d'invitation s'ouvre **une seule fois** et expire en 14 jours ; il ouvre ta session sur
|
||||
ce navigateur pour 30 jours.
|
||||
|
||||
## 3. Tester sans rien installer
|
||||
|
||||
1. Ouvre ton lien d'invitation → tu arrives connectée.
|
||||
2. Les contrôles qui écrivent (voter, corriger, découper) se font dans le **groupe d'essai** :
|
||||
il est caché, une seule voix « pour » suffit à faire passer une proposition, et rien n'en
|
||||
sort. Le texte de Monnaie libre, lui, est le vrai : lis-le, ne vote que pour de vrai.
|
||||
3. Passe les contrôles C1–C10 et M1 (sur ton téléphone aussi), puis tout ce qui te gêne.
|
||||
4. Chaque remarque : **« Faire un retour »** dans le menu de gauche. Écris ce que tu as fait, ce
|
||||
que tu attendais, ce qui s'est passé. La page, la langue et la taille de l'écran sont jointes.
|
||||
|
||||
## 4. Coder en local
|
||||
|
||||
Prérequis : git, Node 22, Rust (rustup — la version 1.99 s'installe toute seule grâce à
|
||||
`rust-toolchain.toml`).
|
||||
|
||||
```bash
|
||||
git clone gitea@git.open.us.org:yvv/decision.git libreDecision && cd libreDecision
|
||||
git switch chantier/acte-certification
|
||||
curl --proto '=https' -sSf https://sh.rustup.rs | sh -s -- -y # si Rust n'est pas installé
|
||||
cd web && npm ci && npm run build && cd ..
|
||||
LD_DEV_LOGIN=1 cargo run -p ld-server # http://127.0.0.1:8002 — API + interface
|
||||
# dans un second terminal, pour l'interface à chaud :
|
||||
cd web && npm run dev # http://127.0.0.1:3002
|
||||
```
|
||||
|
||||
`LD_DEV_LOGIN=1` affiche une connexion « développement » : tu tapes un nom, tu es membre de
|
||||
tous les groupes (y compris l'essai). La base locale vit dans `data/` — supprime ce dossier pour
|
||||
repartir du texte de départ.
|
||||
|
||||
Où sont les choses :
|
||||
|
||||
- les **règles** (seuil, coquille, découpage, aperçus) : `crates/ld-engine/` — pur, testé ;
|
||||
- les **accès** : `crates/trustin-access/` ;
|
||||
- l'**API** : `crates/ld-server/src/` (une route = une fonction ; scénarios dans `tests/api.rs`) ;
|
||||
- l'**interface** : `web/src/routes/` (pages) et `web/src/lib/components/` ;
|
||||
- les **textes affichés** : `web/src/lib/i18n/fr.ts` (puis `en.ts`, `es.ts`) — jamais en dur ;
|
||||
- le **texte de départ** : `seeds/acte-engagement-certification.json`.
|
||||
|
||||
## 5. Ta boucle avant de pousser
|
||||
|
||||
```bash
|
||||
cargo fmt --all --check && cargo clippy --workspace --all-targets -- -D warnings && cargo test --workspace
|
||||
cd web && npm run check && npm test && npm run build && npm run e2e
|
||||
```
|
||||
|
||||
Tout vert, puis : `git switch -c chiara/<sujet>`, commits, `git push origin chiara/<sujet>`, et une
|
||||
demande de fusion vers `chantier/acte-certification`. Le détail : `CONTRIBUTING.md`.
|
||||
|
||||
## 6. Si tu bloques
|
||||
|
||||
Écris à Yvv, ou laisse un retour dans l'outil en commençant par « BLOQUÉE : ».
|
||||
Reference in New Issue
Block a user