Sprint 1 : scaffolding complet de Glibredecision

Plateforme de decisions collectives pour Duniter/G1.
Backend FastAPI async + PostgreSQL (14 tables, 8 routers, 6 services,
moteur de vote avec formule d'inertie WoT/Smith/TechComm).
Frontend Nuxt 4 + Nuxt UI v3 + Pinia (9 pages, 5 stores).
Infrastructure Docker + Woodpecker CI + Traefik.
Documentation technique et utilisateur (15 fichiers).
Seed : Licence G1, Engagement Forgeron v2.0.0, 4 protocoles de vote.
30 tests unitaires (formules, mode params, vote nuance) -- tous verts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Yvv
2026-02-28 12:46:11 +01:00
commit 25437f24e3
100 changed files with 10236 additions and 0 deletions

View File

@@ -0,0 +1,17 @@
---
title: Documentation technique
description: Architecture, API et reference technique de Glibredecision
---
# Documentation technique
Bienvenue dans la documentation technique de Glibredecision.
## Sections
- [Architecture](/dev/architecture) -- Vue d'ensemble de l'architecture
- [Reference API](/dev/api-reference) -- Endpoints et schemas
- [Schema de base de donnees](/dev/database-schema) -- Tables et relations
- [Formules](/dev/formulas) -- Formules mathematiques de seuil
- [Integration blockchain](/dev/blockchain-integration) -- Duniter V2, IPFS, on-chain
- [Contribution](/dev/contributing) -- Guide de contribution

View File

@@ -0,0 +1,81 @@
---
title: Architecture
description: Vue d'ensemble de l'architecture technique de Glibredecision
---
# Architecture
## Vue d'ensemble
Glibredecision est organise en monorepo avec trois composants principaux :
```
Glibredecision/
backend/ # API Python FastAPI (port 8002)
frontend/ # Application Nuxt 4 (port 3002)
docker/ # Fichiers Docker et orchestration
docs/ # Documentation (Nuxt Content)
```
## Stack technique
| Couche | Technologie |
| ------------ | -------------------------------------------------- |
| Frontend | Nuxt 4 + Nuxt UI v3 + Pinia + UnoCSS |
| Backend | Python FastAPI + SQLAlchemy 2.0 (async) + Pydantic v2 |
| Base de donnees | PostgreSQL 16 (asyncpg) |
| Authentification | Duniter V2 Ed25519 challenge-response |
| Sanctuaire | IPFS (kubo) + hash on-chain (system.remark) |
| CI/CD | Woodpecker CI + Docker + Traefik |
## Domaines fonctionnels
L'application est decoupee en 5 domaines metier, chacun avec ses modeles, schemas, routes et services :
1. **Documents** -- Documents de reference modulaires (licence, engagements, reglement) composes d'items individuels versionnables.
2. **Decisions** -- Processus decisionnels multi-etapes (qualification, examen, vote, execution, rapport).
3. **Votes** -- Sessions de vote binaire ou nuance avec formule de seuil WoT, critere Smith et critere TechComm.
4. **Mandats** -- Mandats assignes a des membres (techcomm, forgeron, personnalise) avec cycle de vie complet.
5. **Protocoles** -- Configurations de formules de vote et protocoles de vote reutilisables.
Un domaine transversal, le **Sanctuaire**, assure l'archivage immuable via IPFS et ancrage on-chain.
## Principes d'architecture
- **Async everywhere** : toute la couche donnees et HTTP est asynchrone (asyncpg, AsyncSession, FastAPI async).
- **Separation modeles / schemas / routes / services** : chaque domaine suit ce decoupage strict.
- **API versionnee** : tous les endpoints sont sous `/api/v1/`.
- **Preuve cryptographique** : chaque vote est signe avec la cle Ed25519 du votant.
- **Vote permanent** : les documents de reference sont sous vote permanent, chaque item peut etre modifie par proposition et vote.
## Schema de communication
```
Navigateur
|
v
[Nuxt 4 Frontend] -- SSR/CSR, port 3000 (prod) / 3002 (dev)
|
v (fetch /api/v1/*)
[FastAPI Backend] -- port 8002
|
+---> [PostgreSQL 16] -- Donnees relationnelles
+---> [IPFS kubo] -- Stockage distribue (Sanctuaire)
+---> [Duniter V2 RPC] -- WoT, Smith, TechComm, system.remark
```
## Flux d'authentification
1. Le client envoie son adresse Duniter SS58 via `POST /api/v1/auth/challenge`.
2. Le serveur genere un challenge aleatoire (64 hex) et le stocke en memoire (TTL 5 min).
3. Le client signe le challenge avec sa cle privee Ed25519 et soumet via `POST /api/v1/auth/verify`.
4. Le serveur verifie la signature, cree ou retrouve l'identite `DuniterIdentity`, et retourne un token de session.
5. Le token est utilise en header `Authorization: Bearer <token>` pour les requetes authentifiees.
## Flux de vote
1. Un protocole de vote et sa formule sont crees ou selectionnes.
2. Une session de vote est creee avec un snapshot des tailles WoT/Smith/TechComm.
3. Les membres votent (binaire ou nuance) avec signature cryptographique.
4. A la cloture, le seuil WoT est calcule, les criteres Smith et TechComm sont verifies.
5. Le resultat (adopte/rejete) est archive dans le Sanctuaire (IPFS + on-chain).

View File

@@ -0,0 +1,106 @@
---
title: Reference API
description: Liste des endpoints de l'API Glibredecision
---
# Reference API
Tous les endpoints sont prefixes par `/api/v1`. L'API est auto-documentee via OpenAPI/Swagger a l'adresse `/docs` en mode debug.
## Authentification (`/api/v1/auth`)
| Methode | Endpoint | Description | Auth |
| ------- | ------------- | ----------------------------------------------------- | ---- |
| POST | `/challenge` | Generer un challenge Ed25519 pour une adresse Duniter | Non |
| POST | `/verify` | Verifier la signature du challenge et obtenir un token | Non |
| GET | `/me` | Retourner l'identite authentifiee courante | Oui |
| POST | `/logout` | Invalider la session courante | Oui |
## Documents (`/api/v1/documents`)
| Methode | Endpoint | Description | Auth |
| ------- | -------------------------------------- | ---------------------------------------- | ---- |
| GET | `/` | Lister les documents (filtres: doc_type, status) | Non |
| POST | `/` | Creer un nouveau document | Oui |
| GET | `/{slug}` | Obtenir un document par son slug | Non |
| PUT | `/{slug}` | Mettre a jour un document | Oui |
| POST | `/{slug}/items` | Ajouter un item au document | Oui |
| GET | `/{slug}/items` | Lister les items d'un document | Non |
| GET | `/{slug}/items/{item_id}` | Obtenir un item avec son historique | Non |
| POST | `/{slug}/items/{item_id}/versions` | Proposer une nouvelle version d'un item | Oui |
## Decisions (`/api/v1/decisions`)
| Methode | Endpoint | Description | Auth |
| ------- | ---------------- | ------------------------------------------------ | ---- |
| GET | `/` | Lister les decisions (filtres: decision_type, status) | Non |
| POST | `/` | Creer une nouvelle decision | Oui |
| GET | `/{id}` | Obtenir une decision avec ses etapes | Non |
| PUT | `/{id}` | Mettre a jour une decision | Oui |
| POST | `/{id}/steps` | Ajouter une etape a une decision | Oui |
## Votes (`/api/v1/votes`)
| Methode | Endpoint | Description | Auth |
| ------- | --------------------------- | -------------------------------------------- | ---- |
| POST | `/sessions` | Creer une session de vote | Oui |
| GET | `/sessions/{id}` | Obtenir une session de vote | Non |
| POST | `/sessions/{id}/vote` | Soumettre un vote (signe) | Oui |
| GET | `/sessions/{id}/votes` | Lister les votes d'une session | Non |
| GET | `/sessions/{id}/result` | Calculer et retourner le resultat courant | Non |
## Mandats (`/api/v1/mandates`)
| Methode | Endpoint | Description | Auth |
| ------- | ----------------- | ---------------------------------------------- | ---- |
| GET | `/` | Lister les mandats (filtres: mandate_type, status) | Non |
| POST | `/` | Creer un nouveau mandat | Oui |
| GET | `/{id}` | Obtenir un mandat avec ses etapes | Non |
| PUT | `/{id}` | Mettre a jour un mandat | Oui |
| DELETE | `/{id}` | Supprimer un mandat (brouillon uniquement) | Oui |
| POST | `/{id}/steps` | Ajouter une etape a un mandat | Oui |
| GET | `/{id}/steps` | Lister les etapes d'un mandat | Non |
## Protocoles (`/api/v1/protocols`)
| Methode | Endpoint | Description | Auth |
| ------- | --------------- | -------------------------------------------------- | ---- |
| GET | `/` | Lister les protocoles de vote | Non |
| POST | `/` | Creer un protocole de vote | Oui |
| GET | `/{id}` | Obtenir un protocole avec sa configuration formule | Non |
| GET | `/formulas` | Lister les configurations de formules | Non |
| POST | `/formulas` | Creer une configuration de formule | Oui |
## Sanctuaire (`/api/v1/sanctuary`)
| Methode | Endpoint | Description | Auth |
| ------- | --------- | ---------------------------------------------------------- | ---- |
| GET | `/` | Lister les entrees du sanctuaire (filtre: entry_type) | Non |
| GET | `/{id}` | Obtenir une entree du sanctuaire | Non |
| POST | `/` | Creer une entree (hash SHA-256, CID IPFS, TX on-chain) | Oui |
## WebSocket (`/api/v1/ws`)
| Endpoint | Description |
| --------- | -------------------------------------------------------- |
| `/ws` | Connexion WebSocket pour notifications temps reel (votes, decisions) |
## Sante
| Methode | Endpoint | Description |
| ------- | -------------- | -------------------------- |
| GET | `/api/health` | Verification de sante (hors versionning) |
## Pagination
Les endpoints de liste acceptent les parametres `skip` (offset, defaut 0) et `limit` (max 200, defaut 50).
## Authentification
Les endpoints marques "Oui" dans la colonne Auth requierent un header :
```
Authorization: Bearer <token>
```
Le token est obtenu via le flux challenge-response (`/auth/challenge` puis `/auth/verify`).

View File

@@ -0,0 +1,312 @@
---
title: Schema de base de donnees
description: Tables et relations de la base de donnees PostgreSQL
---
# Schema de base de donnees
Glibredecision utilise PostgreSQL 16 avec SQLAlchemy 2.0 en mode asynchrone (asyncpg). Toutes les cles primaires sont des UUID v4.
## Tables
### `duniter_identities`
Identites Duniter V2 connues de la plateforme.
| Colonne | Type | Description |
| -------------- | ------------ | ---------------------------------------------- |
| id | UUID (PK) | Identifiant unique |
| address | VARCHAR(64) | Adresse SS58 Duniter (unique, indexee) |
| display_name | VARCHAR(128) | Nom d'affichage |
| wot_status | VARCHAR(32) | Statut WoT : member, pending, revoked, unknown |
| is_smith | BOOLEAN | Membre Smith (forgeron) |
| is_techcomm | BOOLEAN | Membre du Comite Technique |
| created_at | TIMESTAMPTZ | Date de creation |
| updated_at | TIMESTAMPTZ | Date de derniere mise a jour |
### `sessions`
Sessions d'authentification (tokens).
| Colonne | Type | Description |
| ------------ | ------------ | ---------------------------------- |
| id | UUID (PK) | Identifiant unique |
| token_hash | VARCHAR(128) | Hash du token (unique, indexe) |
| identity_id | UUID (FK) | -> duniter_identities.id |
| created_at | TIMESTAMPTZ | Date de creation |
| expires_at | TIMESTAMPTZ | Date d'expiration |
### `documents`
Documents de reference modulaires.
| Colonne | Type | Description |
| ------------ | ------------ | ----------------------------------------------------- |
| id | UUID (PK) | Identifiant unique |
| slug | VARCHAR(128) | Identifiant lisible (unique, indexe) |
| title | VARCHAR(256) | Titre du document |
| doc_type | VARCHAR(64) | Type : licence, engagement, reglement, constitution |
| version | VARCHAR(32) | Version semantique (defaut "0.1.0") |
| status | VARCHAR(32) | Statut : draft, active, archived |
| description | TEXT | Description du document |
| ipfs_cid | VARCHAR(128) | CID IPFS de la derniere version archivee |
| chain_anchor | VARCHAR(128) | Hash de transaction on-chain |
| created_at | TIMESTAMPTZ | Date de creation |
| updated_at | TIMESTAMPTZ | Date de derniere mise a jour |
### `document_items`
Items individuels composant un document (clauses, regles, verifications, etc.).
| Colonne | Type | Description |
| ------------------- | ------------ | ------------------------------------------------- |
| id | UUID (PK) | Identifiant unique |
| document_id | UUID (FK) | -> documents.id |
| position | VARCHAR(16) | Numero de position ("1", "1.1", "3.2") |
| item_type | VARCHAR(32) | Type : clause, rule, verification, preamble, section |
| title | VARCHAR(256) | Titre de l'item |
| current_text | TEXT | Texte courant de l'item |
| voting_protocol_id | UUID (FK) | -> voting_protocols.id (protocole specifique) |
| sort_order | INTEGER | Ordre de tri |
| created_at | TIMESTAMPTZ | Date de creation |
| updated_at | TIMESTAMPTZ | Date de derniere mise a jour |
### `item_versions`
Historique des versions proposees pour chaque item.
| Colonne | Type | Description |
| -------------- | ------------ | ------------------------------------------------------ |
| id | UUID (PK) | Identifiant unique |
| item_id | UUID (FK) | -> document_items.id |
| proposed_text | TEXT | Texte propose |
| diff_text | TEXT | Diff unifie entre texte courant et propose |
| rationale | TEXT | Justification de la modification |
| status | VARCHAR(32) | Statut : proposed, voting, accepted, rejected |
| decision_id | UUID (FK) | -> decisions.id (decision associee) |
| proposed_by_id | UUID (FK) | -> duniter_identities.id (auteur de la proposition) |
| created_at | TIMESTAMPTZ | Date de creation |
### `decisions`
Processus decisionnels multi-etapes.
| Colonne | Type | Description |
| ------------------- | ------------ | -------------------------------------------------------- |
| id | UUID (PK) | Identifiant unique |
| title | VARCHAR(256) | Titre de la decision |
| description | TEXT | Description |
| context | TEXT | Contexte additionnel |
| decision_type | VARCHAR(64) | Type : runtime_upgrade, document_change, mandate_vote, custom |
| status | VARCHAR(32) | Statut : draft, qualification, review, voting, executed, closed |
| voting_protocol_id | UUID (FK) | -> voting_protocols.id |
| created_by_id | UUID (FK) | -> duniter_identities.id |
| created_at | TIMESTAMPTZ | Date de creation |
| updated_at | TIMESTAMPTZ | Date de derniere mise a jour |
### `decision_steps`
Etapes d'un processus decisionnel.
| Colonne | Type | Description |
| ---------------- | ------------ | -------------------------------------------------------- |
| id | UUID (PK) | Identifiant unique |
| decision_id | UUID (FK) | -> decisions.id |
| step_order | INTEGER | Ordre de l'etape |
| step_type | VARCHAR(32) | Type : qualification, review, vote, execution, reporting |
| title | VARCHAR(256) | Titre de l'etape |
| description | TEXT | Description |
| status | VARCHAR(32) | Statut : pending, active, completed, skipped |
| vote_session_id | UUID (FK) | -> vote_sessions.id (session de vote associee) |
| outcome | TEXT | Resultat de l'etape |
| created_at | TIMESTAMPTZ | Date de creation |
### `vote_sessions`
Sessions de vote avec snapshot des tailles WoT et decompte en temps reel.
| Colonne | Type | Description |
| ------------------- | ------------ | ---------------------------------------------- |
| id | UUID (PK) | Identifiant unique |
| decision_id | UUID (FK) | -> decisions.id |
| item_version_id | UUID (FK) | -> item_versions.id |
| voting_protocol_id | UUID (FK) | -> voting_protocols.id |
| wot_size | INTEGER | Taille WoT au debut de la session |
| smith_size | INTEGER | Taille Smith au debut de la session |
| techcomm_size | INTEGER | Taille TechComm au debut de la session |
| starts_at | TIMESTAMPTZ | Date de debut |
| ends_at | TIMESTAMPTZ | Date de fin |
| status | VARCHAR(32) | Statut : open, closed, tallied |
| votes_for | INTEGER | Nombre de votes pour |
| votes_against | INTEGER | Nombre de votes contre |
| votes_total | INTEGER | Nombre total de votes |
| smith_votes_for | INTEGER | Votes pour des membres Smith |
| techcomm_votes_for | INTEGER | Votes pour des membres TechComm |
| threshold_required | FLOAT | Seuil calcule requis |
| result | VARCHAR(32) | Resultat : adopted, rejected, null |
| chain_recorded | BOOLEAN | Enregistre sur la blockchain |
| chain_tx_hash | VARCHAR(128) | Hash de la transaction on-chain |
| created_at | TIMESTAMPTZ | Date de creation |
### `votes`
Votes individuels avec preuve cryptographique.
| Colonne | Type | Description |
| ---------------- | ------------ | -------------------------------------------- |
| id | UUID (PK) | Identifiant unique |
| session_id | UUID (FK) | -> vote_sessions.id |
| voter_id | UUID (FK) | -> duniter_identities.id |
| vote_value | VARCHAR(32) | Valeur : for, against, ou niveau nuance |
| nuanced_level | INTEGER | Niveau nuance (0-5) pour les votes nuances |
| comment | TEXT | Commentaire optionnel |
| signature | TEXT | Signature Ed25519 du payload |
| signed_payload | TEXT | Payload signe (pour verification) |
| voter_wot_status | VARCHAR(32) | Statut WoT du votant au moment du vote |
| voter_is_smith | BOOLEAN | Le votant est-il forgeron |
| voter_is_techcomm| BOOLEAN | Le votant est-il membre TechComm |
| is_active | BOOLEAN | Vote actif (false si remplace) |
| created_at | TIMESTAMPTZ | Date de creation |
### `mandates`
Mandats assignes a des membres.
| Colonne | Type | Description |
| ------------- | ------------ | ------------------------------------------------------- |
| id | UUID (PK) | Identifiant unique |
| title | VARCHAR(256) | Titre du mandat |
| description | TEXT | Description |
| mandate_type | VARCHAR(64) | Type : techcomm, smith, custom |
| status | VARCHAR(32) | Statut : draft, candidacy, voting, active, reporting, completed, revoked |
| mandatee_id | UUID (FK) | -> duniter_identities.id (titulaire du mandat) |
| decision_id | UUID (FK) | -> decisions.id (decision associee) |
| starts_at | TIMESTAMPTZ | Date de debut |
| ends_at | TIMESTAMPTZ | Date de fin |
| created_at | TIMESTAMPTZ | Date de creation |
| updated_at | TIMESTAMPTZ | Date de derniere mise a jour |
### `mandate_steps`
Etapes du cycle de vie d'un mandat.
| Colonne | Type | Description |
| ---------------- | ------------ | ------------------------------------------------------------- |
| id | UUID (PK) | Identifiant unique |
| mandate_id | UUID (FK) | -> mandates.id |
| step_order | INTEGER | Ordre de l'etape |
| step_type | VARCHAR(32) | Type : formulation, candidacy, vote, assignment, reporting, completion, revocation |
| title | VARCHAR(256) | Titre de l'etape |
| description | TEXT | Description |
| status | VARCHAR(32) | Statut : pending, active, completed, skipped |
| vote_session_id | UUID (FK) | -> vote_sessions.id (session de vote associee) |
| outcome | TEXT | Resultat de l'etape |
| created_at | TIMESTAMPTZ | Date de creation |
### `voting_protocols`
Protocoles de vote reutilisables.
| Colonne | Type | Description |
| ------------------ | ------------ | ----------------------------------------------- |
| id | UUID (PK) | Identifiant unique |
| name | VARCHAR(128) | Nom du protocole |
| description | TEXT | Description |
| vote_type | VARCHAR(32) | Type de vote : binary, nuanced |
| formula_config_id | UUID (FK) | -> formula_configs.id |
| mode_params | VARCHAR(64) | Parametres compacts ("D30M50B.1G.2T.1") |
| is_meta_governed | BOOLEAN | Le protocole est-il sous meta-gouvernance |
| created_at | TIMESTAMPTZ | Date de creation |
### `formula_configs`
Configurations de formules de seuil WoT.
| Colonne | Type | Description |
| ------------------------- | ------------ | ----------------------------------------- |
| id | UUID (PK) | Identifiant unique |
| name | VARCHAR(128) | Nom de la configuration |
| description | TEXT | Description |
| duration_days | INTEGER | Duree du vote en jours |
| majority_pct | INTEGER | Pourcentage de majorite (0-100) |
| base_exponent | FLOAT | Exposant de base B |
| gradient_exponent | FLOAT | Exposant de gradient G |
| constant_base | FLOAT | Base constante C |
| smith_exponent | FLOAT | Exposant Smith S (null si non requis) |
| techcomm_exponent | FLOAT | Exposant TechComm T (null si non requis) |
| nuanced_min_participants | INTEGER | Participants minimum (vote nuance) |
| nuanced_threshold_pct | INTEGER | Seuil positif % (vote nuance) |
| created_at | TIMESTAMPTZ | Date de creation |
### `sanctuary_entries`
Entrees du sanctuaire (archivage immuable).
| Colonne | Type | Description |
| -------------- | ------------ | ------------------------------------------ |
| id | UUID (PK) | Identifiant unique |
| entry_type | VARCHAR(64) | Type : document, decision, vote_result |
| reference_id | UUID | UUID de l'entite source |
| title | VARCHAR(256) | Titre |
| content_hash | VARCHAR(128) | Hash SHA-256 du contenu |
| ipfs_cid | VARCHAR(128) | CID IPFS |
| chain_tx_hash | VARCHAR(128) | Hash de la transaction on-chain |
| chain_block | INTEGER | Numero de bloc de la transaction |
| metadata_json | TEXT | Metadonnees JSON supplementaires |
| created_at | TIMESTAMPTZ | Date de creation |
### `blockchain_cache`
Cache des donnees blockchain pour eviter les appels RPC repetes.
| Colonne | Type | Description |
| ------------ | ------------ | -------------------------------- |
| id | UUID (PK) | Identifiant unique |
| cache_key | VARCHAR(256) | Cle de cache (unique, indexee) |
| cache_value | JSONB | Valeur en cache |
| fetched_at | TIMESTAMPTZ | Date de recuperation |
| expires_at | TIMESTAMPTZ | Date d'expiration du cache |
## Diagramme des relations
```
duniter_identities
|-- 1:N --> sessions
|-- 1:N --> votes (voter_id)
|-- 1:N --> item_versions (proposed_by_id)
|-- 1:N --> decisions (created_by_id)
|-- 1:N --> mandates (mandatee_id)
documents
|-- 1:N --> document_items
document_items
|-- 1:N --> item_versions
|-- N:1 --> voting_protocols
item_versions
|-- N:1 --> decisions
decisions
|-- 1:N --> decision_steps
decision_steps
|-- N:1 --> vote_sessions
vote_sessions
|-- 1:N --> votes
|-- N:1 --> voting_protocols
mandates
|-- 1:N --> mandate_steps
|-- N:1 --> decisions
mandate_steps
|-- N:1 --> vote_sessions
voting_protocols
|-- N:1 --> formula_configs
formula_configs
|-- 1:N --> voting_protocols
```

View File

@@ -0,0 +1,137 @@
---
title: Formules
description: Formules mathematiques de seuil WoT, criteres Smith et TechComm
---
# Formules de seuil
Glibredecision utilise un systeme de formules mathematiques pour determiner les seuils d'adoption des votes. Le mecanisme central est la **formule d'inertie WoT** qui impose une quasi-unanimite en cas de faible participation et converge vers une majorite simple a participation elevee.
## Formule principale -- Seuil WoT
$$
\text{Result} = C + B^W + \left( M + (1 - M) \cdot \left(1 - \left(\frac{T}{W}\right)^G \right) \right) \cdot \max(0,\; T - C)
$$
### Variables
| Symbole | Parametre | Description | Defaut |
| ------- | ------------------- | ------------------------------------------------ | ------ |
| $C$ | `constant_base` | Base constante additive (plancher) | 0.0 |
| $B$ | `base_exponent` | Exposant de base. $B^W$ devient negligeable quand $W$ est grand ($0 < B < 1$) | 0.1 |
| $W$ | `wot_size` | Taille du corpus des votants eligibles (membres WoT) | -- |
| $T$ | `total_votes` | Nombre total de votes exprimes (pour + contre) | -- |
| $M$ | `majority_pct / 100`| Ratio de majorite. 0.5 = majorite simple a pleine participation | 50 |
| $G$ | `gradient_exponent` | Controle la vitesse de convergence de la super-majorite vers $M$ | 0.2 |
### Mecanisme d'inertie
Le coeur de la formule est le facteur d'inertie :
$$
\text{inertia} = M + (1 - M) \cdot \left(1 - \left(\frac{T}{W}\right)^G \right)
$$
- Quand la **participation est faible** ($T \ll W$) : le ratio $T/W$ est petit, $(T/W)^G$ est proche de 0, donc l'inertie tend vers $M + (1-M) = 1$. Il faut quasiment l'unanimite.
- Quand la **participation est elevee** ($T \to W$) : le ratio $T/W$ tend vers 1, $(T/W)^G$ tend vers 1, donc l'inertie tend vers $M$. La majorite simple suffit.
### Exemple de reference
Avec les parametres `M50 B.1 G.2` et le vote de l'Engagement Forgeron v2.0.0 :
- $W = 7224$ (membres WoT)
- $T = 120$ (97 pour + 23 contre)
- Seuil calcule : $94$
- Resultat : **adopte** (97 >= 94)
## Critere Smith (Forgerons)
$$
\text{SmithThreshold} = \lceil \text{SmithWotSize}^S \rceil
$$
Le critere Smith exige un nombre minimum de votes favorables de la part des membres Smith (forgerons) pour que certaines decisions soient valides.
| Symbole | Parametre | Description | Defaut |
| ------- | ---------------- | ---------------------------- | ------ |
| $S$ | `smith_exponent` | Exposant pour le critere Smith | null (desactive) |
Avec un exposant de $S = 0.1$ et 20 forgerons :
$$
\lceil 20^{0.1} \rceil = \lceil 1.35 \rceil = 2
$$
Au minimum 2 votes favorables de forgerons sont requis.
## Critere TechComm (Comite Technique)
$$
\text{TechCommThreshold} = \lceil \text{CoTecSize}^T \rceil
$$
Le critere TechComm fonctionne de maniere identique au critere Smith mais pour les membres du Comite Technique.
| Symbole | Parametre | Description | Defaut |
| ------- | ------------------- | ------------------------------- | ------ |
| $T$ | `techcomm_exponent` | Exposant pour le critere TechComm | null (desactive) |
Avec un exposant de $T = 0.1$ et 5 membres TechComm :
$$
\lceil 5^{0.1} \rceil = \lceil 1.17 \rceil = 2
$$
Au minimum 2 votes favorables de membres TechComm sont requis.
## Resultat final
Un vote est **adopte** si et seulement si les trois conditions sont remplies simultanement :
1. `votes_for >= seuil_WoT` (formule principale)
2. `smith_votes_for >= seuil_Smith` (si critere Smith actif)
3. `techcomm_votes_for >= seuil_TechComm` (si critere TechComm actif)
## Parametres de mode (mode_params)
Les parametres de formule sont encodes dans une chaine compacte pour faciliter la lecture et le partage. Format : une lettre majuscule suivie d'une valeur numerique.
| Code | Parametre | Type | Exemple |
| ---- | --------------------- | ----- | ------------ |
| D | `duration_days` | int | D30 = 30 jours |
| M | `majority_pct` | int | M50 = 50% |
| B | `base_exponent` | float | B.1 = 0.1 |
| G | `gradient_exponent` | float | G.2 = 0.2 |
| C | `constant_base` | float | C0 = 0.0 |
| S | `smith_exponent` | float | S.1 = 0.1 |
| T | `techcomm_exponent` | float | T.1 = 0.1 |
| N | `ratio_multiplier` | float | N1.5 = 1.5 |
| R | `is_ratio_mode` | bool | R1 = true |
### Exemples
- `"D30M50B.1G.2"` -- 30 jours, majorite 50%, base 0.1, gradient 0.2
- `"D30M50B.1G.2S.1T.1"` -- Idem avec critere Smith (0.1) et TechComm (0.1)
- `"D60M66B.05G.3"` -- 60 jours, majorite 66%, base 0.05, gradient 0.3
## Vote nuance
En plus du vote binaire (pour/contre), Glibredecision supporte un vote nuance a 6 niveaux :
| Niveau | Label |
| ------ | ------------- |
| 0 | CONTRE |
| 1 | PAS DU TOUT |
| 2 | PAS D'ACCORD |
| 3 | NEUTRE |
| 4 | D'ACCORD |
| 5 | TOUT A FAIT |
### Regle d'adoption (vote nuance)
Un vote nuance est adopte si :
1. Le nombre de votes aux niveaux 3, 4 et 5 (positifs) represente au moins `threshold_pct`% du total des votes.
2. Le nombre minimum de participants (`min_participants`) est atteint.
Par defaut : `threshold_pct = 80%`, `min_participants = 59`.

View File

@@ -0,0 +1,165 @@
---
title: Integration blockchain
description: Integration Duniter V2, IPFS et ancrage on-chain
---
# Integration blockchain
Glibredecision s'integre a la blockchain Duniter V2 pour trois fonctions essentielles :
1. **Authentification** -- Verification de l'identite des membres via signature Ed25519
2. **Donnees WoT** -- Recuperation des tailles WoT, Smith et TechComm pour le calcul des seuils
3. **Ancrage on-chain** -- Archivage immuable des resultats via `system.remark`
## Duniter V2 RPC
La communication avec le noeud Duniter V2 utilise la bibliotheque `substrate-interface` via WebSocket RPC.
### Configuration
```
DUNITER_RPC_URL=wss://gdev.p2p.legal/ws
```
### Requetes principales
#### Taille de la WoT (membres)
```python
from substrateinterface import SubstrateInterface
substrate = SubstrateInterface(url="wss://gdev.p2p.legal/ws")
result = substrate.query(
module="Membership",
storage_function="MembershipCount",
)
wot_size = int(result.value)
```
#### Taille Smith (forgerons)
```python
result = substrate.query(
module="SmithMembers",
storage_function="SmithMembershipCount",
)
smith_size = int(result.value)
```
#### Taille TechComm
```python
result = substrate.query(
module="TechnicalCommittee",
storage_function="Members",
)
techcomm_size = len(result.value) if result.value else 0
```
### Cache blockchain
Pour eviter des appels RPC repetes, les donnees blockchain sont mises en cache dans la table `blockchain_cache` avec une duree d'expiration configurable. La cle de cache est une chaine descriptive (ex: `"wot_size"`, `"smith_size"`), la valeur est stockee en JSONB.
## IPFS (kubo)
Le composant IPFS est un noeud kubo qui sert de stockage distribue pour le Sanctuaire. Chaque document adopte, resultat de vote ou decision finalisee est uploade sur IPFS.
### Configuration
```
IPFS_API_URL=http://localhost:5001
IPFS_GATEWAY_URL=http://localhost:8080
```
### Upload de contenu
```python
import httpx
async with httpx.AsyncClient() as client:
response = await client.post(
f"{IPFS_API_URL}/api/v0/add",
files={"file": ("content.txt", content.encode("utf-8"))},
)
response.raise_for_status()
ipfs_cid = response.json()["Hash"]
```
### Acces au contenu
Le contenu est accessible via la passerelle IPFS :
```
GET http://localhost:8080/ipfs/{cid}
```
## Ancrage on-chain (system.remark)
L'ancrage on-chain consiste a soumettre un extrinsic `system.remark` contenant le hash SHA-256 du contenu archive. Cela cree une preuve immuable et horodatee sur la blockchain Duniter V2.
### Format du remark
```
glibredecision:sanctuary:{content_hash_sha256}
```
### Soumission
```python
from substrateinterface import SubstrateInterface, Keypair
substrate = SubstrateInterface(url="wss://gdev.p2p.legal/ws")
call = substrate.compose_call(
call_module="System",
call_function="remark",
call_params={"remark": f"glibredecision:sanctuary:{content_hash}"},
)
extrinsic = substrate.create_signed_extrinsic(call=call, keypair=keypair)
receipt = substrate.submit_extrinsic(extrinsic, wait_for_inclusion=True)
tx_hash = receipt.extrinsic_hash
block_number = receipt.block_number
```
### Verification
Pour verifier qu'un contenu a ete ancre, il suffit de :
1. Recalculer le hash SHA-256 du contenu
2. Rechercher le remark correspondant dans la blockchain
3. Verifier que le hash correspond
## Flux complet du Sanctuaire
```
Contenu adopte
|
v
[SHA-256] --> content_hash
|
+---> [IPFS /api/v0/add] --> ipfs_cid
|
+---> [system.remark] --> tx_hash, block_number
|
v
[sanctuary_entries] -- Enregistrement en base avec content_hash, ipfs_cid, chain_tx_hash, chain_block
```
## Authentification Ed25519
Le flux d'authentification utilise un mecanisme challenge-response :
1. Le serveur genere un challenge aleatoire (64 caracteres hexadecimaux)
2. Le client signe le challenge avec sa cle privee Ed25519 (Duniter V2)
3. Le serveur verifie la signature a l'aide de la cle publique derivee de l'adresse SS58
```python
from substrateinterface import Keypair
keypair = Keypair(ss58_address=address)
is_valid = keypair.verify(challenge_bytes, signature_bytes)
```
Cette methode garantit que seul le proprietaire de l'adresse Duniter peut s'authentifier, sans jamais transmettre la cle privee.

View File

@@ -0,0 +1,145 @@
---
title: Contribution
description: Guide de contribution au projet Glibredecision
---
# Guide de contribution
Merci de votre interet pour contribuer a Glibredecision. Ce guide explique comment configurer l'environnement de developpement, les conventions a respecter et le processus de contribution.
## Prerequis
- Python 3.11+
- Node.js 20+
- PostgreSQL 16
- Docker et Docker Compose (optionnel mais recommande)
- Git
## Installation locale
### Methode 1 : Docker (recommandee)
```bash
# Cloner le depot
git clone https://git.duniter.org/tools/glibredecision.git
cd glibredecision
# Copier le fichier d'environnement
cp .env.example .env
# Demarrer tous les services
docker compose -f docker/docker-compose.yml -f docker/docker-compose.dev.yml up
```
Les services sont accessibles sur :
- Frontend : http://localhost:3002
- Backend : http://localhost:8002
- API docs : http://localhost:8002/docs
### Methode 2 : Installation manuelle
```bash
# Backend
cd backend
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
uvicorn app.main:app --port 8002 --reload
# Frontend (dans un autre terminal)
cd frontend
npm install
npm run dev
```
Assurez-vous qu'une instance PostgreSQL est disponible et que `DATABASE_URL` dans `.env` pointe vers celle-ci.
## Conventions
### Langues
- **Code** (variables, commentaires, docstrings) : anglais
- **Interface utilisateur** (labels, messages, documentation) : francais
### Structure du code
Le backend est organise par domaine :
```
backend/app/
models/ # Modeles SQLAlchemy (un fichier par domaine)
schemas/ # Schemas Pydantic v2 (un fichier par domaine)
routers/ # Routes FastAPI (un fichier par domaine)
services/ # Logique metier (un fichier par domaine)
engine/ # Moteur de calcul (formules, seuils)
tests/ # Tests unitaires
```
Le frontend suit les conventions Nuxt 4 :
```
frontend/app/
components/ # Composants Vue (un dossier par domaine)
composables/ # Composables reutilisables
pages/ # Pages (un dossier par domaine)
stores/ # Stores Pinia
utils/ # Utilitaires
```
### Style de code
- **Python** : PEP 8, type hints systematiques, docstrings au format NumPy
- **TypeScript/Vue** : ESLint + Prettier (via configuration Nuxt)
- **SQL** : noms de tables au pluriel, noms de colonnes en snake_case
### API
- Versionne sous `/api/v1/`
- Schemas Pydantic v2 pour la validation
- Async partout (SQLAlchemy AsyncSession, FastAPI async handlers)
- Codes HTTP standards (201 pour creation, 204 pour suppression, 404, 409, etc.)
## Tests
### Backend
```bash
cd backend
pytest app/tests/ -v
```
Les tests du moteur de calcul (`test_threshold.py`) verifient la formule de seuil WoT avec le cas de reference (Engagement Forgeron v2.0.0 : 97/23 avec WoT 7224).
### Frontend
```bash
cd frontend
npm run build # Verification que le build passe
```
## Processus de contribution
1. Creer une branche a partir de `main` : `git checkout -b feature/ma-fonctionnalite`
2. Developper et tester localement
3. S'assurer que les tests passent : `pytest` (backend) et `npm run build` (frontend)
4. Pousser la branche et creer une merge request
5. La pipeline CI (Woodpecker) validera automatiquement les tests
6. Revue de code par un mainteneur
7. Merge dans `main`
## Secrets Woodpecker CI
La pipeline CI utilise les secrets suivants (a configurer dans l'interface Woodpecker) :
| Secret | Description |
| ----------------- | ------------------------------------ |
| `docker_registry` | URL du registre Docker |
| `docker_username` | Nom d'utilisateur du registre |
| `docker_password` | Mot de passe du registre |
| `deploy_host` | Adresse du serveur de deploiement |
| `deploy_username` | Utilisateur SSH du serveur |
| `deploy_key` | Cle privee SSH pour le deploiement |
## Contact
Pour toute question, rendez-vous sur le forum Duniter ou ouvrez une issue sur le depot Git.

View File

@@ -0,0 +1,28 @@
---
title: Documentation utilisateur
description: Guide d'utilisation de la plateforme Glibredecision
---
# Documentation utilisateur
Bienvenue dans la documentation utilisateur de Glibredecision, la plateforme de decisions collectives pour la communaute Duniter/G1.
## Qu'est-ce que Glibredecision ?
Glibredecision est une plateforme de gouvernance decentralisee qui permet aux membres de la Toile de Confiance (WoT) Duniter de :
- Gerer des **documents de reference** modulaires (Licence G1, Engagements Forgeron, etc.) sous vote permanent
- Prendre des **decisions collectives** via des processus multi-etapes
- **Voter** avec un systeme de seuil adaptatif base sur la participation
- Attribuer des **mandats** a des membres de la communaute
- **Archiver de maniere immuable** les decisions adoptees via IPFS et la blockchain Duniter
## Sections
- [Premiers pas](/user/getting-started) -- Connexion et prise en main
- [Documents](/user/documents) -- Consulter et proposer des modifications aux documents de reference
- [Decisions](/user/decisions) -- Comprendre et participer aux processus decisionnels
- [Vote](/user/voting) -- Comment voter et comprendre les resultats
- [Mandats](/user/mandates) -- Mandats et responsabilites
- [Sanctuaire](/user/sanctuary) -- Archivage immuable et verification
- [FAQ](/user/faq) -- Questions frequentes

View File

@@ -0,0 +1,51 @@
---
title: Premiers pas
description: Connexion et prise en main de Glibredecision
---
# Premiers pas
## Qui peut utiliser Glibredecision ?
Glibredecision est ouvert a tous les membres de la Toile de Confiance (WoT) Duniter V2. Pour utiliser pleinement la plateforme, vous devez posseder une identite Duniter avec une adresse SS58 valide.
- **Consultation** : tout visiteur peut consulter les documents, decisions et resultats de vote.
- **Participation** (voter, proposer) : reservee aux membres authentifies via leur identite Duniter.
## Connexion
La connexion utilise votre identite Duniter sans jamais transmettre votre cle privee :
1. Cliquez sur **Se connecter** dans la barre de navigation.
2. Saisissez votre **adresse Duniter** (format SS58, par exemple `5GrwvaEF...`).
3. La plateforme vous envoie un **challenge** (texte aleatoire a signer).
4. Signez le challenge avec votre cle privee Ed25519 (via votre portefeuille Duniter ou Cesium).
5. Soumettez la signature. La plateforme verifie que vous etes bien le proprietaire de l'adresse.
6. Vous etes connecte. Un jeton de session est stocke localement (valable 24h).
## Navigation
L'interface est organisee autour de cinq sections principales :
| Section | Description |
| ------------ | ---------------------------------------------------- |
| Documents | Documents de reference de la communaute |
| Decisions | Processus decisionnels en cours et archives |
| Votes | Sessions de vote actives et resultats |
| Mandats | Mandats attribues aux membres |
| Sanctuaire | Archives immuables (IPFS + blockchain) |
## Votre profil
Apres connexion, votre profil affiche :
- Votre **adresse Duniter** SS58
- Votre **nom d'affichage** (si configure)
- Votre **statut WoT** : membre, en attente, revoque
- Vos **roles** : membre Smith (forgeron) et/ou membre du Comite Technique
Ces informations sont synchronisees depuis la blockchain Duniter V2 et determinent vos droits de vote.
## Deconnexion
Cliquez sur votre profil puis **Se deconnecter**. La session est invalidee cote serveur et le jeton local est supprime.

View File

@@ -0,0 +1,57 @@
---
title: Documents
description: Guide des documents de reference sur Glibredecision
---
# Documents de reference
## Principe
Les documents de reference sont les textes fondateurs de la communaute Duniter/G1. Ils sont **modulaires** : chaque document est compose d'items individuels (clauses, regles, verifications, preambules, sections) qui peuvent etre modifies independamment par proposition et vote.
## Types de documents
| Type | Description | Exemples |
| -------------- | --------------------------------------------------- | -------------------------------- |
| Licence | Licence monetaire definissant les regles de la monnaie | Licence G1 |
| Engagement | Engagement des membres a respecter des regles | Engagement Forgeron v2.0.0 |
| Reglement | Reglement interieur d'un organe | Reglement du Comite Technique |
| Constitution | Texte constitutif fondamental | -- |
## Consulter un document
1. Rendez-vous dans la section **Documents**.
2. Utilisez les filtres (type, statut) pour trouver le document souhaite.
3. Cliquez sur le document pour voir la liste de ses items.
4. Chaque item affiche son texte courant, son type et sa position dans le document.
## Proposer une modification
Tout membre authentifie peut proposer une modification a un item de document :
1. Ouvrez le document et selectionnez l'item a modifier.
2. Cliquez sur **Proposer une modification**.
3. Redigez le **nouveau texte propose**.
4. Ajoutez une **justification** expliquant pourquoi cette modification est necessaire.
5. Soumettez. Un diff automatique est genere entre le texte courant et votre proposition.
La proposition passe ensuite par un processus de decision (examen, vote) avant d'etre acceptee ou rejetee.
## Cycle de vie d'une proposition
```
Proposee --> En vote --> Acceptee --> Texte courant mis a jour
--> Rejetee --> Archivee
```
## Statuts des documents
| Statut | Description |
| -------- | ------------------------------------------------ |
| Brouillon | En cours de redaction, non soumis au vote |
| Actif | Document en vigueur, sous vote permanent |
| Archive | Document archive, plus en vigueur |
## Versionnage
Chaque document possede un numero de version semantique (ex: `2.0.0`). Chaque modification adoptee peut entrainer une mise a jour de version selon l'importance du changement.

View File

@@ -0,0 +1,61 @@
---
title: Decisions
description: Guide des processus decisionnels sur Glibredecision
---
# Decisions
## Principe
Une decision est un processus structure qui conduit a un choix collectif. Chaque decision suit un ensemble d'etapes definies, de la qualification a l'execution.
## Types de decisions
| Type | Description |
| ------------------ | ------------------------------------------------------ |
| Document change | Modification d'un item de document de reference |
| Runtime upgrade | Mise a jour du runtime de la blockchain Duniter |
| Mandate vote | Vote pour l'attribution d'un mandat |
| Custom | Decision personnalisee |
## Etapes d'une decision
Une decision progresse a travers les etapes suivantes :
| Etape | Description |
| --------------- | ---------------------------------------------------------------- |
| Qualification | Verification que la proposition est recevable |
| Examen (review) | Periode d'examen et de discussion par la communaute |
| Vote | Session de vote formelle avec seuil de validation |
| Execution | Mise en oeuvre de la decision adoptee |
| Rapport | Compte-rendu de l'execution et archivage des resultats |
Certaines etapes peuvent etre sautees selon le type de decision.
## Cycle de vie
```
Brouillon --> Qualification --> Examen --> Vote --> Executee --> Cloturee
--> Rejetee
```
## Suivre une decision
1. Rendez-vous dans la section **Decisions**.
2. Filtrez par type ou statut pour trouver la decision qui vous interesse.
3. La page de detail affiche toutes les etapes avec leur statut.
4. Si une etape de vote est active, vous pouvez voter directement depuis la page de decision.
## Creer une decision
Les membres authentifies peuvent creer une decision :
1. Cliquez sur **Nouvelle decision**.
2. Renseignez le titre, la description, le contexte et le type.
3. Selectionnez un **protocole de vote** qui definit les parametres de la formule de seuil.
4. Ajoutez les etapes necessaires.
5. Soumettez. La decision passe en statut "brouillon" jusqu'a ce que la premiere etape soit lancee.
## Lien avec les documents
Quand une decision de type "document change" est adoptee, la modification proposee est automatiquement appliquee a l'item du document concerne. L'ancienne version est conservee dans l'historique.

View File

@@ -0,0 +1,90 @@
---
title: Vote
description: Guide du systeme de vote sur Glibredecision
---
# Vote
## Principe
Le systeme de vote de Glibredecision est concu pour adapter le seuil d'adoption a la participation reelle. Quand peu de membres votent, une quasi-unanimite est exigee. Quand la participation est elevee, une majorite simple suffit. Ce mecanisme d'**inertie** protege contre les decisions prises par un petit groupe.
## Types de vote
### Vote binaire
Chaque votant choisit **Pour** ou **Contre**. Le seuil est calcule par la formule WoT.
### Vote nuance
Chaque votant exprime son opinion sur une echelle a 6 niveaux :
| Niveau | Label | Comptage |
| ------ | ------------- | --------------- |
| 0 | CONTRE | Negatif |
| 1 | PAS DU TOUT | Negatif |
| 2 | PAS D'ACCORD | Negatif |
| 3 | NEUTRE | Positif |
| 4 | D'ACCORD | Positif |
| 5 | TOUT A FAIT | Positif |
Le vote est adopte si les niveaux positifs (3, 4, 5) representent au moins 80% des votes et qu'un nombre minimum de participants est atteint.
## Comment voter
1. Rendez-vous sur une session de vote ouverte (via la section **Votes** ou la page d'une decision).
2. Choisissez votre vote (pour/contre en binaire, ou un niveau en nuance).
3. Ajoutez un commentaire optionnel pour expliquer votre choix.
4. **Signez votre vote** : la plateforme vous demande de signer un payload avec votre cle privee Ed25519.
5. Soumettez. Votre vote est enregistre avec la signature cryptographique.
### Modifier son vote
Vous pouvez modifier votre vote tant que la session est ouverte. L'ancien vote est desactive (conserve pour l'audit) et remplace par le nouveau.
## Comprendre les resultats
La page de resultat affiche :
| Information | Description |
| ------------------- | ---------------------------------------------------- |
| Votes pour | Nombre de votes favorables |
| Votes contre | Nombre de votes defavorables |
| Total | Nombre total de votes exprimes |
| Taille WoT | Nombre de membres WoT eligibles (snapshot au debut) |
| Seuil requis | Seuil calcule par la formule d'inertie |
| Critere Smith | Seuil et validation des votes Smith (si applicable) |
| Critere TechComm | Seuil et validation des votes TechComm (si applicable) |
| Resultat | **Adopte** ou **Rejete** |
### Exemple concret
Pour le vote de l'Engagement Forgeron v2.0.0 :
- Taille WoT : 7224 membres
- 97 votes pour, 23 votes contre (120 total)
- Seuil calcule : 94 (avec les parametres M50 B.1 G.2)
- Resultat : **Adopte** (97 >= 94)
La faible participation (120 sur 7224 = 1.7%) a rendu le seuil exigeant (94 pour sur 120 = 78%), bien au-dessus de la majorite simple de 50%.
## Preuve cryptographique
Chaque vote est accompagne d'une signature Ed25519 qui garantit :
- **Authenticite** : seul le proprietaire de l'adresse Duniter peut voter en son nom
- **Integrite** : le vote ne peut pas etre modifie apres soumission
- **Non-repudiation** : le votant ne peut pas nier avoir vote
Les votes signes peuvent etre verifies independamment par quiconque possede la cle publique du votant.
## Protocoles de vote
Chaque session de vote est liee a un **protocole de vote** qui definit :
- Le type de vote (binaire ou nuance)
- La duree du vote (en jours)
- Les parametres de la formule de seuil (majorite, exposants, etc.)
- Les criteres Smith et TechComm eventuels
Les protocoles sont reutilisables et peuvent eux-memes etre soumis a meta-gouvernance.

View File

@@ -0,0 +1,57 @@
---
title: Mandats
description: Guide des mandats sur Glibredecision
---
# Mandats
## Principe
Un mandat est une responsabilite attribuee a un membre de la communaute pour une duree determinee, apres validation par vote collectif. Les mandats permettent de formaliser les roles au sein de la gouvernance Duniter.
## Types de mandats
| Type | Description |
| --------- | ------------------------------------------------------- |
| TechComm | Mandat de membre du Comite Technique |
| Smith | Mandat lie au role de forgeron (Smith) |
| Custom | Mandat personnalise pour tout autre role |
## Cycle de vie d'un mandat
Un mandat progresse a travers les etapes suivantes :
```
Brouillon --> Candidature --> Vote --> Actif --> Rapport --> Termine
--> Revoque
```
| Etape | Description |
| ------------ | ------------------------------------------------------------ |
| Formulation | Definition du mandat, de ses objectifs et de sa duree |
| Candidature | Periode de depot des candidatures |
| Vote | Vote collectif pour designer le mandataire |
| Assignation | Attribution du mandat au candidat elu |
| Rapport | Periode de reporting sur l'execution du mandat |
| Completion | Fin normale du mandat a echeance |
| Revocation | Fin anticipee du mandat (en cas de manquement) |
## Consulter les mandats
1. Rendez-vous dans la section **Mandats**.
2. Filtrez par type (techcomm, smith, custom) ou statut.
3. Chaque mandat affiche le titulaire, les dates et les etapes.
## Creer un mandat
Les membres authentifies peuvent proposer un nouveau mandat :
1. Cliquez sur **Nouveau mandat**.
2. Renseignez le titre, la description et le type.
3. Definissez les dates de debut et de fin.
4. Ajoutez les etapes du processus.
5. Le mandat passe en phase de candidature puis de vote.
## Suppression
Seuls les mandats au statut "brouillon" peuvent etre supprimes. Une fois le processus de candidature lance, le mandat reste dans le systeme pour tracabilite.

View File

@@ -0,0 +1,61 @@
---
title: Sanctuaire
description: Guide de l'archivage immuable sur Glibredecision
---
# Sanctuaire
## Principe
Le Sanctuaire est la couche d'archivage immuable de Glibredecision. Chaque document adopte, resultat de vote ou decision finalisee est archive de maniere permanente grace a trois mecanismes :
1. **Hash SHA-256** du contenu pour garantir l'integrite
2. **Stockage IPFS** pour la distribution decentralisee
3. **Ancrage on-chain** via `system.remark` sur la blockchain Duniter V2
## Pourquoi le Sanctuaire ?
La gouvernance exige la transparence et la tracabilite. Le Sanctuaire garantit que :
- Aucune decision adoptee ne peut etre modifiee retroactivement
- Tout membre peut verifier l'authenticite d'un document ou d'un resultat de vote
- L'historique des decisions est preservee independamment de la plateforme
## Types d'entrees
| Type | Description |
| ------------ | ------------------------------------------------ |
| Document | Version adoptee d'un document de reference |
| Decision | Decision finalisee avec son resultat |
| Vote result | Resultat detaille d'une session de vote |
## Consulter le Sanctuaire
1. Rendez-vous dans la section **Sanctuaire**.
2. Filtrez par type d'entree si necessaire.
3. Chaque entree affiche :
- Le titre
- Le hash SHA-256 du contenu
- Le CID IPFS (lien vers le contenu sur IPFS)
- Le hash de la transaction on-chain
- Le numero de bloc
- La date d'archivage
## Verification d'integrite
Pour verifier qu'une entree du Sanctuaire est authentique :
1. Recuperez le contenu via IPFS en utilisant le CID affiche.
2. Calculez le hash SHA-256 du contenu telecharge.
3. Comparez avec le hash enregistre dans le Sanctuaire.
4. Verifiez que le meme hash est present dans le remark on-chain (via un explorateur blockchain).
Si les trois hash correspondent, le contenu est authentique et n'a pas ete modifie.
## Automatisation
L'archivage dans le Sanctuaire est declenche automatiquement lorsqu'un processus decisionnel est finalise :
- Quand une version d'item de document est **acceptee**, le nouveau texte est archive.
- Quand une session de vote est **cloturee**, le resultat detaille est archive.
- Quand une decision est **executee**, l'ensemble de la decision est archive.

View File

@@ -0,0 +1,80 @@
---
title: FAQ
description: Questions frequentes sur Glibredecision
---
# Questions frequentes
## Acces et authentification
### Ai-je besoin d'un compte Duniter pour utiliser Glibredecision ?
Pour **consulter** les documents, decisions et resultats de vote, aucune authentification n'est necessaire. Pour **voter**, **proposer des modifications** ou **creer des decisions**, vous devez posseder une identite Duniter V2 avec une adresse SS58.
### Comment fonctionne la connexion sans mot de passe ?
Glibredecision utilise un systeme challenge-response base sur la cryptographie Ed25519. Vous signez un texte aleatoire avec votre cle privee, et la plateforme verifie la signature avec votre cle publique. Votre cle privee n'est jamais transmise.
### Ma session a expire, que faire ?
Les sessions durent 24 heures. Reconnectez-vous en suivant le meme processus (challenge + signature). Vos votes et propositions precedents ne sont pas affectes.
## Vote
### Pourquoi le seuil est-il si eleve quand peu de personnes votent ?
C'est le mecanisme d'**inertie**. Quand la participation est faible, le seuil est eleve pour empecher qu'un petit groupe prenne des decisions engageant toute la communaute. A mesure que la participation augmente, le seuil converge vers la majorite simple. Cela incite a la participation large.
### Puis-je changer mon vote ?
Oui, tant que la session de vote est ouverte, vous pouvez modifier votre vote. L'ancien vote est conserve en base de donnees pour l'audit mais marque comme inactif. Seul le dernier vote est pris en compte dans le decompte.
### Qu'est-ce que le critere Smith ?
Certaines decisions exigent un nombre minimum de votes favorables de la part des **forgerons** (membres Smith de la WoT). Cela garantit que les decisions techniques sont soutenues par ceux qui maintiennent le reseau.
### Qu'est-ce que le critere TechComm ?
De maniere similaire, certaines decisions exigent un nombre minimum de votes favorables du **Comite Technique**. Cela concerne les decisions qui affectent le runtime ou l'infrastructure technique.
### Comment fonctionnent les votes nuances ?
Au lieu de "pour" ou "contre", vous choisissez un niveau de 0 (CONTRE) a 5 (TOUT A FAIT). Les niveaux 3, 4 et 5 comptent comme positifs. Pour que le vote soit adopte, il faut que les votes positifs representent au moins 80% du total et qu'un nombre minimum de participants soit atteint.
## Documents
### Qu'est-ce qu'un document de reference ?
Un document de reference est un texte fondateur de la communaute Duniter (Licence G1, Engagement Forgeron, Reglement du Comite Technique, etc.). Il est compose d'items modulaires sous vote permanent.
### Comment proposer une modification ?
Ouvrez le document, selectionnez l'item a modifier, cliquez sur "Proposer une modification", redigez le nouveau texte avec une justification, puis soumettez. La proposition sera soumise a un processus de decision et de vote.
### Que signifie "vote permanent" ?
Les documents actifs sont toujours ouverts aux propositions de modification. Il n'y a pas de periode speciale pour proposer des changements. Cela permet une evolution continue et organique des textes.
## Sanctuaire
### Pourquoi archiver sur IPFS et la blockchain ?
IPFS fournit un stockage distribue : le contenu est accessible meme si la plateforme Glibredecision est hors ligne. L'ancrage on-chain via `system.remark` cree une preuve horodatee immuable sur la blockchain Duniter. Ensemble, ils garantissent que les decisions de la communaute sont preservees de maniere permanente et verifiable.
### Comment verifier qu'un document n'a pas ete modifie ?
Telechargez le document depuis IPFS via son CID, calculez le hash SHA-256, puis comparez-le au hash enregistre dans le Sanctuaire et au remark on-chain. Si les trois correspondent, le document est intact.
## Technique
### Sur quelle blockchain Glibredecision fonctionne-t-il ?
Glibredecision se connecte a la blockchain **Duniter V2** (basee sur Substrate). En environnement de developpement, il se connecte au reseau de test GDev (`wss://gdev.p2p.legal/ws`).
### Les donnees de vote sont-elles publiques ?
Oui. Les votes et leurs signatures cryptographiques sont publics, conformement au principe de transparence de la gouvernance. Chaque vote peut etre verifie independamment.
### Ou est heberge Glibredecision ?
La plateforme est hebergee sur une infrastructure geree par la communaute, avec deploiement automatise via Docker et Woodpecker CI. Le code source est ouvert et disponible sur le depot Git Duniter.