35 KiB
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 :
- Créer branche :
git checkout -b feature/add-member-m004 - Modifier fichier(s) : Éditer
membres/m004-nouveau.yml - Commit :
git commit -m "feat: Add member m004 (Nouveau OBNL)" - Push :
git push origin feature/add-member-m004 - Ouvrir Pull Request sur Forge
- Review : 1+ membre (vérification conformité)
- CI/CD : Tests automatiques (yamllint, schema validation)
- 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
# ============================================================================
# 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_idslugstatusidentity.legal_nameidentity.legal_formidentity.joined_alliance_datecontacts.primary(name, email)contacts.technical.emailcontacts.security.emailinfrastructure.dns.primary_nsservices.status_page.url
Recommandés (warning si absent) :
identity.websiteinfrastructure.dns.dnssec_enabledservices.email(si service email offert)standards.open_source_percentagelabel.current(si labellisé)
Optionnels (sans warning) :
infrastructure.network.asnstandards.certificationsparticipation.contributionsmetadata.notes
2.3 Valeurs Enum (Contrôlées)
Statut membre (status) :
probation: En période probatoire (3 mois)active: Membre actif confirmésuspended: Suspendu temporairementexited: Sorti de L'Alliance (volontaire ou radiation)
Forme légale (identity.legal_form) :
corporation: Entreprise incorporéecoop: Coopérativenpo: Organisme à but non lucratifsole_proprietorship: Travailleur autonome
Niveau label (label.current.level) :
bronzesilvergoldplatinumnull: Non labellisé
Type contribution (participation.contributions.type) :
code: Contribution code (forge)documentation: Rédaction wiki/runbooksmentoring: Parrainage nouveau membreaudit: Audit pair-à-pairgovernance: Participation cercleinfrastructure: Support technique mutuel
SECTION 3 : VALIDATION AUTOMATIQUE
3.1 YAML Lint (Syntaxe)
Outil : yamllint
Configuration : .yamllint
extends: default
rules:
line-length:
max: 120
level: warning
indentation:
spaces: 2
comments:
min-spaces-from-content: 2
document-start:
present: true
Commande :
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
{
"$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 :
# 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)
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 :
#!/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 :
-
Cloner le dépôt
git clone https://forge.boreal.ca/alliance/registraire.git cd registraire -
Créer branche
git checkout -b update/m001-add-matrix-service -
Éditer fiche
vim membres/m001-chezlepro.yml # Ajouter section services.matrix -
Valider localement
yamllint membres/m001-chezlepro.yml ajv validate -s schemas/member.schema.json -d membres/m001-chezlepro.yml -
Commit
git add membres/m001-chezlepro.yml git commit -m "feat(m001): Add Matrix federation service" -
Push et Pull Request
git push origin update/m001-add-matrix-service # Ouvrir PR sur forge.boreal.ca -
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 :
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
mainautorisé (exception) - Notification Matrix #incidents immédiate
- Justification dans commit message
Exemple :
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) :
#!/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 :
<!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) :
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 :
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 :
# 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
---
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)
{
"$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 :
grep -l "slug: chezlepro" membres/*.yml
Liste membres actifs :
grep -l "status: active" membres/*.yml | wc -l
Extraction infos avec yq :
# 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 :
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.md05_Architecture_Reference_Standards_Techniques.md03_Cadre_Conformite_Label_Prestige.mddevis_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.