diff --git a/CHANGELOG.md b/CHANGELOG.md index 013e2e4..d4eb661 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,39 @@ # CHANGELOG — Set-OPS +## 2026-08-09 — La reconstruction from-zero est prouvée : cinq devis sur cinq + +Écosystème `chezlepro` détruit — 14 VM, disques compris — puis **rejoué depuis le plan +seul**. Aucune sauvegarde restaurée. Les cinq devis rendent le même verdict qu'avant la +destruction, et `docs/audit/reference-avant-reconstruction-2026-08-08.md` porte les deux +états côte à côte pour que « identique » soit vérifiable et non ressenti. + +C'est la première fois que le dépôt peut affirmer que le **système reconstruit est celui +que le plan décrit**, au lieu d'affirmer que le dépôt est cohérent avec lui-même. + +**Six défauts trouvés, tous invisibles autrement** — trois d'ordre, deux de course, un +conflit de port. Chacun a fait l'objet de son propre commit ; ce qu'ils ont en commun +mérite d'être dit : **ils dormaient tous derrière un état préexistant.** Un compte qui +existait déjà, des rôles créés par un passage antérieur, des clients déjà là, un service +qui tournait depuis toujours, un port déjà tenu. Le rejeu n'a rien cassé — il a retiré +l'état qui masquait. + +Le sixième est le plus instructif. Alloy et le SASL de Dovecot revendiquent tous deux le +port 12345 sur `infra-mail-01`. Le conflit existait depuis le premier jour, mais dans +l'autre sens : Alloy tenait le port et c'est **l'écoute SASL de Dovecot qui échouait, en +silence**. L'ordre des couches d'une reconstruction a inversé les rôles et rendu le défaut +audible. Le port d'Alloy est désormais **imposé et déclaré** — le vrai défaut n'était pas +le numéro, c'était qu'un port *subi* ne se déclare nulle part, donc qu'aucun contrôle ne +pouvait voir la collision. + +**Ce qu'il reste à construire, et que ce rejeu a rendu évident :** + +- une preuve « tout intrant qu'un rôle **exige** est fourni par l'instance » — le défaut + nº 1 se serait vu sans détruire quoi que ce soit ; +- une preuve « deux rôles co-localisés ne revendiquent pas le même port » — maintenant que + les ports subis se déclarent, elle devient possible ; +- vider `/etc/resolv.conf` à la capture du gabarit doré : il transporte encore le + résolveur de son réseau de fabrication. + ## 2026-08-08 — D-71 éprouvée : l'AC et le DNS montent seuls, sur des machines neuves Première exécution de `_amorcer-socle` sur une flotte qui vient d'être clonée, aucun pair diff --git a/docs/audit/preuve-2026-08-09.md b/docs/audit/preuve-2026-08-09.md index fea81cf..1a863dd 100644 --- a/docs/audit/preuve-2026-08-09.md +++ b/docs/audit/preuve-2026-08-09.md @@ -7,7 +7,7 @@ > [`docs/audit/affirmations.md`](affirmations.md). - **Instance** : `instance` — inventaire `instance/inventories/principal/hosts.yml` -- **Verdict** : ✅ CONFORME (31 OK · 0 echec · 0 saute) +- **Verdict** : ✅ CONFORME (30 OK · 0 echec · 1 saute) ## Preuves @@ -28,9 +28,9 @@ | P13 | Invariants structurels/doctrinaux | AFF-015, AFF-022, AFF-037, AFF-038, AFF-062 | ✅ OK | LICENSE, socle dossier, pas de couches paralleles, SSH clef-only, nftables off : OK. | | P14 | Pas de chemin lab/ code en dur | AFF-097 | ✅ OK | Aucun chemin instance/inventories/lab/group_vars code en dur. | | P15 | Modele public socle valide | AFF-022, AFF-099 | ✅ OK | Modele public socle : domaines/serveurs/applications/bases valides. | -| P16 | Inventaire Ansible complet (--list) | AFF-030 | ✅ OK | 14 hotes, 31 groupes (inventaire dechiffre et parse). | +| P16 | Inventaire Ansible complet (--list) | AFF-030 | ⚪ SAUTE | Voute chiffree sans ANSIBLE_VAULT_PASSWORD_FILE (prerequis AFF-026). | | P17 | Tous les modeles valident (registres + underlay) | AFF-022, AFF-099 | ✅ OK | Les 1 modele(s) decouvert(s) valident. | -| P18 | Gabarit de voute complet | AFF-026 | ✅ OK | Gabarit de voute complet : 25 secret(s) exige(s), tous presents. Voute reelle : 28 cle(s), aucun manque. | +| P18 | Gabarit de voute complet | AFF-026 | ✅ OK | Gabarit de voute complet : 25 secret(s) exige(s), tous presents. (Voute reelle non lisible ici : verification sautee.) | | P19 | Le GUI couvre le schema du plan | AFF-002, AFF-095 | ✅ OK | GUI : les 28 champ(s) des plans reels sont editables (2 plan(s) inspecte(s)), registres toleres : nomenclature. | | P20 | Adressage 100% derive du seed (aucun stocke) | AFF-001, AFF-003 | ✅ OK | 2 nomenclature(s) : adressage 100% derive du seed index. | | P21 | Federation : aucun index en collision | AFF-102 | ✅ OK | Federation coherente : 2 instance(s) federee(s), aucun index en collision. | diff --git a/docs/audit/reference-avant-reconstruction-2026-08-08.md b/docs/audit/reference-avant-reconstruction-2026-08-08.md index 0fad195..a90d177 100644 --- a/docs/audit/reference-avant-reconstruction-2026-08-08.md +++ b/docs/audit/reference-avant-reconstruction-2026-08-08.md @@ -42,3 +42,50 @@ web-frontal-01 10.27.21.31 2 service(s) metier > Ce qui **survit** : les deux voûtes et `~/.config/setops-vault-pass` vivent hors dépôt > et hors cluster ; le code est sur `eregion.chezlepro.ca` (192.168.12.201), machine > distincte du tenant. Rien de ce qui est nécessaire au rejeu n'est dans les 14 VM. + + +--- + +## Après reconstruction — 2026-08-09 + +Écosystème détruit (14 VM, disques compris) puis **rejoué depuis le plan seul**. Aucune +sauvegarde restaurée : ni LDAP, ni base, ni certificat, ni fichier. + +``` +identite CONFORME +certificats CONFORME +expositions CONFORME +postgresql CONFORME +courriel CONFORME +``` + +**Cinq sur cinq, identiques à la référence.** C'est la première fois que le dépôt peut dire +que le système reconstruit est celui que le plan décrit — au lieu de dire que le dépôt est +cohérent avec lui-même. + +### Les six défauts que seul un rejeu depuis zéro pouvait montrer + +| # | Défaut | Pourquoi il dormait | +|---|---|---| +| 1 | `amorcage_acces_courriel` jamais déclaré par le tenant | le compte existait déjà, le garde-fou n'avait jamais eu à se déclencher | +| 2 | rôles de realm créés **après** leur attachement aux groupes | un passage précédent les avait créés | +| 3 | claim de groupes posé **avant** les clients OIDC | les clients existaient déjà | +| 4 | écriture Keycloak annulée par le collecteur de transactions | la synchro LDAP complète ne se rejoue pas en exploitation | +| 5 | `grafana-cli` lancé avant que Grafana ait fini de démarrer | le service tournait depuis toujours | +| 6 | port d'Alloy (12345) en collision avec le SASL de Dovecot | Alloy tenait le port ; c'est **Dovecot** qui échouait, en silence | + +Trois défauts d'ordre, deux courses de premier démarrage, un conflit de port. **Aucun +n'était visible à un redéploiement**, et aucun aux 31 preuves statiques — elles lisent le +dépôt, pas la machine. + +Le sixième mérite d'être relu : le conflit existait depuis toujours, mais dans l'autre +sens. Alloy tenait `12345` et l'écoute SASL de Dovecot échouait sans que personne ne le +voie. La reconstruction a inversé l'ordre de démarrage et rendu visible un défaut qui +était là depuis le début. + +### Ce qui a dû être refait à la main + +- **La base de Grafana** : le premier démarrage, interrompu par le défaut nº 5, avait + laissé un schéma à moitié migré (`no such column: with_credentials`). Base mise de côté, + recréée par Grafana — 95 s pour lier son port, ce qui explique la course. +- **Rien d'autre.** Ni certificat, ni compte, ni zone DNS, ni base de données.