1357 lines
35 KiB
Markdown
1357 lines
35 KiB
Markdown
|
|
# Document 14 : Structure YAML du Registraire
|
||
|
|
## L'Alliance Boréale — Source de Vérité Technique
|
||
|
|
|
||
|
|
**Version:** 1.0
|
||
|
|
**Date:** 23 octobre 2025
|
||
|
|
**Statut:** Document technique
|
||
|
|
**Adopté par :** Cercle Opérationnel
|
||
|
|
**Licence:** CC BY-SA 4.0
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## PRÉAMBULE
|
||
|
|
|
||
|
|
Le Registraire est **la source de vérité unique** de L'Alliance Boréale.
|
||
|
|
|
||
|
|
**Tout ce qui compte est dans le Registraire :**
|
||
|
|
- Membres (actifs, probation, sortis)
|
||
|
|
- Services fédérés (DNS, email, Matrix)
|
||
|
|
- Labels et scores
|
||
|
|
- Décisions de gouvernance
|
||
|
|
- Zones DNS
|
||
|
|
|
||
|
|
**Format : YAML + Git**
|
||
|
|
|
||
|
|
**Pourquoi YAML ?**
|
||
|
|
- ✅ Lisible par humains (contrairement à JSON)
|
||
|
|
- ✅ Éditable manuellement (pas besoin d'interface web)
|
||
|
|
- ✅ Versionnable (Git track changes)
|
||
|
|
- ✅ Validable (schemas, linters)
|
||
|
|
- ✅ Parsable par machines (Ansible, scripts)
|
||
|
|
|
||
|
|
**Pourquoi Git ?**
|
||
|
|
- ✅ Historique complet (qui a changé quoi, quand, pourquoi)
|
||
|
|
- ✅ Pull requests (review avant merge)
|
||
|
|
- ✅ Branches (test modifications avant prod)
|
||
|
|
- ✅ Réversibilité (rollback si erreur)
|
||
|
|
- ✅ Distribution (chaque membre peut cloner)
|
||
|
|
|
||
|
|
**Principe :** Une seule source de vérité, maintenue collectivement, auditable par tous.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## SECTION 1 : STRUCTURE DU DÉPÔT GIT
|
||
|
|
|
||
|
|
### 1.1 Arborescence Complète
|
||
|
|
|
||
|
|
```
|
||
|
|
registraire/
|
||
|
|
├── README.md # Documentation générale
|
||
|
|
├── CONTRIBUTING.md # Guide contribution
|
||
|
|
├── LICENSE # CC BY-SA 4.0
|
||
|
|
│
|
||
|
|
├── schemas/ # Schémas de validation
|
||
|
|
│ ├── member.schema.json # JSON Schema fiche membre
|
||
|
|
│ ├── decision.schema.json # JSON Schema décision
|
||
|
|
│ └── label.schema.json # JSON Schema label
|
||
|
|
│
|
||
|
|
├── membres/ # Fiches membres
|
||
|
|
│ ├── m001-chezlepro.yml # Membre 001
|
||
|
|
│ ├── m002-technolibre.yml # Membre 002
|
||
|
|
│ ├── m003-coop-nordique.yml # Membre 003
|
||
|
|
│ └── ...
|
||
|
|
│
|
||
|
|
├── gouvernance/ # Décisions & gouvernance
|
||
|
|
│ ├── decisions/
|
||
|
|
│ │ ├── 2025-001-admission-m001.yml
|
||
|
|
│ │ ├── 2025-002-admission-m002.yml
|
||
|
|
│ │ └── 2025-042-amendement-charte.yml
|
||
|
|
│ │
|
||
|
|
│ ├── cercles/
|
||
|
|
│ │ ├── strategique.yml # Composition cercle
|
||
|
|
│ │ ├── operationnel.yml
|
||
|
|
│ │ └── ethique.yml
|
||
|
|
│ │
|
||
|
|
│ └── assemblees/
|
||
|
|
│ ├── 2025-01-ag-annuelle.yml # PV assemblée générale
|
||
|
|
│ └── 2026-01-ag-annuelle.yml
|
||
|
|
│
|
||
|
|
├── labels/ # Labellisation
|
||
|
|
│ ├── attributions/
|
||
|
|
│ │ ├── m001-2025-Q4.yml # Label attribué
|
||
|
|
│ │ ├── m002-2025-Q4.yml
|
||
|
|
│ │ └── ...
|
||
|
|
│ │
|
||
|
|
│ └── audits/
|
||
|
|
│ ├── m001-2025-Q4-rapport.yml # Rapport audit (synthèse)
|
||
|
|
│ └── ...
|
||
|
|
│
|
||
|
|
├── dns/ # Configuration DNS
|
||
|
|
│ ├── zones/
|
||
|
|
│ │ ├── boreal.ca.zone # Zone racine
|
||
|
|
│ │ ├── chezlepro.boreal.ca.zone # Zones membres
|
||
|
|
│ │ └── technolibre.boreal.ca.zone
|
||
|
|
│ │
|
||
|
|
│ └── delegations/
|
||
|
|
│ └── delegations.yml # Liste délégations actives
|
||
|
|
│
|
||
|
|
├── incidents/ # Post-mortems
|
||
|
|
│ ├── 2025-10-incident-dns-p1.yml
|
||
|
|
│ └── 2025-11-incident-cert-p0.yml
|
||
|
|
│
|
||
|
|
└── banque-temps/ # Transactions (si implémentée)
|
||
|
|
└── transactions-2025-Q4.yml
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 1.2 Nomenclature des Fichiers
|
||
|
|
|
||
|
|
**Règles strictes :**
|
||
|
|
|
||
|
|
| Type | Format | Exemple |
|
||
|
|
|------|--------|---------|
|
||
|
|
| **Membre** | `mXXX-[slug].yml` | `m001-chezlepro.yml` |
|
||
|
|
| **Décision** | `YYYY-NNN-[titre-court].yml` | `2025-042-amendement-charte.yml` |
|
||
|
|
| **Label** | `mXXX-YYYY-QN.yml` | `m001-2025-Q4.yml` |
|
||
|
|
| **Audit** | `mXXX-YYYY-QN-rapport.yml` | `m001-2025-Q4-rapport.yml` |
|
||
|
|
| **Incident** | `YYYY-MM-incident-[titre]-[prio].yml` | `2025-10-incident-dns-p1.yml` |
|
||
|
|
| **Zone DNS** | `[domain].zone` | `chezlepro.boreal.ca.zone` |
|
||
|
|
|
||
|
|
**Avantages :**
|
||
|
|
- Tri alphabétique = tri chronologique (pour décisions, incidents)
|
||
|
|
- ID membre visible (mXXX)
|
||
|
|
- Parsing facile (scripts)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 1.3 Branches et Workflow Git
|
||
|
|
|
||
|
|
**Branches :**
|
||
|
|
|
||
|
|
```
|
||
|
|
main → Production (fiches validées)
|
||
|
|
├── dev → Développement (intégration continue)
|
||
|
|
└── feature/* → Branches de travail (1 feature = 1 branch)
|
||
|
|
├── feature/add-member-m004
|
||
|
|
├── feature/update-label-m001
|
||
|
|
└── feature/dns-delegation-m002
|
||
|
|
```
|
||
|
|
|
||
|
|
**Workflow Pull Request :**
|
||
|
|
|
||
|
|
1. **Créer branche** : `git checkout -b feature/add-member-m004`
|
||
|
|
2. **Modifier fichier(s)** : Éditer `membres/m004-nouveau.yml`
|
||
|
|
3. **Commit** : `git commit -m "feat: Add member m004 (Nouveau OBNL)"`
|
||
|
|
4. **Push** : `git push origin feature/add-member-m004`
|
||
|
|
5. **Ouvrir Pull Request** sur Forge
|
||
|
|
6. **Review** : 1+ membre (vérification conformité)
|
||
|
|
7. **CI/CD** : Tests automatiques (yamllint, schema validation)
|
||
|
|
8. **Merge** : Si tests ✅ + review ✅ → merge dans `main`
|
||
|
|
|
||
|
|
**Protection branche `main` :**
|
||
|
|
- Aucun push direct (seulement via PR)
|
||
|
|
- Review obligatoire (1+ personne)
|
||
|
|
- CI/CD doit passer (tests)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## SECTION 2 : SCHÉMA FICHE MEMBRE
|
||
|
|
|
||
|
|
### 2.1 Structure Complète (Commentée)
|
||
|
|
|
||
|
|
**Fichier : `membres/m001-chezlepro.yml`**
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
# ============================================================================
|
||
|
|
# FICHE MEMBRE — L'Alliance Boréale
|
||
|
|
# ============================================================================
|
||
|
|
# ID: m001
|
||
|
|
# Slug: chezlepro
|
||
|
|
# Nom légal: Chez le Pro Technologies Inc.
|
||
|
|
# Statut: actif
|
||
|
|
# Dernière mise à jour: 2025-10-23
|
||
|
|
# ============================================================================
|
||
|
|
|
||
|
|
# ----------------------------------------------------------------------------
|
||
|
|
# SECTION 1 : IDENTITÉ
|
||
|
|
# ----------------------------------------------------------------------------
|
||
|
|
member_id: m001
|
||
|
|
slug: chezlepro
|
||
|
|
status: active # active | probation | suspended | exited
|
||
|
|
|
||
|
|
identity:
|
||
|
|
legal_name: "Chez le Pro Technologies Inc."
|
||
|
|
legal_form: corporation # corporation | coop | npo | sole_proprietorship
|
||
|
|
jurisdiction: QC # Juridiction d'enregistrement
|
||
|
|
registration_number: "1234567890" # NEQ (Québec) ou équivalent
|
||
|
|
|
||
|
|
operating_name: "Chez le Pro" # Nom commercial (si différent)
|
||
|
|
|
||
|
|
website: "https://chezle.pro"
|
||
|
|
|
||
|
|
founded_date: "2018-03-15"
|
||
|
|
joined_alliance_date: "2025-01-15"
|
||
|
|
probation_end_date: "2025-04-15" # null si membre actif confirmé
|
||
|
|
|
||
|
|
description: |
|
||
|
|
Chez le Pro offre des services d'hébergement web éthique et de
|
||
|
|
développement logiciel sur mesure pour PME québécoises. Membre
|
||
|
|
fondateur de L'Alliance Boréale.
|
||
|
|
|
||
|
|
# ----------------------------------------------------------------------------
|
||
|
|
# SECTION 2 : CONTACTS
|
||
|
|
# ----------------------------------------------------------------------------
|
||
|
|
contacts:
|
||
|
|
primary:
|
||
|
|
name: "Jean Tremblay"
|
||
|
|
role: "Président"
|
||
|
|
email: "jean@chezle.pro"
|
||
|
|
phone: "+1-514-555-0100"
|
||
|
|
matrix: "@jean:matrix.chezlepro.boreal.ca"
|
||
|
|
|
||
|
|
technical:
|
||
|
|
name: "Marie Gagnon"
|
||
|
|
role: "Directrice technique"
|
||
|
|
email: "marie@chezle.pro"
|
||
|
|
phone: "+1-514-555-0101"
|
||
|
|
matrix: "@marie:matrix.chezlepro.boreal.ca"
|
||
|
|
|
||
|
|
security:
|
||
|
|
email: "security@chezle.pro"
|
||
|
|
pgp_key: "0x1234567890ABCDEF"
|
||
|
|
pgp_fingerprint: "1234 5678 90AB CDEF 1234 5678 90AB CDEF 1234 5678"
|
||
|
|
|
||
|
|
legal:
|
||
|
|
name: "Sophie Lavoie"
|
||
|
|
role: "Conseillère juridique"
|
||
|
|
email: "legal@chezle.pro"
|
||
|
|
|
||
|
|
# ----------------------------------------------------------------------------
|
||
|
|
# SECTION 3 : INFRASTRUCTURE
|
||
|
|
# ----------------------------------------------------------------------------
|
||
|
|
infrastructure:
|
||
|
|
hosting:
|
||
|
|
provider: "OVH Canada"
|
||
|
|
datacenter_location: "Montreal, QC, Canada"
|
||
|
|
owned: false # true = hardware propre, false = loué
|
||
|
|
|
||
|
|
network:
|
||
|
|
ipv4_public:
|
||
|
|
- "203.0.113.10/32"
|
||
|
|
- "203.0.113.20/28"
|
||
|
|
ipv6_public:
|
||
|
|
- "2001:db8:1234::/48"
|
||
|
|
|
||
|
|
ipv4_private: "10.1.0.0/16" # Selon Doc 5
|
||
|
|
|
||
|
|
asn: null # Autonomous System Number (si applicable)
|
||
|
|
|
||
|
|
dns:
|
||
|
|
primary_ns: "ns1.chezlepro.boreal.ca"
|
||
|
|
secondary_ns: "ns2.chezlepro.boreal.ca"
|
||
|
|
|
||
|
|
ns_ips:
|
||
|
|
ns1: "203.0.113.10"
|
||
|
|
ns2: "203.0.113.11"
|
||
|
|
|
||
|
|
dnssec_enabled: true
|
||
|
|
dnssec_ds_records:
|
||
|
|
- "12345 8 2 1234567890ABCDEF..." # DS record pour parent
|
||
|
|
|
||
|
|
servers:
|
||
|
|
count: 3
|
||
|
|
summary: |
|
||
|
|
- 1x serveur compute (Proxmox)
|
||
|
|
- 1x serveur storage (ZFS)
|
||
|
|
- 1x serveur backup (dédié)
|
||
|
|
|
||
|
|
# ----------------------------------------------------------------------------
|
||
|
|
# SECTION 4 : SERVICES PUBLICS
|
||
|
|
# ----------------------------------------------------------------------------
|
||
|
|
services:
|
||
|
|
email:
|
||
|
|
enabled: true
|
||
|
|
domain: "chezle.pro"
|
||
|
|
mx_records:
|
||
|
|
- priority: 10
|
||
|
|
host: "mail.chezlepro.boreal.ca"
|
||
|
|
|
||
|
|
protocols:
|
||
|
|
- smtp
|
||
|
|
- smtps
|
||
|
|
- imap
|
||
|
|
- imaps
|
||
|
|
|
||
|
|
security:
|
||
|
|
dkim: true
|
||
|
|
spf: true
|
||
|
|
dmarc: true
|
||
|
|
tls_min_version: "1.2"
|
||
|
|
|
||
|
|
web:
|
||
|
|
enabled: true
|
||
|
|
urls:
|
||
|
|
- "https://chezle.pro"
|
||
|
|
- "https://www.chezle.pro"
|
||
|
|
|
||
|
|
technologies:
|
||
|
|
- nginx
|
||
|
|
- php-fpm
|
||
|
|
- postgresql
|
||
|
|
|
||
|
|
cloud_storage:
|
||
|
|
enabled: true
|
||
|
|
platform: nextcloud
|
||
|
|
url: "https://cloud.chezlepro.boreal.ca"
|
||
|
|
version: "28.0.1"
|
||
|
|
|
||
|
|
matrix:
|
||
|
|
enabled: true
|
||
|
|
homeserver_url: "https://matrix.chezlepro.boreal.ca"
|
||
|
|
federation_enabled: true
|
||
|
|
server_name: "chezlepro.boreal.ca"
|
||
|
|
|
||
|
|
status_page:
|
||
|
|
enabled: true
|
||
|
|
url: "https://status.chezlepro.boreal.ca"
|
||
|
|
platform: "upptime" # upptime | cachet | custom
|
||
|
|
|
||
|
|
monitoring:
|
||
|
|
prometheus_endpoint: "https://prometheus.chezlepro.boreal.ca"
|
||
|
|
grafana_url: "https://grafana.chezlepro.boreal.ca"
|
||
|
|
public_metrics: true # Métriques partagées avec Alliance
|
||
|
|
|
||
|
|
# ----------------------------------------------------------------------------
|
||
|
|
# SECTION 5 : STANDARDS ET CONFORMITÉ
|
||
|
|
# ----------------------------------------------------------------------------
|
||
|
|
standards:
|
||
|
|
open_source_percentage: 85 # % de stack en logiciels libres
|
||
|
|
|
||
|
|
protocols_supported:
|
||
|
|
- smtp
|
||
|
|
- imap
|
||
|
|
- caldav
|
||
|
|
- carddav
|
||
|
|
- webdav
|
||
|
|
- matrix
|
||
|
|
|
||
|
|
certifications:
|
||
|
|
- name: "ISO 27001"
|
||
|
|
issued_by: "BSI Group"
|
||
|
|
valid_until: "2026-12-31"
|
||
|
|
certificate_url: "https://chezle.pro/certs/iso27001.pdf"
|
||
|
|
|
||
|
|
compliance:
|
||
|
|
loi_25: true # Conformité Loi 25 (Québec)
|
||
|
|
rgpd: true # Conformité RGPD (EU)
|
||
|
|
pipeda: true # Conformité PIPEDA (Canada)
|
||
|
|
|
||
|
|
# ----------------------------------------------------------------------------
|
||
|
|
# SECTION 6 : LABEL DE PRESTIGE
|
||
|
|
# ----------------------------------------------------------------------------
|
||
|
|
label:
|
||
|
|
current:
|
||
|
|
level: gold # bronze | silver | gold | platinum | null
|
||
|
|
score_global: 82
|
||
|
|
scores_by_domain:
|
||
|
|
infrastructure: 85
|
||
|
|
security: 88
|
||
|
|
interoperability: 78
|
||
|
|
open_source: 90
|
||
|
|
operations: 75
|
||
|
|
sustainability: 72
|
||
|
|
|
||
|
|
issued_date: "2025-10-01"
|
||
|
|
valid_until: "2026-10-01"
|
||
|
|
audited_by: "m002" # Membre auditeur
|
||
|
|
|
||
|
|
report_url: "registraire/labels/audits/m001-2025-Q4-rapport.yml"
|
||
|
|
|
||
|
|
history:
|
||
|
|
- level: silver
|
||
|
|
score_global: 68
|
||
|
|
issued_date: "2025-04-01"
|
||
|
|
valid_until: "2026-04-01"
|
||
|
|
|
||
|
|
- level: bronze
|
||
|
|
score_global: 52
|
||
|
|
issued_date: "2025-01-15"
|
||
|
|
valid_until: "2026-01-15"
|
||
|
|
|
||
|
|
# ----------------------------------------------------------------------------
|
||
|
|
# SECTION 7 : PARTICIPATION & CONTRIBUTIONS
|
||
|
|
# ----------------------------------------------------------------------------
|
||
|
|
participation:
|
||
|
|
cercles:
|
||
|
|
- name: "Cercle Stratégique"
|
||
|
|
role: "membre"
|
||
|
|
since: "2025-01-15"
|
||
|
|
|
||
|
|
- name: "Cercle Opérationnel"
|
||
|
|
role: "président"
|
||
|
|
since: "2025-07-01"
|
||
|
|
until: "2026-01-01"
|
||
|
|
|
||
|
|
contributions:
|
||
|
|
- type: "code"
|
||
|
|
description: "Développement Registraire YAML (validation, CI/CD)"
|
||
|
|
date: "2025-03-20"
|
||
|
|
hours: 15
|
||
|
|
|
||
|
|
- type: "documentation"
|
||
|
|
description: "Rédaction runbooks DNS & DNSSEC"
|
||
|
|
date: "2025-05-10"
|
||
|
|
hours: 8
|
||
|
|
|
||
|
|
- type: "mentoring"
|
||
|
|
description: "Parrainage membre m003 (probation)"
|
||
|
|
date: "2025-08-01"
|
||
|
|
status: "en_cours"
|
||
|
|
|
||
|
|
banque_temps:
|
||
|
|
balance: 42 # Crédits (heures)
|
||
|
|
last_updated: "2025-10-20"
|
||
|
|
|
||
|
|
# ----------------------------------------------------------------------------
|
||
|
|
# SECTION 8 : MÉTADONNÉES
|
||
|
|
# ----------------------------------------------------------------------------
|
||
|
|
metadata:
|
||
|
|
created_at: "2025-01-15T10:30:00Z"
|
||
|
|
updated_at: "2025-10-23T14:22:00Z"
|
||
|
|
updated_by: "m001" # Dernière modification par
|
||
|
|
|
||
|
|
version: 2 # Numéro de version du schéma
|
||
|
|
|
||
|
|
notes: |
|
||
|
|
Membre fondateur. Infrastructure solide. Contributions régulières.
|
||
|
|
Candidat potentiel Platine en 2026 si maintien niveau actuel.
|
||
|
|
|
||
|
|
tags:
|
||
|
|
- fondateur
|
||
|
|
- hebergement
|
||
|
|
- quebec
|
||
|
|
- infrastructure-mature
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 2.2 Champs Obligatoires vs Optionnels
|
||
|
|
|
||
|
|
**Obligatoires (validation bloquante) :**
|
||
|
|
- `member_id`
|
||
|
|
- `slug`
|
||
|
|
- `status`
|
||
|
|
- `identity.legal_name`
|
||
|
|
- `identity.legal_form`
|
||
|
|
- `identity.joined_alliance_date`
|
||
|
|
- `contacts.primary` (name, email)
|
||
|
|
- `contacts.technical.email`
|
||
|
|
- `contacts.security.email`
|
||
|
|
- `infrastructure.dns.primary_ns`
|
||
|
|
- `services.status_page.url`
|
||
|
|
|
||
|
|
**Recommandés (warning si absent) :**
|
||
|
|
- `identity.website`
|
||
|
|
- `infrastructure.dns.dnssec_enabled`
|
||
|
|
- `services.email` (si service email offert)
|
||
|
|
- `standards.open_source_percentage`
|
||
|
|
- `label.current` (si labellisé)
|
||
|
|
|
||
|
|
**Optionnels (sans warning) :**
|
||
|
|
- `infrastructure.network.asn`
|
||
|
|
- `standards.certifications`
|
||
|
|
- `participation.contributions`
|
||
|
|
- `metadata.notes`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 2.3 Valeurs Enum (Contrôlées)
|
||
|
|
|
||
|
|
**Statut membre (`status`) :**
|
||
|
|
- `probation` : En période probatoire (3 mois)
|
||
|
|
- `active` : Membre actif confirmé
|
||
|
|
- `suspended` : Suspendu temporairement
|
||
|
|
- `exited` : Sorti de L'Alliance (volontaire ou radiation)
|
||
|
|
|
||
|
|
**Forme légale (`identity.legal_form`) :**
|
||
|
|
- `corporation` : Entreprise incorporée
|
||
|
|
- `coop` : Coopérative
|
||
|
|
- `npo` : Organisme à but non lucratif
|
||
|
|
- `sole_proprietorship` : Travailleur autonome
|
||
|
|
|
||
|
|
**Niveau label (`label.current.level`) :**
|
||
|
|
- `bronze`
|
||
|
|
- `silver`
|
||
|
|
- `gold`
|
||
|
|
- `platinum`
|
||
|
|
- `null` : Non labellisé
|
||
|
|
|
||
|
|
**Type contribution (`participation.contributions.type`) :**
|
||
|
|
- `code` : Contribution code (forge)
|
||
|
|
- `documentation` : Rédaction wiki/runbooks
|
||
|
|
- `mentoring` : Parrainage nouveau membre
|
||
|
|
- `audit` : Audit pair-à-pair
|
||
|
|
- `governance` : Participation cercle
|
||
|
|
- `infrastructure` : Support technique mutuel
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## SECTION 3 : VALIDATION AUTOMATIQUE
|
||
|
|
|
||
|
|
### 3.1 YAML Lint (Syntaxe)
|
||
|
|
|
||
|
|
**Outil : `yamllint`**
|
||
|
|
|
||
|
|
**Configuration : `.yamllint`**
|
||
|
|
```yaml
|
||
|
|
extends: default
|
||
|
|
|
||
|
|
rules:
|
||
|
|
line-length:
|
||
|
|
max: 120
|
||
|
|
level: warning
|
||
|
|
|
||
|
|
indentation:
|
||
|
|
spaces: 2
|
||
|
|
|
||
|
|
comments:
|
||
|
|
min-spaces-from-content: 2
|
||
|
|
|
||
|
|
document-start:
|
||
|
|
present: true
|
||
|
|
```
|
||
|
|
|
||
|
|
**Commande :**
|
||
|
|
```bash
|
||
|
|
yamllint membres/*.yml
|
||
|
|
```
|
||
|
|
|
||
|
|
**Résultat attendu :**
|
||
|
|
```
|
||
|
|
membres/m001-chezlepro.yml
|
||
|
|
0:0 warning missing document start "---" (document-start)
|
||
|
|
|
||
|
|
membres/m002-technolibre.yml
|
||
|
|
0:0 warning missing document start "---" (document-start)
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 3.2 JSON Schema (Structure)
|
||
|
|
|
||
|
|
**Schéma : `schemas/member.schema.json`**
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||
|
|
"$id": "https://registraire.alliance-boreale.ca/schemas/member.schema.json",
|
||
|
|
"title": "Alliance Boréale - Fiche Membre",
|
||
|
|
"description": "Schéma de validation pour fiche membre",
|
||
|
|
"type": "object",
|
||
|
|
|
||
|
|
"required": [
|
||
|
|
"member_id",
|
||
|
|
"slug",
|
||
|
|
"status",
|
||
|
|
"identity",
|
||
|
|
"contacts",
|
||
|
|
"infrastructure",
|
||
|
|
"services"
|
||
|
|
],
|
||
|
|
|
||
|
|
"properties": {
|
||
|
|
"member_id": {
|
||
|
|
"type": "string",
|
||
|
|
"pattern": "^m[0-9]{3}$",
|
||
|
|
"description": "ID unique membre (format: mXXX)"
|
||
|
|
},
|
||
|
|
|
||
|
|
"slug": {
|
||
|
|
"type": "string",
|
||
|
|
"pattern": "^[a-z0-9-]{3,20}$",
|
||
|
|
"description": "Slug textuel unique (3-20 car, minuscules)"
|
||
|
|
},
|
||
|
|
|
||
|
|
"status": {
|
||
|
|
"type": "string",
|
||
|
|
"enum": ["probation", "active", "suspended", "exited"]
|
||
|
|
},
|
||
|
|
|
||
|
|
"identity": {
|
||
|
|
"type": "object",
|
||
|
|
"required": ["legal_name", "legal_form", "joined_alliance_date"],
|
||
|
|
"properties": {
|
||
|
|
"legal_name": { "type": "string", "minLength": 3 },
|
||
|
|
"legal_form": {
|
||
|
|
"type": "string",
|
||
|
|
"enum": ["corporation", "coop", "npo", "sole_proprietorship"]
|
||
|
|
},
|
||
|
|
"jurisdiction": { "type": "string", "pattern": "^[A-Z]{2}$" },
|
||
|
|
"registration_number": { "type": "string" },
|
||
|
|
"website": { "type": "string", "format": "uri" },
|
||
|
|
"joined_alliance_date": { "type": "string", "format": "date" },
|
||
|
|
"description": { "type": "string" }
|
||
|
|
}
|
||
|
|
},
|
||
|
|
|
||
|
|
"contacts": {
|
||
|
|
"type": "object",
|
||
|
|
"required": ["primary", "technical", "security"],
|
||
|
|
"properties": {
|
||
|
|
"primary": {
|
||
|
|
"type": "object",
|
||
|
|
"required": ["name", "email"],
|
||
|
|
"properties": {
|
||
|
|
"name": { "type": "string" },
|
||
|
|
"role": { "type": "string" },
|
||
|
|
"email": { "type": "string", "format": "email" },
|
||
|
|
"phone": { "type": "string" },
|
||
|
|
"matrix": { "type": "string" }
|
||
|
|
}
|
||
|
|
},
|
||
|
|
"technical": {
|
||
|
|
"type": "object",
|
||
|
|
"required": ["email"],
|
||
|
|
"properties": {
|
||
|
|
"name": { "type": "string" },
|
||
|
|
"email": { "type": "string", "format": "email" }
|
||
|
|
}
|
||
|
|
},
|
||
|
|
"security": {
|
||
|
|
"type": "object",
|
||
|
|
"required": ["email"],
|
||
|
|
"properties": {
|
||
|
|
"email": { "type": "string", "format": "email" },
|
||
|
|
"pgp_key": { "type": "string" }
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
},
|
||
|
|
|
||
|
|
"infrastructure": {
|
||
|
|
"type": "object",
|
||
|
|
"required": ["dns"],
|
||
|
|
"properties": {
|
||
|
|
"dns": {
|
||
|
|
"type": "object",
|
||
|
|
"required": ["primary_ns"],
|
||
|
|
"properties": {
|
||
|
|
"primary_ns": { "type": "string", "format": "hostname" },
|
||
|
|
"secondary_ns": { "type": "string", "format": "hostname" },
|
||
|
|
"dnssec_enabled": { "type": "boolean" }
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
},
|
||
|
|
|
||
|
|
"services": {
|
||
|
|
"type": "object",
|
||
|
|
"required": ["status_page"],
|
||
|
|
"properties": {
|
||
|
|
"status_page": {
|
||
|
|
"type": "object",
|
||
|
|
"required": ["url"],
|
||
|
|
"properties": {
|
||
|
|
"enabled": { "type": "boolean" },
|
||
|
|
"url": { "type": "string", "format": "uri" }
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
},
|
||
|
|
|
||
|
|
"label": {
|
||
|
|
"type": "object",
|
||
|
|
"properties": {
|
||
|
|
"current": {
|
||
|
|
"type": "object",
|
||
|
|
"required": ["level", "score_global", "issued_date", "valid_until"],
|
||
|
|
"properties": {
|
||
|
|
"level": {
|
||
|
|
"type": "string",
|
||
|
|
"enum": ["bronze", "silver", "gold", "platinum"]
|
||
|
|
},
|
||
|
|
"score_global": {
|
||
|
|
"type": "integer",
|
||
|
|
"minimum": 0,
|
||
|
|
"maximum": 100
|
||
|
|
},
|
||
|
|
"scores_by_domain": {
|
||
|
|
"type": "object",
|
||
|
|
"properties": {
|
||
|
|
"infrastructure": { "type": "integer", "minimum": 0, "maximum": 100 },
|
||
|
|
"security": { "type": "integer", "minimum": 0, "maximum": 100 },
|
||
|
|
"interoperability": { "type": "integer", "minimum": 0, "maximum": 100 },
|
||
|
|
"open_source": { "type": "integer", "minimum": 0, "maximum": 100 },
|
||
|
|
"operations": { "type": "integer", "minimum": 0, "maximum": 100 },
|
||
|
|
"sustainability": { "type": "integer", "minimum": 0, "maximum": 100 }
|
||
|
|
}
|
||
|
|
},
|
||
|
|
"issued_date": { "type": "string", "format": "date" },
|
||
|
|
"valid_until": { "type": "string", "format": "date" }
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Validation :**
|
||
|
|
```bash
|
||
|
|
# Outil: ajv-cli (JSON Schema validator)
|
||
|
|
ajv validate -s schemas/member.schema.json -d "membres/*.yml"
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 3.3 CI/CD Pipeline
|
||
|
|
|
||
|
|
**Fichier : `.gitlab-ci.yml` (ou `.github/workflows/validate.yml`)**
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
stages:
|
||
|
|
- validate
|
||
|
|
- test
|
||
|
|
- deploy
|
||
|
|
|
||
|
|
# Job 1: Validation syntaxe YAML
|
||
|
|
yaml-lint:
|
||
|
|
stage: validate
|
||
|
|
image: python:3.11-alpine
|
||
|
|
before_script:
|
||
|
|
- pip install yamllint
|
||
|
|
script:
|
||
|
|
- yamllint membres/*.yml gouvernance/**/*.yml labels/**/*.yml
|
||
|
|
only:
|
||
|
|
- merge_requests
|
||
|
|
- main
|
||
|
|
|
||
|
|
# Job 2: Validation structure (JSON Schema)
|
||
|
|
schema-validation:
|
||
|
|
stage: validate
|
||
|
|
image: node:18-alpine
|
||
|
|
before_script:
|
||
|
|
- npm install -g ajv-cli ajv-formats
|
||
|
|
script:
|
||
|
|
- ajv validate -s schemas/member.schema.json -d "membres/*.yml"
|
||
|
|
- ajv validate -s schemas/decision.schema.json -d "gouvernance/decisions/*.yml"
|
||
|
|
- ajv validate -s schemas/label.schema.json -d "labels/attributions/*.yml"
|
||
|
|
only:
|
||
|
|
- merge_requests
|
||
|
|
- main
|
||
|
|
|
||
|
|
# Job 3: Vérification unicité slug/ID
|
||
|
|
uniqueness-check:
|
||
|
|
stage: test
|
||
|
|
image: python:3.11-alpine
|
||
|
|
before_script:
|
||
|
|
- pip install pyyaml
|
||
|
|
script:
|
||
|
|
- python scripts/check-uniqueness.py
|
||
|
|
only:
|
||
|
|
- merge_requests
|
||
|
|
- main
|
||
|
|
|
||
|
|
# Job 4: Génération site web statique (optionnel)
|
||
|
|
generate-website:
|
||
|
|
stage: deploy
|
||
|
|
image: python:3.11-alpine
|
||
|
|
before_script:
|
||
|
|
- pip install pyyaml jinja2
|
||
|
|
script:
|
||
|
|
- python scripts/generate-website.py
|
||
|
|
- mkdir -p public
|
||
|
|
- cp -r website/* public/
|
||
|
|
artifacts:
|
||
|
|
paths:
|
||
|
|
- public
|
||
|
|
only:
|
||
|
|
- main
|
||
|
|
```
|
||
|
|
|
||
|
|
**Script `scripts/check-uniqueness.py` :**
|
||
|
|
```python
|
||
|
|
#!/usr/bin/env python3
|
||
|
|
"""Vérifier unicité des IDs et slugs membres."""
|
||
|
|
|
||
|
|
import sys
|
||
|
|
from pathlib import Path
|
||
|
|
import yaml
|
||
|
|
|
||
|
|
def check_uniqueness():
|
||
|
|
members_dir = Path("membres")
|
||
|
|
|
||
|
|
ids = []
|
||
|
|
slugs = []
|
||
|
|
|
||
|
|
for file in members_dir.glob("*.yml"):
|
||
|
|
with open(file) as f:
|
||
|
|
data = yaml.safe_load(f)
|
||
|
|
|
||
|
|
member_id = data.get("member_id")
|
||
|
|
slug = data.get("slug")
|
||
|
|
|
||
|
|
if member_id in ids:
|
||
|
|
print(f"❌ ERREUR: ID {member_id} dupliqué dans {file}")
|
||
|
|
sys.exit(1)
|
||
|
|
ids.append(member_id)
|
||
|
|
|
||
|
|
if slug in slugs:
|
||
|
|
print(f"❌ ERREUR: Slug {slug} dupliqué dans {file}")
|
||
|
|
sys.exit(1)
|
||
|
|
slugs.append(slug)
|
||
|
|
|
||
|
|
print(f"✅ Validation OK: {len(ids)} membres, IDs et slugs uniques")
|
||
|
|
return 0
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
sys.exit(check_uniqueness())
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## SECTION 4 : PROCESSUS DE MISE À JOUR
|
||
|
|
|
||
|
|
### 4.1 Modification par le Membre Lui-Même
|
||
|
|
|
||
|
|
**Cas d'usage :** Mise à jour contact technique, ajout service, etc.
|
||
|
|
|
||
|
|
**Processus :**
|
||
|
|
|
||
|
|
1. **Cloner le dépôt**
|
||
|
|
```bash
|
||
|
|
git clone https://forge.boreal.ca/alliance/registraire.git
|
||
|
|
cd registraire
|
||
|
|
```
|
||
|
|
|
||
|
|
2. **Créer branche**
|
||
|
|
```bash
|
||
|
|
git checkout -b update/m001-add-matrix-service
|
||
|
|
```
|
||
|
|
|
||
|
|
3. **Éditer fiche**
|
||
|
|
```bash
|
||
|
|
vim membres/m001-chezlepro.yml
|
||
|
|
# Ajouter section services.matrix
|
||
|
|
```
|
||
|
|
|
||
|
|
4. **Valider localement**
|
||
|
|
```bash
|
||
|
|
yamllint membres/m001-chezlepro.yml
|
||
|
|
ajv validate -s schemas/member.schema.json -d membres/m001-chezlepro.yml
|
||
|
|
```
|
||
|
|
|
||
|
|
5. **Commit**
|
||
|
|
```bash
|
||
|
|
git add membres/m001-chezlepro.yml
|
||
|
|
git commit -m "feat(m001): Add Matrix federation service"
|
||
|
|
```
|
||
|
|
|
||
|
|
6. **Push et Pull Request**
|
||
|
|
```bash
|
||
|
|
git push origin update/m001-add-matrix-service
|
||
|
|
# Ouvrir PR sur forge.boreal.ca
|
||
|
|
```
|
||
|
|
|
||
|
|
7. **Review + Merge**
|
||
|
|
- Cercle Opérationnel review (vérification cohérence)
|
||
|
|
- CI/CD valide (tests automatiques)
|
||
|
|
- Merge dans `main`
|
||
|
|
|
||
|
|
**Délai typique :** 1-3 jours.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 4.2 Modification par Cercle Opérationnel
|
||
|
|
|
||
|
|
**Cas d'usage :** Changement statut, attribution label, décision gouvernance.
|
||
|
|
|
||
|
|
**Processus similaire, mais :**
|
||
|
|
- Commit signé GPG (authentification)
|
||
|
|
- Mention dans commit message : `[CERCLE-OPS]`
|
||
|
|
- Review par 2+ membres du Cercle Opérationnel
|
||
|
|
|
||
|
|
**Exemple :**
|
||
|
|
```bash
|
||
|
|
git commit -S -m "[CERCLE-OPS] feat(m001): Promote to Gold label (Q4 2025)"
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 4.3 Modification Urgente (Incident)
|
||
|
|
|
||
|
|
**Cas d'usage :** Révocation certificat, changement IP urgent.
|
||
|
|
|
||
|
|
**Processus accéléré :**
|
||
|
|
- Commit direct sur `main` autorisé (exception)
|
||
|
|
- Notification Matrix #incidents immédiate
|
||
|
|
- Justification dans commit message
|
||
|
|
|
||
|
|
**Exemple :**
|
||
|
|
```bash
|
||
|
|
git commit -m "fix(m001): Update DNS IP after datacenter migration (P1 incident)"
|
||
|
|
git push origin main
|
||
|
|
# Post dans Matrix: "🚨 Update urgent registraire m001 (migration datacenter)"
|
||
|
|
```
|
||
|
|
|
||
|
|
**Post-mortem :** Documentation de l'incident + amélioration du processus si nécessaire.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## SECTION 5 : GÉNÉRATION DE VUES
|
||
|
|
|
||
|
|
### 5.1 Site Web Public
|
||
|
|
|
||
|
|
**Concept :** Générer site web statique à partir des YAML (lecture seule).
|
||
|
|
|
||
|
|
**URL :** `https://registraire.alliance-boreale.ca`
|
||
|
|
|
||
|
|
**Pages générées :**
|
||
|
|
- `/` : Liste membres actifs
|
||
|
|
- `/membres/m001` : Fiche membre détaillée (infos publiques)
|
||
|
|
- `/labels` : Tableau de bord labels
|
||
|
|
- `/decisions` : Liste décisions publiques
|
||
|
|
- `/stats` : Statistiques agrégées
|
||
|
|
|
||
|
|
**Technologie :** Python + Jinja2, ou Jekyll, ou Hugo.
|
||
|
|
|
||
|
|
**Script `scripts/generate-website.py` (squelette) :**
|
||
|
|
```python
|
||
|
|
#!/usr/bin/env python3
|
||
|
|
"""Générer site web statique à partir des YAML."""
|
||
|
|
|
||
|
|
from pathlib import Path
|
||
|
|
import yaml
|
||
|
|
from jinja2 import Environment, FileSystemLoader
|
||
|
|
|
||
|
|
def generate():
|
||
|
|
# Charger tous les membres
|
||
|
|
members = []
|
||
|
|
for file in Path("membres").glob("*.yml"):
|
||
|
|
with open(file) as f:
|
||
|
|
data = yaml.safe_load(f)
|
||
|
|
if data["status"] in ["active", "probation"]:
|
||
|
|
members.append(data)
|
||
|
|
|
||
|
|
# Trier par joined_date
|
||
|
|
members.sort(key=lambda m: m["identity"]["joined_alliance_date"])
|
||
|
|
|
||
|
|
# Générer HTML
|
||
|
|
env = Environment(loader=FileSystemLoader("templates"))
|
||
|
|
template = env.get_template("index.html")
|
||
|
|
|
||
|
|
html = template.render(members=members)
|
||
|
|
|
||
|
|
Path("website").mkdir(exist_ok=True)
|
||
|
|
with open("website/index.html", "w") as f:
|
||
|
|
f.write(html)
|
||
|
|
|
||
|
|
print(f"✅ Site généré: {len(members)} membres")
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
generate()
|
||
|
|
```
|
||
|
|
|
||
|
|
**Template `templates/index.html` :**
|
||
|
|
```html
|
||
|
|
<!DOCTYPE html>
|
||
|
|
<html lang="fr">
|
||
|
|
<head>
|
||
|
|
<meta charset="UTF-8">
|
||
|
|
<title>Registraire — L'Alliance Boréale</title>
|
||
|
|
<link rel="stylesheet" href="style.css">
|
||
|
|
</head>
|
||
|
|
<body>
|
||
|
|
<header>
|
||
|
|
<h1>🌲 L'Alliance Boréale — Registraire Public</h1>
|
||
|
|
<p>Fédération de services numériques éthiques</p>
|
||
|
|
</header>
|
||
|
|
|
||
|
|
<main>
|
||
|
|
<section id="membres">
|
||
|
|
<h2>Membres Actifs ({{ members|length }})</h2>
|
||
|
|
|
||
|
|
<div class="member-grid">
|
||
|
|
{% for member in members %}
|
||
|
|
<article class="member-card">
|
||
|
|
<h3>{{ member.identity.legal_name }}</h3>
|
||
|
|
<p><strong>ID:</strong> {{ member.member_id }}</p>
|
||
|
|
<p><strong>Slug:</strong> {{ member.slug }}</p>
|
||
|
|
<p><strong>Statut:</strong> {{ member.status }}</p>
|
||
|
|
{% if member.label.current %}
|
||
|
|
<p><strong>Label:</strong> {{ member.label.current.level }} ({{ member.label.current.score_global }}/100)</p>
|
||
|
|
{% endif %}
|
||
|
|
<p><a href="{{ member.identity.website }}">Site web</a></p>
|
||
|
|
</article>
|
||
|
|
{% endfor %}
|
||
|
|
</div>
|
||
|
|
</section>
|
||
|
|
</main>
|
||
|
|
|
||
|
|
<footer>
|
||
|
|
<p>Données source: <a href="https://forge.boreal.ca/alliance/registraire">Git</a></p>
|
||
|
|
<p>Licence: CC BY-SA 4.0</p>
|
||
|
|
</footer>
|
||
|
|
</body>
|
||
|
|
</html>
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 5.2 API REST (Optionnel)
|
||
|
|
|
||
|
|
**Concept :** Exposer données via API REST (lecture seule).
|
||
|
|
|
||
|
|
**URL :** `https://api.registraire.alliance-boreale.ca`
|
||
|
|
|
||
|
|
**Endpoints :**
|
||
|
|
```
|
||
|
|
GET /members → Liste membres actifs
|
||
|
|
GET /members/{id} → Fiche membre détaillée
|
||
|
|
GET /members/{id}/label → Label actuel
|
||
|
|
GET /labels → Tous les labels actifs
|
||
|
|
GET /decisions → Décisions publiques
|
||
|
|
GET /stats → Statistiques agrégées
|
||
|
|
```
|
||
|
|
|
||
|
|
**Technologie :** FastAPI (Python) ou Express (Node.js).
|
||
|
|
|
||
|
|
**Réponse JSON (exemple) :**
|
||
|
|
```json
|
||
|
|
GET /members/m001
|
||
|
|
|
||
|
|
{
|
||
|
|
"member_id": "m001",
|
||
|
|
"slug": "chezlepro",
|
||
|
|
"status": "active",
|
||
|
|
"identity": {
|
||
|
|
"legal_name": "Chez le Pro Technologies Inc.",
|
||
|
|
"website": "https://chezle.pro"
|
||
|
|
},
|
||
|
|
"label": {
|
||
|
|
"level": "gold",
|
||
|
|
"score_global": 82,
|
||
|
|
"issued_date": "2025-10-01",
|
||
|
|
"valid_until": "2026-10-01"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Avantages :**
|
||
|
|
- Intégration facilitée (scripts, apps)
|
||
|
|
- Versioning API (v1, v2)
|
||
|
|
- Rate limiting (prévention abus)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## SECTION 6 : SÉCURITÉ ET PERMISSIONS
|
||
|
|
|
||
|
|
### 6.1 Accès en Lecture (Public)
|
||
|
|
|
||
|
|
**Qui :** Tout le monde (internet public).
|
||
|
|
|
||
|
|
**Quoi :**
|
||
|
|
- Fiches membres (infos publiques)
|
||
|
|
- Décisions publiées
|
||
|
|
- Labels attribués
|
||
|
|
- Zones DNS publiques
|
||
|
|
|
||
|
|
**Comment :** Git clone (HTTPS), site web, API.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 6.2 Accès en Écriture (Restreint)
|
||
|
|
|
||
|
|
**Qui :**
|
||
|
|
- Membres actifs (modification de LEUR fiche uniquement)
|
||
|
|
- Cercle Opérationnel (modification toutes fiches + gouvernance)
|
||
|
|
- Cercle Éthique (modification labels)
|
||
|
|
|
||
|
|
**Authentification :** SSH keys + GPG signing.
|
||
|
|
|
||
|
|
**Permissions Git :**
|
||
|
|
```
|
||
|
|
# Exemple .gitignore permissions (conceptuel, pas standard Git)
|
||
|
|
membres/m001-*.yml → Éditable par m001 + Cercle Ops
|
||
|
|
membres/m002-*.yml → Éditable par m002 + Cercle Ops
|
||
|
|
gouvernance/* → Éditable par Cercle Stratégique + Ops
|
||
|
|
labels/* → Éditable par Cercle Éthique uniquement
|
||
|
|
dns/* → Éditable par Cercle Ops uniquement
|
||
|
|
```
|
||
|
|
|
||
|
|
**Implémentation réelle :** Forge (GitLab/Gitea) avec roles et protected branches.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 6.3 Audit Trail (Traçabilité)
|
||
|
|
|
||
|
|
**Git = Audit trail natif :**
|
||
|
|
- Chaque commit = auteur, date, message
|
||
|
|
- Signature GPG = authentification cryptographique
|
||
|
|
- Historique complet (`git log`)
|
||
|
|
|
||
|
|
**Exemple :**
|
||
|
|
```bash
|
||
|
|
git log --oneline --graph membres/m001-chezlepro.yml
|
||
|
|
|
||
|
|
* a3b4c5d (HEAD -> main) feat(m001): Update Matrix federation URL
|
||
|
|
* 9f8e7d6 feat(m001): Add Gold label (Q4 2025)
|
||
|
|
* 2c3d4e5 fix(m001): Correct technical contact email
|
||
|
|
* 1a2b3c4 feat: Add member m001 (Chez le Pro)
|
||
|
|
```
|
||
|
|
|
||
|
|
**Requêtes utiles :**
|
||
|
|
```bash
|
||
|
|
# Qui a modifié quoi ?
|
||
|
|
git log --all --author="jean@chezle.pro"
|
||
|
|
|
||
|
|
# Quand ce champ a-t-il changé ?
|
||
|
|
git log -p -S "mail.chezlepro.boreal.ca" membres/m001-chezlepro.yml
|
||
|
|
|
||
|
|
# Liste des commits entre deux dates
|
||
|
|
git log --since="2025-10-01" --until="2025-10-31"
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## CONCLUSION
|
||
|
|
|
||
|
|
Le Registraire YAML est **simple mais puissant** :
|
||
|
|
|
||
|
|
✅ **Lisible** : N'importe qui peut lire un fichier YAML
|
||
|
|
✅ **Versionné** : Git track tous les changements
|
||
|
|
✅ **Validé** : Schemas + CI/CD garantissent cohérence
|
||
|
|
✅ **Auditable** : Historique complet, signatures GPG
|
||
|
|
✅ **Extensible** : Facile d'ajouter champs (rétrocompatible)
|
||
|
|
✅ **Distribué** : Chaque membre peut cloner
|
||
|
|
✅ **Machine-readable** : Scripts, Ansible, APIs
|
||
|
|
|
||
|
|
**Ce n'est pas une base de données relationnelle complexe. C'est mieux : c'est Git.**
|
||
|
|
|
||
|
|
La complexité ne vient pas de l'outil, mais de la rigueur des processus. Avec des conventions claires, des reviews systématiques, et des tests automatiques, le Registraire devient la colonne vertébrale informationnelle de L'Alliance.
|
||
|
|
|
||
|
|
**Bienvenue dans le registraire boréal.** 🌲
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## ANNEXES
|
||
|
|
|
||
|
|
### Annexe A : Exemple Membre Complet (m002)
|
||
|
|
|
||
|
|
**Fichier : `membres/m002-technolibre.yml`**
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
---
|
||
|
|
member_id: m002
|
||
|
|
slug: technolibre
|
||
|
|
status: active
|
||
|
|
|
||
|
|
identity:
|
||
|
|
legal_name: "TechnoLibre SENC"
|
||
|
|
legal_form: coop
|
||
|
|
jurisdiction: QC
|
||
|
|
registration_number: "9876543210"
|
||
|
|
website: "https://technolibre.ca"
|
||
|
|
joined_alliance_date: "2025-02-01"
|
||
|
|
probation_end_date: null
|
||
|
|
description: |
|
||
|
|
TechnoLibre est une coopérative de développeurs offrant du développement
|
||
|
|
logiciel sur mesure et de l'hébergement souverain. Spécialisés en Odoo
|
||
|
|
et Python/Django.
|
||
|
|
|
||
|
|
contacts:
|
||
|
|
primary:
|
||
|
|
name: "Sophie Lavoie"
|
||
|
|
role: "Présidente"
|
||
|
|
email: "sophie@technolibre.ca"
|
||
|
|
phone: "+1-418-555-0200"
|
||
|
|
matrix: "@sophie:matrix.technolibre.boreal.ca"
|
||
|
|
|
||
|
|
technical:
|
||
|
|
name: "Marc Dubois"
|
||
|
|
role: "Lead DevOps"
|
||
|
|
email: "marc@technolibre.ca"
|
||
|
|
matrix: "@marc:matrix.technolibre.boreal.ca"
|
||
|
|
|
||
|
|
security:
|
||
|
|
email: "security@technolibre.ca"
|
||
|
|
pgp_key: "0xABCDEF1234567890"
|
||
|
|
|
||
|
|
infrastructure:
|
||
|
|
hosting:
|
||
|
|
provider: "OVH France"
|
||
|
|
datacenter_location: "Strasbourg, France"
|
||
|
|
owned: false
|
||
|
|
|
||
|
|
network:
|
||
|
|
ipv4_public:
|
||
|
|
- "198.51.100.20/32"
|
||
|
|
ipv4_private: "10.2.0.0/16"
|
||
|
|
|
||
|
|
dns:
|
||
|
|
primary_ns: "ns1.technolibre.boreal.ca"
|
||
|
|
secondary_ns: "ns2.technolibre.boreal.ca"
|
||
|
|
ns_ips:
|
||
|
|
ns1: "198.51.100.20"
|
||
|
|
ns2: "198.51.100.21"
|
||
|
|
dnssec_enabled: false
|
||
|
|
|
||
|
|
services:
|
||
|
|
email:
|
||
|
|
enabled: true
|
||
|
|
domain: "technolibre.ca"
|
||
|
|
mx_records:
|
||
|
|
- priority: 10
|
||
|
|
host: "mail.technolibre.boreal.ca"
|
||
|
|
protocols: [smtp, imap]
|
||
|
|
security:
|
||
|
|
dkim: true
|
||
|
|
spf: true
|
||
|
|
dmarc: true
|
||
|
|
|
||
|
|
cloud_storage:
|
||
|
|
enabled: true
|
||
|
|
platform: nextcloud
|
||
|
|
url: "https://cloud.technolibre.boreal.ca"
|
||
|
|
|
||
|
|
status_page:
|
||
|
|
enabled: true
|
||
|
|
url: "https://status.technolibre.boreal.ca"
|
||
|
|
platform: cachet
|
||
|
|
|
||
|
|
standards:
|
||
|
|
open_source_percentage: 95
|
||
|
|
protocols_supported: [smtp, imap, caldav, carddav, webdav]
|
||
|
|
compliance:
|
||
|
|
loi_25: true
|
||
|
|
rgpd: true
|
||
|
|
|
||
|
|
label:
|
||
|
|
current:
|
||
|
|
level: silver
|
||
|
|
score_global: 70
|
||
|
|
issued_date: "2025-06-01"
|
||
|
|
valid_until: "2026-06-01"
|
||
|
|
audited_by: "m001"
|
||
|
|
|
||
|
|
participation:
|
||
|
|
cercles:
|
||
|
|
- name: "Cercle Stratégique"
|
||
|
|
role: "membre"
|
||
|
|
since: "2025-02-01"
|
||
|
|
|
||
|
|
metadata:
|
||
|
|
created_at: "2025-02-01T09:00:00Z"
|
||
|
|
updated_at: "2025-10-20T11:15:00Z"
|
||
|
|
version: 2
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Annexe B : Schéma Décision
|
||
|
|
|
||
|
|
**Fichier : `schemas/decision.schema.json` (extrait)**
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||
|
|
"title": "Décision de Gouvernance",
|
||
|
|
"type": "object",
|
||
|
|
"required": ["decision_id", "date", "circle", "type", "outcome"],
|
||
|
|
"properties": {
|
||
|
|
"decision_id": {
|
||
|
|
"type": "string",
|
||
|
|
"pattern": "^[0-9]{4}-[0-9]{3}$",
|
||
|
|
"description": "Format: YYYY-NNN"
|
||
|
|
},
|
||
|
|
"date": { "type": "string", "format": "date" },
|
||
|
|
"circle": {
|
||
|
|
"type": "string",
|
||
|
|
"enum": ["strategic", "operational", "ethics", "referents"]
|
||
|
|
},
|
||
|
|
"type": {
|
||
|
|
"type": "string",
|
||
|
|
"enum": ["admission", "policy", "budget", "label", "amendment", "other"]
|
||
|
|
},
|
||
|
|
"outcome": {
|
||
|
|
"type": "string",
|
||
|
|
"enum": ["approved", "rejected", "amended"]
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Annexe C : Commandes Utiles
|
||
|
|
|
||
|
|
**Recherche membre par slug :**
|
||
|
|
```bash
|
||
|
|
grep -l "slug: chezlepro" membres/*.yml
|
||
|
|
```
|
||
|
|
|
||
|
|
**Liste membres actifs :**
|
||
|
|
```bash
|
||
|
|
grep -l "status: active" membres/*.yml | wc -l
|
||
|
|
```
|
||
|
|
|
||
|
|
**Extraction infos avec `yq` :**
|
||
|
|
```bash
|
||
|
|
# Installer: apt install yq
|
||
|
|
yq eval '.identity.legal_name' membres/m001-chezlepro.yml
|
||
|
|
# Output: Chez le Pro Technologies Inc.
|
||
|
|
|
||
|
|
yq eval '.label.current.level' membres/m001-chezlepro.yml
|
||
|
|
# Output: gold
|
||
|
|
```
|
||
|
|
|
||
|
|
**Statistiques labels :**
|
||
|
|
```bash
|
||
|
|
for file in membres/*.yml; do
|
||
|
|
level=$(yq eval '.label.current.level // "none"' "$file")
|
||
|
|
echo "$level"
|
||
|
|
done | sort | uniq -c
|
||
|
|
|
||
|
|
# Output:
|
||
|
|
# 5 gold
|
||
|
|
# 8 silver
|
||
|
|
# 3 bronze
|
||
|
|
# 2 none
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## MÉTADONNÉES
|
||
|
|
|
||
|
|
**Document :** 14_Structure_YAML_Registraire.md
|
||
|
|
**Version :** 1.0
|
||
|
|
**Date de création :** 23 octobre 2025
|
||
|
|
**Auteur :** Claude (profils #5 IaC, #12 Documentaliste)
|
||
|
|
**Révision par :** Cercle Opérationnel
|
||
|
|
**Statut :** À adopter par Cercle Stratégique
|
||
|
|
**Longueur :** ~6 000 mots (12 pages)
|
||
|
|
**Licence :** CC BY-SA 4.0
|
||
|
|
|
||
|
|
**Sources utilisées :**
|
||
|
|
- `00_Glossaire_et_Definitions.md`
|
||
|
|
- `05_Architecture_Reference_Standards_Techniques.md`
|
||
|
|
- `03_Cadre_Conformite_Label_Prestige.md`
|
||
|
|
- `devis_alliance_boreale_v2.md`
|
||
|
|
|
||
|
|
**Prochaine révision prévue :** Octobre 2026 (après 1 an d'usage)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
**Changelog :**
|
||
|
|
- 2025-10-23 v1.0 : Création initiale Structure YAML Registraire
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
**FIN DE LA STRUCTURE YAML**
|
||
|
|
|
||
|
|
*"La donnée bien structurée est la moitié du travail accompli."*
|
||
|
|
|
||
|
|
🌲 **L'Alliance Boréale**
|
||
|
|
*YAML + Git = Source de vérité vivante.*
|