- Dans Monnaie libre (électorat = toile de confiance), seuls les membres de la toile votent (trustin_access::votes_in) ; une identité d'invitation y lit, propose et signale. L'interface le dit à la place des boutons (fr/en/es). - Un lien d'invitation ne vise jamais une identité Ğ1 ; le lien est réservé avant de créer l'identité (deux acceptations simultanées : une seule passe). - Un nombre n'est jamais une coquille (« 50 » → « 5,0 », « 1 5 » → « 15 »). - Redirection après connexion : caractères de contrôle refusés. - En-têtes : X-Frame-Options DENY, frame-ancestors 'none', nosniff, Referrer-Policy. - Déploiement : le produit passe en premier ; la maquette attend son succès. Les conteneurs, même arrêtés, qui revendiquent encore la racine sortent de « restart: always » (ils reviendraient au redémarrage de Docker). - Tests : 57 Rust (dont 14 scénarios d'API), e2e 12 / 12 avec C11. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6.2 KiB
6.2 KiB
libreDecision
Rendre possible la décision collective — en fonction du contexte, processus et modalités,
boîte à outils. v3 : Rust + Svelte, un chantier à la fois, chacun livré en production avant
le suivant (docs/chantiers/README.md).
Référence du chantier en cours : docs/chantiers/acte-certification/CHANTIER.md — toute
décision de comportement s'y adosse ; les décisions durables dans docs/adr/.
La maquette v2 (Nuxt + FastAPI) vit dans maquette/, intacte (Yvv la présente) — ne pas y
développer.
Protocole de début de session
git pull --rebase origin main(puis la branche du chantier :chantier/acte-certification)- Lire
HANDOFF.md(où on en est, ce qui attend Yvv) - Si l'objectif de la session n'est pas précisé, le demander
Stack
- Serveur : Rust edition 2024, toolchain 1.99 épinglée (
rust-toolchain.toml) ; rustup installé sans PATH →export PATH=$HOME/.cargo/bin:$PATH. axum 0.8, sqlx 0.8 (SQLite, requêtes runtime +migrate!), tokio, reqwest rustls. - Interface : SvelteKit 2 / Svelte 5 (runes), adapter-static SPA, vite 7, vitest, Playwright ; npm. Polices Literata (textes) + Nunito (interface), fontsource.
- Ports : dev interface 3002 (strict, proxy
/api→ 8002) · serveur 8002 · serveur jetable des e2e 8092. - Déploiement : une image (
docker/app.Dockerfile), Woodpeckerci.open.us.orgdépôt LPK/decision → sonic (fabio)..woodpecker/app.yml= le produit sur decision.librodrome.org ;.woodpecker/maquette.yml= la maquette sur maquette.decision.librodrome.org (le produit passe en premier et retire de la racine tout conteneur qui la revendique ; la maquette attend un déploiement réussi du produit). Push surprod(gitea@git.open.us.org:EHV/decision.git) branchemain= déploiement.
Structure
crates/
ld-engine/ # PUR (zéro I/O) : threshold (formule inertielle, presets), edit (coquille vs fond,
# diff), assist (découpage, similarité, longueur), compose (adoption, aperçus)
trustin-access/ # règles d'accès de trustinWallet : sees / opens / manages_access, groupes par défaut
ld-server/
migrations/ # schéma SQLite — additif seulement
src/ # lib.rs (routes, csrf, run) · config.rs (LD_*) · auth.rs (connect OAuth2, invitations,
# dev, bootstrap) · docs.rs (lecture, aperçus) · proposals.rs (écrire, voter, signaler,
# traduire) · adoption.rs (balayage, verrou) · publish.rs (file → git) · wot.rs (W
# sur la chaîne) · seed.rs · web.rs (sert web/build)
tests/api.rs # scénarios bout en bout
seeds/ # acte-engagement-certification.json (trilingue, 33 articles, I1/E1/E2 en vigueur)
web/src/
lib/i18n/ # fr.ts SOURCE (types Key) · en.ts · es.ts — parité testée
lib/components/ # Sidebar, DocPanel, VoteView, ProposeView, UnitBlock, DeepList, Seal, Stamp…
routes/ # / · connexion · invitation · groupes · g/[group] · g/[group]/docs/[doc] (lecteur,
# panneau dans l'URL ?onglet=&article=) · acces (trustinWallet) · decisions/mandats/
# protocoles (à venir)
web/e2e/ # Playwright C1–C11 + M1 ; serve.sh = serveur jetable /tmp/ld-e2e sur :8092
docker/ # app.Dockerfile · app-compose.yml (sonic)
.woodpecker/ # app.yml · maquette.yml
docs/ # chantiers/ · adr/ · dev/BLUEPRINT-V2.md (doctrine de la maquette) · recherche/
maquette/ # v2 intacte (frontend Nuxt, backend FastAPI, docker, docs-v1)
Données runtime — jamais écrasées
- Production : volume
lpk-libredecision-app_data(/data:libredecision.db,textes/= clone du dépôt publié,keys/= clé de publication,bootstrap-admin.txt). Jamaisdown -v, jamais recréé. - Maquette : volumes
lpk-decision-main_postgres-data/_ipfs-data(inchangés). - Local :
data/(gitignoré) — le supprimer repart du seed. Les e2e utilisent/tmp/ld-e2e. - Un document seedé n'est jamais réinstancié : dès qu'il existe en base, c'est de la donnée.
Commandes — la boucle (tout vert = fait)
export PATH=$HOME/.cargo/bin:$PATH
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 # e2e : 12 contrôles
LD_DEV_LOGIN=1 cargo run -p ld-server # :8002, sert web/build
cd web && npm run dev # :3002 à chaud
docker build -f docker/app.Dockerfile --target production . # rejoue toute la boucle
Conventions / pièges
- UI français, code anglais ; trilingue : aucune chaîne affichée en dur, tout passe par
web/src/lib/i18n/fr.tspuis en/es (test de parité +FORBIDDEN_UI_TERMS). Tutoyer ; le sujet est la personne ou le groupe, jamais le système. Le français du texte voté fait foi. - Moteur pur : une règle de vote / édition / composition s'écrit et se teste dans
ld-engineavant d'être câblée. Le serveur ne décide jamais l'accès seul :trustin-access. - Invariants : une seule voix ne fait jamais passer un texte (C = 50 pour Monnaie libre) ; une coquille ne demande pas de vote, un changement de fond si ; un signalement de contradiction bloque ; l'inertie se vote au cran au-dessus ; le groupe d'essai ne publie jamais.
- Écritures : en-tête
x-requested-with: libredecisionobligatoire (CSRF) ; cookield_session. Les tests d'API passent parClient(tests/api.rs). - Pièges vus :
pkill -f target/debug/ld-servertue son propre shell →pkill -x ld-server; unfrom_secretabsent fait refuser tout le pipeline Woodpecker ; la route hôte/*de fabio masque le webroot ACME → arrêter le service avantacme.sh --issue; Playwright en localefr-FR(sinon l'interface part en anglais). - Design : sans bordures, arrondis 16/12/20/14, ambiances
pierre/nuit(data-mood, posé avant le premier rendu), sceau hexagramme 井 #48 en SVG (Seal,Stamp— jamais le glyphe, qui s'affiche mal). Mouvement réduit respecté. - Domaine : decision.librodrome.org ; dépôt des textes
git.duniter.org/Yvv/libredecision-textes.