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,19 @@
|
||||
# 0001 — Rust + Svelte, une image, SQLite
|
||||
|
||||
**Contexte.** La v2 (Nuxt local-first + FastAPI) a servi de maquette. Yvv veut « un dev rust -
|
||||
svelte pour la longue durée, la performance, la modularité et la compilation de haute qualité ».
|
||||
Le premier chantier a besoin d'un serveur (votes partagés, publication), pas d'un stockage
|
||||
navigateur.
|
||||
|
||||
**Décision.**
|
||||
- Serveur en Rust : `ld-engine` (règles pures, sans I/O), `trustin-access` (accès),
|
||||
`ld-server` (axum + sqlx). Toolchain épinglée, `clippy -D warnings`, `unsafe` interdit.
|
||||
- Interface SvelteKit / Svelte 5 en SPA statique, compilée et servie par le même binaire.
|
||||
- SQLite (WAL) dans un volume nommé : une instance, des milliers de votants, aucune base à
|
||||
administrer. Migrations additives seulement.
|
||||
- Une seule image ; sa construction rejoue toute la boucle.
|
||||
- La maquette v2 reste dans `maquette/`, intacte, déployée à part.
|
||||
|
||||
**Coût.** Deux langages dans le dépôt ; une instance unique (pas de réplication). Si la
|
||||
synchronisation entre instances devient nécessaire, elle passera par le dépôt des textes et une
|
||||
API, pas par la base.
|
||||
@@ -0,0 +1,20 @@
|
||||
# 0002 — Vote permanent : marge du texte en place et plancher C
|
||||
|
||||
**Contexte.** Chaque article est sous vote permanent ; « dès qu'une proposition atteint le score,
|
||||
elle remonte en vigueur ». La formule inertielle Ğ1 donne un seuil faible quand peu de gens
|
||||
votent : sans garde-fou, une seule voix ferait passer un texte. Sans règle de départage, deux
|
||||
versions qui atteignent leur seuil s'échangeraient la place à chaque vote.
|
||||
|
||||
**Décision.**
|
||||
- Plancher **C = nombre minimal de votants « pour »** (Monnaie libre : 50 ; essai : 1), dans
|
||||
la formule (`R = C + …`) — choix d'Yvv.
|
||||
- Une proposition entre en vigueur si elle atteint son seuil **et** tient une marge
|
||||
(pour − requis) strictement plus large que la version en place. La version déplacée redevient
|
||||
une proposition avec ses votes : rien n'est perdu, tout peut revenir.
|
||||
- Les textes de départ sont des *seeds a minima* (0 vote, marge −C) : visibles, non adoptés.
|
||||
- Changer l'inertie d'un article est une proposition votée à l'inertie du cran au-dessus.
|
||||
- Le balayage tourne après chaque geste et toutes les 5 minutes, sous un verrou global.
|
||||
|
||||
**Coût.** Une version en place très soutenue est difficile à déloger — c'est voulu. La taille
|
||||
de la toile (W) bouge : un texte peut passer ou repasser sans nouveau vote ; chaque entrée en
|
||||
vigueur est datée et chiffrée dans `adoptions`.
|
||||
@@ -0,0 +1,15 @@
|
||||
# 0003 — Corriger n'est pas voter
|
||||
|
||||
**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é.
|
||||
|
||||
**Décision.** Le moteur classe chaque modification (`ld-engine/src/edit.rs`) :
|
||||
- **coquille** si le squelette (sans accents, casse, ponctuation, espaces) est identique, ou si
|
||||
au plus 2 mots diffèrent de 2 lettres au plus, sans chiffre ni mot de négation (ne, pas,
|
||||
jamais, personne…) ; elle s'applique sans vote, garde les votes et les traductions ;
|
||||
- **de fond** sinon : nouvelle révision d'une proposition ouverte (par son auteur), votes
|
||||
antérieurs « à reconfirmer », signalements levés ; refusée sur un texte en vigueur.
|
||||
L'éditeur montre le verdict avant d'enregistrer. Les brouillons s'éditent librement.
|
||||
|
||||
**Coût.** Le classement est prudent : certaines vraies coquilles (« persone » → « personne »)
|
||||
passent pour du fond et demandent une proposition. On préfère ce sens d'erreur.
|
||||
@@ -0,0 +1,14 @@
|
||||
# 0004 — Contradictions : signalées par les personnes, bloquantes
|
||||
|
||||
**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.
|
||||
|
||||
**Décision.** Tout membre signale une contradiction entre deux propositions, avec un motif.
|
||||
Tant que le signalement tient, celle qui n'est pas en vigueur ne peut pas y entrer. Il se lève
|
||||
par son auteur ou un administrateur, et tombe si la proposition signalée change sur le fond.
|
||||
L'assistant, lui, prévient (sans bloquer) quand un texte porte plusieurs décisions ou ressemble
|
||||
à une proposition existante.
|
||||
|
||||
**Coût.** Un signalement abusif bloque une proposition jusqu'à sa levée. Les signalements sont
|
||||
publics, motivés, et l'administration peut les lever.
|
||||
@@ -0,0 +1,17 @@
|
||||
# 0005 — Publication par file d'envoi vers un dépôt git
|
||||
|
||||
**Contexte.** « Le tout est automatiquement poussé sur le dépôt git exploité par les applis
|
||||
clientes. » Le réseau ou la forge peuvent être indisponibles ; un vote ne doit jamais échouer
|
||||
pour autant.
|
||||
|
||||
**Décision.** Chaque entrée en vigueur (ou correction de coquille, ou traduction d'un texte en
|
||||
vigueur) ajoute une ligne à une file d'envoi en base ; au démarrage, chaque document publié y
|
||||
est remis une fois (rien ne se perd sur un redémarrage, un document inchangé ne fait pas de
|
||||
commit : sa date est celle du dernier changement, jamais « maintenant »). Un travailleur rend `fr.md`, `en.md`,
|
||||
`es.md` et `document.json` dans le clone du serveur, commit, pousse avec une clé de déploiement
|
||||
générée par le serveur (sa partie publique s'affiche dans trustinWallet), et réessaie avec un
|
||||
délai croissant. Dépôt : `git.duniter.org/Yvv/libredecision-textes`, un dossier par groupe et
|
||||
par document. Le français fait foi ; les traductions sont marquées éditoriales.
|
||||
|
||||
**Coût.** La publication est asynchrone (quelques secondes, plus en cas de panne) ; l'état
|
||||
de la file se lit dans trustinWallet.
|
||||
@@ -0,0 +1,20 @@
|
||||
# 0006 — Accès : connect.monnaie-libre.fr, invitations, trustinWallet
|
||||
|
||||
**Contexte.** « Le même accès que pour le forum Monnaie libre », « toute personne avec une clé
|
||||
Duniter peut se loger et tout faire — sauf la gestion des accès », qui revient à trustinWallet
|
||||
(nouveau nom de trustWallet, déjà pris).
|
||||
|
||||
**Décision.**
|
||||
- Connexion Ğ1 : libreDecision est client OAuth2 de connect.monnaie-libre.fr (comme le forum).
|
||||
Le compte est la clé d'identité (`idty:N`) ; on garde le nom affiché et le statut de membre.
|
||||
- En attendant l'inscription du client : liens d'invitation à usage unique (14 jours), le
|
||||
secret dans le fragment de l'URL (jamais dans les journaux du serveur).
|
||||
- Sessions : cookie HttpOnly, SameSite=Lax, Secure en https, 30 jours, jeton haché en base ;
|
||||
en-tête anti-CSRF sur toute écriture.
|
||||
- Les règles (qui voit, qui ouvre, qui administre) vivent dans `trustin-access`, futur cœur du
|
||||
service trustinWallet ; le serveur ne décide jamais seul.
|
||||
- Premier administrateur : un lien d'invitation écrit au premier démarrage dans le volume de
|
||||
données (0600), jamais dans les journaux.
|
||||
|
||||
**Coût.** Tant que connect n'est pas branché, chaque testeuse a besoin d'un lien. Quand
|
||||
trustinWallet deviendra un service, `trustin-access` deviendra son client.
|
||||
@@ -0,0 +1,13 @@
|
||||
# Décisions d'architecture
|
||||
|
||||
Une décision durable par fichier : le contexte, la décision, ce qu'elle coûte. On n'efface
|
||||
pas une décision : on en écrit une nouvelle qui la remplace, et on le note dans l'ancienne.
|
||||
|
||||
| # | Décision | Date |
|
||||
|---|---|---|
|
||||
| [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 |
|
||||
| [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 |
|
||||
Reference in New Issue
Block a user