- Mot mal tapé = un seul glissement (une lettre ajoutée, retirée, ou deux
voisines inversées), jamais au début du mot (préfixes : valide/invalide,
limitée/illimitée), jamais une lettre remplacée (deux/dix, majorité/minorité),
jamais sur un mot de négation ou de quantité, mots de 4 lettres au moins.
- Parenthèses, crochets, « / » et tout ce qui est entre accents graves comptent
comme le sens (ceil(N^(1/5)) → ceil(N^1/5) n'est plus une coquille).
- Caractères invisibles (inversion du sens d'écriture, largeur nulle, BOM)
refusés dans les textes, titres, traductions et motifs de signalement.
- Déploiement : la version en service est gardée (image « previous ») ; un
témoin marque le déploiement en cours ; « retablir » relance la maquette au
premier déploiement, la version précédente ensuite ; la liste des conteneurs
retirés n'est plus vidée par un pipeline annulé.
- Tests : 59 Rust (dont 14 scénarios d'API, avec deux → dix sur E2 en vigueur
et l'inversion bidi), e2e 12 / 12.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Correction de coquille : un chiffre, un signe, un séparateur dans un nombre ou
une relation changés (« >= » → « <= », « + » → « - », « 182.625 » → « 182 625 »,
« % » → « ‰ ») rendent la modification « de fond ». Testé dans le moteur et
par l'API sur le vrai texte K1.
- Déploiement : les conteneurs retirés de la racine qui tournaient sont notés ;
si la suite échoue, l'étape « retablir » arrête le produit et les relance.
Le produit est recréé à chaque déploiement (--force-recreate).
- Cookies préfixés en https : __Host-ld_session, __Secure-ld_oauth (pas de
cookie planté par un site voisin sous librodrome.org).
- syft épinglé (v1.55.0) dans les deux pipelines : ce conteneur a le socket Docker.
- Docs : limites connues assumées, groupe d'essai à deux voix, error.identity_kind.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 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>
- 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>
- Clé de publication ed25519 générée au démarrage dans le volume ; sa partie
publique et l'état de la file d'envoi s'affichent dans /acces.
- Publication initiale à l'instanciation d'un document seedé publiable.
- Reprise au démarrage : chaque document publié repasse une fois dans la file ;
la date publiée est celle du dernier changement, un document inchangé ne
fait pas de commit (testé contre un dépôt nu).
- Le travailleur fait un premier passage sans attendre ; journaux sans codes
couleur hors terminal.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Accueil sobre, menu complet à gauche (Décisions, Docs de référence, Mandats,
Protocoles), intro demandée, quatre sections, connexion Ğ1.
- Lecteur : texte en vigueur en Literata, actions contextuelles par article
(le vote, propositions, proposer), propositions en cours sous la « surface »
avec leur niveau d'eau, aperçus « si les bien cotées passent » / « si tout
passe », langue du texte fr/en/es (traductions éditoriales).
- Panneau : vote pour/contre, seuil et formule (MathML), inertie et son
changement (voté en inertie +), coquille sans vote, traduction, signalement
de contradiction, historique des corrections.
- trustinWallet (/acces) : groupes et membres, invitations à usage unique,
administrateurs, retours d'usage.
- Contrôles : vitest (markdown, catalogues, anti-lexique), Playwright C1–C10 + M1.
- Sections du seed portées jusqu'à l'écran.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- crates/ld-engine : formule inertielle (parité avec la maquette, garde C),
coquille / changement de fond, assistant d'édition à règles, composition
d'un document sous vote permanent (adoptions, aperçus, rivales).
- crates/trustin-access : qui voit, qui ouvre, qui gère les accès.
- crates/ld-server : API axum + SQLite, connexion Ğ1 (client OAuth2 de
connect.monnaie-libre.fr), invitations, entrée en vigueur automatique,
signalements de contradiction, traductions éditoriales, publication git,
taille de la toile lue sur la chaîne.
- seeds/acte-engagement-certification.json : 33 articles, fr + en + es ;
en vigueur : préambule, E1, E2 (seed a minima).
- maquette/ : frontend, backend et docker v2 déplacés tels quels.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- ACME : le challenge HTTP-01 échoue en IPv6 (AAAA présent, webroot non
servi en v6) ; quand un certificat est déjà en place (valide jusqu'au
30/09), on le conserve avec avertissement au lieu de bloquer le déploiement
— sans certificat existant, échec franc inchangé
- l'org forge renommée EHV→LPK a changé le COMPOSE_PROJECT_NAME : le
« compose stop » ne touchait plus l'ancienne stack ehv-decision-main-*
(double inscription fabio, trafic partagé v1/v2) → arrêt par filtre de nom
avant déploiement
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- le POST vers Dependency-Track meurt à la connexion (secret dtrack_domain
vide ou service éteint) et bloquait le déploiement au step sbom-publish
- failure: ignore — télémétrie ; le scan CVE trivy reste bloquant
- à réexaminer côté serveur : service DTrack + secrets dependency_track_token
/ dtrack_domain du repo Woodpecker
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- syft installé en « latest » émet une spec plus récente que ce que le
trivy 0.69.3 du runner décode → « invalid specification version »
au step sbom-scan (pipeline 26, tout le reste était vert)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- la dép git+ssh échouait en CI : pas de clé SSH dans les conteneurs, et
node:20-slim n'a pas le binaire git (ENOENT) — npm signalait un faux
« tarball corrupted »
- package.json + lock : git+https://git.open.us.org/… (#v0.1.0 → b1c6a2f,
même commit épinglé) — nécessite le repo yvv-nuxt-base public
- git + ca-certificates ajoutés : step test-frontend (.woodpecker.yml) et
image de base du frontend.Dockerfile
- vérifié : npm install + build zéro erreur
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- overlays Nuxt UI (UModal/USlideover) : géométrie posée en CSS
(assets/css/overlays.css) — les utilitaires tailwind attendus par @nuxt/ui
ne sont pas générés (UnoCSS ne scanne pas node_modules) : drawer mobile et
modales de confirmation se rendaient hors écran
- a11y : title/description sur les 3 overlays (DialogTitle/Description
rendus, warnings reka-ui éteints), fermeture du drawer ancrée et testée
- suppression du collectif actif : bascule sur un collectif restant —
jamais d'accueil orphelin (test store ajouté, 343 vitest verts)
- observatoire : la route « transmis » entre dans les barres (base 100 %)
- overflows mobiles à zéro : formules KaTeX (défilement), table vigueur
(défilement < 768px), pill cible (retour à la ligne), inputs decider et
mandat (border-box)
- vérifié navigateur : drawer, modale, 14 routes sans débordement,
zéro erreur console
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- les seeds (Ğ1, Atelier) n'ont aucun isMe : la carte identité propose
désormais de se désigner parmi les personnes existantes (chips) ou de
s'ajouter (formulaire), au lieu d'un état vide sans issue
- vitest 13 fichiers verts, build zéro erreur
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Ajout clause else IS NULL sur tous les endpoints list (protocols, decisions,
mandates, documents, groups, votes) — sans X-Organization → données globales
seulement, jamais le contenu d'un autre espace
- _get_protocol/_get_decision/_get_mandate : org_id propagé à tous les
endpoints GET/PUT/DELETE/advance/assign/revoke/steps → 404 si UUID d'un
autre espace
- votes.py : list_vote_sessions filtre via JOIN VotingProtocol.organization_id
- groups.py : suppression _org_id_from_header() mort, create_group assigne
organization_id correctement
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remplace par un bloc DO $$ IF NOT EXISTS ... $$ pour le FK circulaire
item_versions→document_items. Testé localement sur pg-test : 5 migrations
OK + idempotence OK.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 0b9c1d2e3f4a : migration initiale (CREATE TABLE IF NOT EXISTS) — safe
sur une DB déjà bootstrappée via create_all()
- 70914b334cfb : ADD COLUMN IF NOT EXISTS (organization_id) — was down_revision=None
- b78571ae9e00 : CREATE TABLE IF NOT EXISTS qualification_protocols
- c4e812fb3a01 : CREATE TABLE IF NOT EXISTS groups + group_members
- d91a3c7f8b02 : ADD COLUMN IF NOT EXISTS origin (mandates)
- Dockerfile prod : restaure alembic upgrade head au démarrage
Sur le serveur prod, exécuter une fois :
docker exec <projet>-backend alembic upgrade head
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Le lifespan FastAPI appelle déjà init_db() (create_all) au démarrage.
Lancer alembic en plus cassait sur une DB vide (migration initiale manquante).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Login : panneau proto-mode en avant quand DEMO_MODE actif (profils API)
masque le formulaire extension-required ; note trustWallet à venir
- auth.ts : TODO trustWallet avec protocole postMessage prévu
- routers/auth.py : TODO trustWallet au point de vérification signature
- test_middleware : fixture _create_tables (autouse) — ASGITransport ne
déclenche pas le lifespan, init_db() ne tournait pas → duniter_identities
introuvable au verify ; 224/224 passent
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- qualify_ai_service : ai_frame_async() avec Claude Haiku
· round 1 → questions contextualisées si ANTHROPIC_API_KEY définie
· round 2 → explication enrichie par Claude
· fallback transparent sur ai_frame() si pas de clé (tests inchangés)
- config : ANTHROPIC_API_KEY + ANTHROPIC_MODEL (claude-haiku-4-5-20251001)
- requirements : anthropic>=0.97.0
- main : auth rate limit = RATE_LIMIT_DEFAULT partout (prototype mode)
→ supporte accès démo/test sans lockout en prod comme en dev
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Middleware : CORSMiddleware ajouté en dernier = plus externe = tous les
codes de retour (dont 429) portent Access-Control-Allow-Origin
→ résout "no response / Failed to fetch" sur POST /auth/challenge
- Dev mode : rate_limit_auth = RATE_LIMIT_DEFAULT (60/min) au lieu de 10/min
→ plus de blocage login après quelques reconnexions
- app.vue : watcher activeSlug → refetch documents/décisions/protocoles/mandats
→ le sélecteur de workspace filtre désormais le contenu en temps réel
- TDD : 4 tests middleware (RED→GREEN) + doc méthode docs/dev/tdd-methode.md
- Régression : 190/190 tests verts
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Titres cards : "Décisions et consultation d'avis", "Documents de référence",
"Mandats et nominations", "Protocoles et fonctionnement"
- Burger supprimé sur desktop (≥768px), conservé mobile uniquement
- CI : step seed (docker exec python seed.py) entre test-deploy et healthcheck
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Le fichier séparé cassait Woodpecker 3.x (multi-file + when:manual
empêchait tous les triggers push depuis commit 1842303c).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>