Files
decision/CLAUDE.md
T
YvvandClaude Opus 5.5 1f9c241b41 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>
2026-10-21 03:50:44 +02:00

6.2 KiB
Raw Blame History

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

  1. git pull --rebase origin main (puis la branche du chantier : chantier/acte-certification)
  2. Lire HANDOFF.md (où on en est, ce qui attend Yvv)
  3. 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), Woodpecker ci.open.us.org dé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 attend la maquette, qui libère la racine). Push sur prod (gitea@git.open.us.org:EHV/decision.git) branche main = 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–C10 + 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). Jamais down -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 : 11 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.ts puis 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-engine avant 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: libredecision obligatoire (CSRF) ; cookie ld_session. Les tests d'API passent par Client (tests/api.rs).
  • Pièges vus : pkill -f target/debug/ld-server tue son propre shell → pkill -x ld-server ; un from_secret absent fait refuser tout le pipeline Woodpecker ; la route hôte /* de fabio masque le webroot ACME → arrêter le service avant acme.sh --issue ; Playwright en locale fr-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.