diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a13261..a317a7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,33 @@ # CHANGELOG — Set-OPS +## 2026-09-27 (1) — Patient 0 effacé, l'index 29 libéré + +Ses machines n'existaient plus depuis le 2026-09-06 (D-83), mais son plan restait sur +disque en `federe: true` : la fédération lui réservait l'index 29, et quatre machines du +site ouvraient SSH, apt, DNS et HTTPS à `10.29.0.0/16` — un périmètre vide. + +**Ce qui est fait :** + +- `SITE-Chezlepro/underlay.yml` : `OPS-Patient0: 29` retiré de `tenants`. +- `SITE-Chezlepro/plan/serveurs.yml` : le runner du site ne clone plus `ops-patient0`. +- `make flux` : `10.29.0.0/16` sort des règles de `site-backup-01`, `site-cache-01`, + `site-dns-01`, `site-dnspub-01` et `site-forge-01` — et rien d'autre ne change. +- Le dépôt local `OPS-Patient0/` est supprimé ; sa copie reste sur `eregion`. +- Les commentaires et documents vivants qui le nommaient gardent leur leçon sans le nommer + (moteur, modèles, tenants, sites). Le CHANGELOG, les rapports de preuve datés et la + chronique restent tels quels : ce sont des archives. +- `filiation-emancipation.md` §« Qui est le parent ? » ramené à la décision et à la dette + qui reste — `eregion`, hors flotte, alimente la forge qui fait autorité. + +**Ce qui n'est pas encore sur le réseau.** Les `.nft` régénérés doivent être posés par le +runner du site. Le SDN (zone `t29`, VLAN 1291-1296), la frontière et le pare-feu Proxmox +n'ont pas pu être relus depuis le poste : le cluster ne répondait pas (22 et 8006). + +**Mesuré en passant.** `make sdn-plan`, cluster injoignable, annonce « à créer : 33 » — +TOUTES les zones, Chezlepro comprise. Il lit un cluster muet comme un cluster vide, là où +`frontiere-plan` refuse de conclure. `make verifier` : 82 OK, 1 échec — P02, +`test_ecriture_plan.py` sur `domaines.yml` (`'list' object has no attribute 'get'`), +présent avant ce changement. ## 2026-09-25 — Le registre disait « mesure » d'une cible qui coupe l'amont **21 preuves sur `test_runbooks.py`, `verifier` à 0 écart.** Un outil tiers veut diff --git a/docs/decisions-architecture.md b/docs/decisions-architecture.md index 2eea413..6601d04 100644 --- a/docs/decisions-architecture.md +++ b/docs/decisions-architecture.md @@ -56,7 +56,7 @@ sont les seules vérifiables. | # | Décision | Pourquoi | Détail | Garde | |---|---|---|---|---| | **D-82** | **Patient 0 n'est le parent de personne.** Il est la **mise en œuvre de référence** du modèle `origine` — le plus petit écosystème complet — et un pair de la famille du génome, pas sa racine | trois faits l'ont retiré un par un : D-81 a donné l'autorité du génome à la forge du SITE (son dernier lecteur corrigé le 2026-08-26, Technolibre le 08-31) ; le dénominateur commun vit dans les modèles depuis le 08-24 ; et **l'ancêtre était locataire de son enfant** — index 29 sur la fabric de `SITE-Chezlepro`, qui descend de lui. Ce qu'il devait éliminer — le SPOF `eregion`, hors flotte — n'a PAS été éliminé mais **promu** : le poste y pousse, la forge du site en tire. Cette dette appartient désormais au SITE, et la nommer est le minimum : *un objectif qu'on abandonne sans le dire devient un objectif qu'on croit atteint* | `OPS-Patient0/README.md`, `docs/filiation-emancipation.md` | — | -| **D-83** | **Patient 0 a été retiré** — ses machines n'existent plus (constaté le 2026-09-06) | D-82 lui avait laissé une raison d'être : la mise en œuvre de référence du modèle `origine`, et un **témoin** de plus du génome. Le retrait solde la première et **abaisse la seconde de trois copies vivantes à deux** (`eregion`, la forge du site). Ce qu'il devait éliminer — le SPOF `eregion` — reste entier, et sans lui il n'y a plus de miroir indépendant pour l'absorber. **Son plan reste sur disque et la fédération lui réserve toujours l'index 29** : tant que ce n'est pas tranché, le site ouvre SSH, apt, DNS et HTTPS à `10.29.0.0/16` — un périmètre vide | `OPS-Patient0/`, `SITE-Chezlepro/flux-genere/` | **P21** (index), **P23** | +| **D-83** | **Patient 0 a été retiré** — ses machines n'existent plus (constaté le 2026-09-06) | D-82 lui avait laissé une raison d'être : la mise en œuvre de référence du modèle `origine`, et un **témoin** de plus du génome. Le retrait solde la première et **abaisse la seconde de trois copies vivantes à deux** (`eregion`, la forge du site). Ce qu'il devait éliminer — le SPOF `eregion` — reste entier, et sans lui il n'y a plus de miroir indépendant pour l'absorber. **Son plan a été effacé le 2026-09-27** : l'index 29 est libéré, et le site n'ouvre plus rien à `10.29.0.0/16` | `SITE-Chezlepro/underlay.yml` (`tenants`), `SITE-Chezlepro/flux-genere/` | **P21** (index), **P23** | | **D-84** | **Le plan de contrôle reste gelé — c'est la CARTE DES SEUILS qui était fausse** | La question « et si on retirait le gel ? » a mis à l'épreuve les cinq seuils de `positionnement.md`, et deux ne tenaient pas. **RBAC** : couvert depuis que trois classes d'acteurs aux pouvoirs disjoints existent — poste, runner de site, runners de tenant — séparés **cryptographiquement** (une voûte, une clé, 2026-08-28) et non par une table de permissions qu'une faille applicative contournerait ; adopter AWX pour ce besoin serait **régresser**. **IPAM** : sans objet par construction — rien ne s'alloue, tout dérive du seed, et P20/P21/P23/P28/P33 tiennent déjà ce qu'un IPAM vérifierait *a posteriori*. Les deux lignes sont retirées du tableau : les garder aurait fait adopter un outil pour un besoin déjà rempli. **Et un seuil manquait** — l'**émancipation** : le GUI est mono-utilisateur (`127.0.0.1` + jeton), or la trajectoire mène à plusieurs humains aux portées disjointes, sur des machines qui ne sont pas les nôtres. Ce seuil n'appelle pas AWX, il appelle une décision non prise. *Un seuil qu'on ne nomme pas est un seuil qu'on franchit sans le voir.* Corollaire consigné : le gel porte sur les **fonctions**, jamais sur les **vues** — montrer à l'écran ce que le moteur sait déjà ne franchit aucun seuil | `positionnement.md` §3, §4, §5 | — | | **D-85** | **cloud-init naît avec la VM et ne lui survit pas** | cloud-init n'est pas un logiciel d'installation : c'est une **source de vérité externe**, qui se réveille à *chaque* démarrage et relit le lecteur attaché par l'hyperviseur — lequel peut redéfinir comptes, clés SSH autorisées, mots de passe et réseau. Sur une machine que le plan possède, c'est un **second maître** : le plan ne le décrit pas, `make valider` ne le mesure pas, et il parle en premier. Sa tâche est pourtant finie à la première seconde — c'est parce qu'il a **réussi** à poser l'adresse et les clés qu'Ansible a pu entrer. **Trois moitiés, qui se défont séparément** : le **gabarit** le garde (sans lui un clone ne naît pas — P56) ; le **socle** ne l'installe plus (le garder produisait un va-et-vient à chaque déploiement : le socle installe, le durcissement retire, deux `changed` par passage) ; le **durcissement** le retire (`cloud_init_retrait`, en dernier). **Ce qui rend le retrait sûr est mesuré, pas supposé** (2026-09-09, `obs-01`) : `/etc/network/interfaces.d/50-cloud-init` n'appartient à aucun paquet — `dpkg -S` ne le trouve pas — et le `postrm` ne le nomme jamais, même en `purge`. L'adresse survit. Le rôle le **vérifie** malgré tout, avant et après : une VM qui perd ce fichier ne se plaint pas, elle repart sans adresse et plus personne ne peut entrer pour le constater. **⚠ CE QUE CETTE DÉCISION NE FERME PAS — et il faut le dire, sinon elle se lit comme une émancipation qu'elle n'est pas.** Retirer cloud-init **n'ôte aucun pouvoir à l'hébergeur**. `qemu-guest-agent` est au gabarit (P56 : il doit y être — c'est par lui que `creer-vm` confirme la matérialisation sans entrer chez le tenant), et l'API Proxmox expose sur son dos, sur toute VM vivante de la flotte, un pouvoir **strictement plus grand** que le lecteur cloud-init : `exec`, `file-write`, `file-read`, `set-user-password`, `shutdown` (relevé le 2026-09-09 sur `edge-mta-01`, jeton d'API du site). Ce que D-85 ferme est donc **précis et étroit** : (a) une réapplication **automatique, à chaque démarrage**, depuis un support que le plan ne possède pas et qu'aucune preuve ne lit ; (b) le code de cloud-init lui-même — un interpréteur Python complet, exécuté en root au démarrage, et ses ~29 dépendances. Elle ne ferme **pas** la mainmise de l'hyperviseur sur ses invités : celle-là est une propriété de la virtualisation, pas de cloud-init, et elle appelle sa propre décision — non prise. **Le seuil où le remplacer deviendrait juste** : le jour où une première seconde ne peut plus être amorcée par Proxmox (autre hyperviseur, métal nu, hébergeur sans API), le chemin par l'agent invite cesse d'être une réimplémentation d'un standard — que `positionnement.md` interdit — et devient **le chemin portable**. Tant que ce seuil n'est pas atteint, écrire soi-même l'amorçage serait échanger un standard éprouvé contre du code maison au moment le plus fragile, dont le mode de panne est le pire : une VM injoignable | `roles/cloud_init_retrait/`, `serveur_durci.yml`, `positionnement.md` | **P63** | | **D-86** | **La supervision se déploie juste après la PKI, pas à la fin** | L'observabilité (`prometheus`, `loki`, `grafana`) et le **moteur** de supervision (`icinga`) passent en couche 4, immédiatement après `client_pki` ; les agents qui les nourrissent (`client_metrique`, `client_journal`, `client_sante`) en couche 5. **Le raisonnement** : ce qui se déploie ensuite l'est *sous l'œil* de la supervision — une unité qui casse se voit à la minute, pas à la fin. Une **reconstruction depuis zéro** est précisément le moment où l'on a le plus besoin de voir, et c'était le seul moment où l'on ne voyait rien. **Déplacer les serveurs sans les agents n'aurait rien changé** : ce sont les agents qui rapportent, et ils étaient en dernière couche. **Ce que ça a coûté en dépendances** : `serveur_postgresql` monte aussi (il n'exige rien lui-même, et `icinga` l'exige). **Ce qui reste tard, à dessein** : `icingaweb2` et `oauth2_proxy` réclament LDAP et Keycloak — c'est la CONSOLE, pas la mesure. L'interface humaine peut attendre. **Limite dite franchement** : les *notifications* dépendent de `client_smtp`, encore en dernière couche — pendant une reconstruction, l'état est mesuré et consultable, mais rien ne part par courriel avant la fin. **CE QUI REND CE DÉPLACEMENT POSSIBLE**, et qui n'est pas un détail : le DNS (`powerdns`, `resolveur`) reste en couche 6, donc *après* la supervision. Or `icinga` joint sa base par un **nom** (`data-sql-01.chezlepro.internal`), et `client_sante` pousse vers un **nom**. Ça tient parce que le **plancher `/etc/hosts`**, posé dès la couche 1 par `hosts_statiques`, porte déjà les 34 entrées de l'écosystème — vérifié. C'est exactement ce pour quoi il existe : *« il ne s'installe pas, il rend installable »*. Sans lui, cette décision serait impossible. **P08** valide l'ordre : aucune arête en arrière | `docs/couches-deploiement.yml`, `catalogue-services.md` §Ordre | **P08** | diff --git a/docs/filiation-emancipation.md b/docs/filiation-emancipation.md index 036b43d..18d31c7 100644 --- a/docs/filiation-emancipation.md +++ b/docs/filiation-emancipation.md @@ -14,7 +14,7 @@ Jusqu'ici, le moteur a rencontré ce besoin **trois fois sans le nommer** : ``` client_artefacts_actif dérivé : « une source existe-t-elle chez moi ? » serveur_ops_forge_externe « je lis mon génome ailleurs » -client_backup_cible patient 0 sauvegarde chez eregion — mutualisé, en production +client_backup_cible « je sauvegarde chez le site » — mutualisé, en production ``` Trois astuces, une seule notion. Ce document la déclare. @@ -239,29 +239,14 @@ déclarer du tout. ## Qui est le parent ? — tranché le 2026-08-31 (D-82) -Le dilemme est resté ouvert trois jours. Les faits l'ont tranché plus que le raisonnement : -**personne n'est le parent, et la forge du SITE est l'autorité.** +**Personne. La forge du SITE fait autorité pour le génome** (D-81) ; toute autre copie est +un miroir. Le dépôt l'avait suivi avant de le déclarer : `serveur_forge_site`, puis +`serveur_cache_site`, puis `serveur_resolveur_site` — trois services prêtés par le site à +ses locataires, un seul patron. -Trois issues avaient été posées. C'est la deuxième qui l'emporte, non parce qu'elle était -la plus élégante, mais parce que les deux autres avaient cessé d'être disponibles : - -- **patient 0 redevient la source** — impossible sans le rendre atteignable depuis *tout* - site, alors qu'il vit dans la fabric d'un seul, en locataire de son propre descendant ; -- **le SITE est la source** ✔ — c'est ce que D-81 avait déjà fait, et que le reste du dépôt - a suivi sans qu'on le déclare : `serveur_forge_site`, puis `serveur_cache_site`, puis - `serveur_resolveur_site`. Trois services prêtés, un seul patron ; -- **une famille de pairs** — reste vraie *pour la redondance*. C'est ce que patient 0 - gardait : un miroir du génome, comme chaque écosystème. Il perdait le rang, pas la place. - -> **Il a perdu la place aussi : ses machines n'existent plus (2026-09-06).** La famille du -> génome compte donc **deux** copies vivantes au lieu de trois — `eregion` et la forge du -> site. Or c'est précisément le raisonnement ci-dessus qui portait tout : *on n'échappe pas -> à la boucle par la ruse, mais par le nombre.* Le nombre a baissé, et le SPOF que patient 0 -> devait absorber (`eregion`, hors flotte) est toujours là. - -**Ce que ça ne règle pas.** Le point unique de défaillance que patient 0 devait éliminer — -`eregion`, hors flotte — n'a pas disparu : il alimente maintenant l'autorité. La dette a -changé de propriétaire, pas de nature. Elle appartient au SITE. +**Ce que ça ne règle pas.** La forge qui fait autorité est alimentée depuis `eregion`, hors +flotte — que Set-OPS ne déploie, ne sauvegarde ni ne prouve. Le génome compte deux copies +vivantes : `eregion` et la forge du site. Cette dette appartient au SITE. ## État — revu le 2026-09-06 diff --git a/docs/frontiere-physique-virtuel.md b/docs/frontiere-physique-virtuel.md index e762af4..503e555 100644 --- a/docs/frontiere-physique-virtuel.md +++ b/docs/frontiere-physique-virtuel.md @@ -32,8 +32,8 @@ qu'on touche à son plan — c'est ce qui rend la portabilité possible. > **Un tenant ne détient jamais un secret du monde physique.** -Chaque tenant a porté dans sa voûte le jeton d'API du cluster — patient 0 a dû le recopier -pour exister. C'était exactement la faute des **neuf copies** de la résolution d'instance, +Chaque tenant a porté dans sa voûte le jeton d'API du cluster — chaque nouveau tenant devait le +recopier pour exister. C'était exactement la faute des **neuf copies** de la résolution d'instance, appliquée aux secrets : une valeur qui vit à N endroits finit par diverger, et on ne peut plus révoquer l'une sans révoquer les autres. diff --git a/docs/multi-instances.md b/docs/multi-instances.md index be53df3..c9ec1a4 100644 --- a/docs/multi-instances.md +++ b/docs/multi-instances.md @@ -54,7 +54,6 @@ make instances OPS-Chezlepro-lab 13 1131-1136 LOCAL non * OPS-Chezlepro 17 1171-1176 oui oui OPS-Technolibre 23 1231-1236 oui non - OPS-Patient0 29 1291-1296 oui ? * = instance active (symlink 'instance'). Basculer : make instance-utiliser NOM= ``` diff --git a/docs/positionnement.md b/docs/positionnement.md index 0cb573f..3e88354 100644 --- a/docs/positionnement.md +++ b/docs/positionnement.md @@ -48,7 +48,7 @@ Raisons assumées : Ce document a longtemps écrit « ~13 VM ». Le moteur pilote aujourd'hui **quatre plans vivants** (mesuré le 2026-09-06) : Chezlepro 14 VM, Technolibre 15, le lab 15, plus les 7 machines du site — **51 VM déclarées**, réparties sur des écosystèmes qui ne se parlent - pas. *(Patient 0 en portait 5 ; ses machines n'existent plus.)* Ça reste très loin de l'échelle entreprise pour laquelle NetBox est fait, + pas. Ça reste très loin de l'échelle entreprise pour laquelle NetBox est fait, et le seuil du §4 n'est pas franchi. Mais la courbe monte : c'est **le** chiffre à regarder quand on se demande si la décision tient encore. 3. **Modèle sur-mesure** — NetBox exprimerait nos DSN / expositions à coups de diff --git a/docs/remise-au-client.md b/docs/remise-au-client.md index 82082c3..16e7854 100644 --- a/docs/remise-au-client.md +++ b/docs/remise-au-client.md @@ -118,7 +118,7 @@ contenu. - un temps 2 déclaré fait pendant que le plan ne révoque **aucune** clé. Elle ne juge **pas** un écosystème sans registre : tous ne sont pas remis, et beaucoup ne -le seront jamais — le lab, patient 0, l'écosystème de l'hébergeur lui-même. +le seront jamais — le lab, l'écosystème de l'hébergeur lui-même. ## 7. Ce que cette procédure ne couvre pas diff --git a/docs/sortir-les-cles-du-poste.md b/docs/sortir-les-cles-du-poste.md index 3493686..b7ec011 100644 --- a/docs/sortir-les-cles-du-poste.md +++ b/docs/sortir-les-cles-du-poste.md @@ -8,8 +8,7 @@ Le **code** de Set-OPS est répliqué **deux fois** : `eregion` et la forge du site. Les **voûtes chiffrées** y sont aussi. -> **Ce chiffre était trois, et il a baissé sans que rien ne le signale.** Le troisième -> témoin était patient 0 ; ses machines n'existent plus. Un coffre répliqué deux fois reste +> **Ce chiffre était trois, et il a baissé sans que rien ne le signale.** Un coffre répliqué deux fois reste > solide — mais c'est la **redondance du génome** qui a diminué, pas le chiffrement, et > c'est exactement ce que la page *Filiation, signatures & témoins* appelle la vraie mesure > de résistance d'une lignée : combien de copies **vivantes**, sur combien de machines diff --git a/exemples/modeles/socle/inventories/production/group_vars/all/10-intrants.yml b/exemples/modeles/socle/inventories/production/group_vars/all/10-intrants.yml index de22811..1fd0c04 100644 --- a/exemples/modeles/socle/inventories/production/group_vars/all/10-intrants.yml +++ b/exemples/modeles/socle/inventories/production/group_vars/all/10-intrants.yml @@ -22,9 +22,9 @@ identite_realm: "exemple" # `instance` du moteur, en dur. Tout role lisant le plan lisait donc celui de # l'instance POINTEE PAR LE LIEN, et non celle qu'on deploie. # -# CE QUE CA A DONNE. En deployant patient 0 avec `SETOPS_INSTANCE`, le plancher +# CE QUE CA A DONNE. En deployant un autre ecosysteme avec `SETOPS_INSTANCE`, le plancher # /etc/hosts de `ops-01` a recu les FQDN de CHEZLEPRO -- auth.chezlepro.internal, -# forge.chezlepro.internal... -- pointes sur l'edge de patient 0. Un ecosysteme +# forge.chezlepro.internal... -- pointes sur l'edge de l'autre. Un ecosysteme # annoncait les noms d'un autre. Neuf roles lisent cette variable ; le plancher est # simplement celui qui l'a rendu visible. # diff --git a/exemples/modeles/socle/inventories/production/group_vars/serveur_nginx.yml b/exemples/modeles/socle/inventories/production/group_vars/serveur_nginx.yml index 9f77662..29aeb8a 100644 --- a/exemples/modeles/socle/inventories/production/group_vars/serveur_nginx.yml +++ b/exemples/modeles/socle/inventories/production/group_vars/serveur_nginx.yml @@ -4,8 +4,8 @@ # Sans ce fichier, `client_pki` n'emet le certificat de l'edge qu'avec ses propres noms # (`infra-edge-01.genese.internal`), et nginx retombe sur le certificat auto-signe de # Debian pour tout FQDN expose. Le service repond, la page s'affiche apres un -# avertissement — et rien ne signale la panne. C'est ce qui s'est passe ici : la forge de -# patient 0 etait publiee derriere un `ssl-cert-snakeoil.pem`, et `git clone` a ete le +# avertissement — et rien ne signale la panne. C'est ce qui s'est passe ici : une forge +# etait publiee derriere un `ssl-cert-snakeoil.pem`, et `git clone` a ete le # premier a refuser, a juste titre. # # Ce fichier appartient au MODELE parce que trois instances sur quatre le portaient diff --git a/roles/hosts_statiques/defaults/main.yml b/roles/hosts_statiques/defaults/main.yml index 57901d2..c3b639f 100644 --- a/roles/hosts_statiques/defaults/main.yml +++ b/roles/hosts_statiques/defaults/main.yml @@ -17,7 +17,7 @@ hosts_statiques_expositions: [] # # LE PIÈGE, MESURÉ LE 2026-08-23. `forge.alliance-boreale.ca` résout vers 192.168.14.66 # depuis le poste d'administration, et vers 69.70.26.51 — l'adresse PUBLIQUE — depuis -# l'overlay de patient 0, qui ne sait pas l'atteindre de l'intérieur (pas de retour en +# l'overlay d'un écosystème, qui ne sait pas l'atteindre de l'intérieur (pas de retour en # épingle). Le clone initial du miroir avait pourtant réussi : la résolution n'est pas # stable, elle dépend du résolveur interrogé. Un miroir qui se synchronise toutes les # huit heures serait tombé dessus tôt ou tard, et le silence aurait duré. diff --git a/roles/serveur_artefacts/tasks/main.yml b/roles/serveur_artefacts/tasks/main.yml index 035ef5b..5864b2d 100644 --- a/roles/serveur_artefacts/tasks/main.yml +++ b/roles/serveur_artefacts/tasks/main.yml @@ -45,7 +45,7 @@ # n'atteint jamais la couche qui poserait le bon amont. Le correctif se retrouve dans la # couche que la panne empeche d'atteindre, et il faut une main pour en sortir. # -# C'est exactement ce qui est arrive : l'amont pointait sur le cache de patient 0, eteint +# C'est exactement ce qui est arrive : l'amont pointait sur le cache d'un autre ecosysteme, eteint # la veille pour liberer de la RAM. `apt` rendait `503 Connection timeout` EN CITANT # L'ADRESSE DU CACHE LOCAL, jamais celle de l'amont manquant — la panne accusait le # maillon visible. diff --git a/roles/serveur_backup_site/README.md b/roles/serveur_backup_site/README.md index 0b3c1d0..e388f7d 100644 --- a/roles/serveur_backup_site/README.md +++ b/roles/serveur_backup_site/README.md @@ -20,7 +20,7 @@ vivaient sur `backup-01`, une VM de sa propre flotte.** Raser l'écosystème aur les données et leur seul filet dans le même geste. La doctrine affirmait pourtant que `client_backup_cible` *« pointe déjà hors de -l'écosystème »*. C'était vrai pour patient 0, qui sauvegarde chez `eregion` — faux pour +l'écosystème »*. C'était faux pour Chezlepro. *Un document qui décrit une propriété que le réel n'a pas est exactement ce que ce dépôt traque.* diff --git a/roles/serveur_backup_site/meta/flux.yml b/roles/serveur_backup_site/meta/flux.yml index e46d1df..907a916 100644 --- a/roles/serveur_backup_site/meta/flux.yml +++ b/roles/serveur_backup_site/meta/flux.yml @@ -8,8 +8,8 @@ # CE QUE SON ABSENCE COÛTAIT (mesuré le 2026-09-01). Chezlepro sauvegardait sur # `backup-01`, une VM de sa PROPRE flotte. Raser l'écosystème aurait détruit les données # et leur seul filet dans le même geste — et la doctrine affirmait pourtant que -# `client_backup_cible` « pointe déjà hors de l'écosystème ». C'était vrai pour patient 0, -# faux pour Chezlepro. +# `client_backup_cible` « pointe déjà hors de l'écosystème ». C'était faux pour +# Chezlepro. # # `voisins_site` désigne les autres tenants que CE SITE héberge. Ni `flotte`, ni `externe` : # un dépôt de sauvegarde ouvert à l'Internet serait la pire porte du site. diff --git a/roles/serveur_cache_site/meta/main.yml b/roles/serveur_cache_site/meta/main.yml index f475920..534b315 100644 --- a/roles/serveur_cache_site/meta/main.yml +++ b/roles/serveur_cache_site/meta/main.yml @@ -13,7 +13,7 @@ # AVANT le marqueur, dans le MÊME play, donc ses variables sont en portée. Et l'ordre # cesse de dépendre de la façon dont on lance le déploiement. # -# Chez patient 0 les deux vivaient sur le même hôte et étaient appliqués ensemble : la +# Dans le premier écosystème les deux vivaient sur le même hôte et étaient appliqués ensemble : la # dépendance existait déjà, elle n'était simplement écrite nulle part. dependencies: - role: serveur_artefacts diff --git a/roles/serveur_cache_site/tasks/main.yml b/roles/serveur_cache_site/tasks/main.yml index 699b92d..96e8485 100644 --- a/roles/serveur_cache_site/tasks/main.yml +++ b/roles/serveur_cache_site/tasks/main.yml @@ -2,7 +2,7 @@ # CE RÔLE MARQUE UN CACHE ; IL N'EN INSTALLE PAS. # # Il présuppose `serveur_artefacts` sur le même hôte — c'est lui qui pose apt-cacher-ng — -# et lit ses variables. Chez patient 0 les deux vivaient sur `forge-01`, donc la +# et lit ses variables. Dans le premier écosystème les deux vivaient sur `forge-01`, donc la # dépendance ne se voyait pas. La première machine à ne porter que le marqueur l'a # révélée, et le message était : « variable non définie : `serveur_artefacts_port` ». # diff --git a/roles/serveur_forgejo/defaults/main.yml b/roles/serveur_forgejo/defaults/main.yml index 3353eb7..15cc009 100644 --- a/roles/serveur_forgejo/defaults/main.yml +++ b/roles/serveur_forgejo/defaults/main.yml @@ -105,8 +105,8 @@ serveur_forgejo_oidc_discovery: >- # # POURQUOI CE CHOIX EXISTE (2026-08-22). Une offre `forge` pour un petit organisme # exigeait une VM PostgreSQL entiere — un serveur, une zone, un secret, une sauvegarde — -# pour une base que trois personnes sollicitent. Le premier ecosysteme a en avoir profite -# est patient 0, qui porte le genome : moins de surface sur la machine dont tout descend. +# pour une base que trois personnes sollicitent. Moins de surface, aussi, sur une forge +# qui porte le genome : c'est la machine dont tout descend. # # CE QUE `sqlite` CHANGE AILLEURS : rien a la sauvegarde — le job `serveur_forgejo` de # `client_backup` emporte deja `serveur_forgejo_data`, ou le fichier se trouve. Et rien diff --git a/roles/serveur_forgejo/tasks/main.yml b/roles/serveur_forgejo/tasks/main.yml index 72eedb0..7e480ab 100644 --- a/roles/serveur_forgejo/tasks/main.yml +++ b/roles/serveur_forgejo/tasks/main.yml @@ -410,7 +410,7 @@ - name: Creer le compte administrateur (une fois) # `--must-change-password=false` : SANS LUI, LE COMPTE EST INUTILISABLE (2026-08-23, - # premiere forge de patient 0). Forgejo exige par defaut un changement de mot de passe + # premiere forge d'un ecosysteme). Forgejo exige par defaut un changement de mot de passe # au premier acces, et refuse TOUTE requete d'API tant qu'il n'a pas eu lieu : # « You must change your password ». Or ce role desactive la connexion locale # (`serveur_forgejo_connexion_locale: false`, SSO d'abord) — il n'existait donc aucun @@ -438,7 +438,7 @@ # ON VERIFIE L'ETAT, ON NE FAIT PAS CONFIANCE AU DRAPEAU (2026-08-25). # # La creation passe deja `--must-change-password=false` — corrige le 2026-08-23, sur la -# premiere forge de patient 0. **Forgejo 16 l'a ignore** : le compte de la forge du SITE +# premiere forge d'un ecosysteme. **Forgejo 16 l'a ignore** : le compte de la forge du SITE # est ne avec le drapeau POSE malgre l'option. # # La panne qui en resulte n'accuse rien de juste : toute requete d'API rend **403**, pas diff --git a/roles/serveur_ops/defaults/main.yml b/roles/serveur_ops/defaults/main.yml index 99f868c..99b3377 100644 --- a/roles/serveur_ops/defaults/main.yml +++ b/roles/serveur_ops/defaults/main.yml @@ -90,8 +90,8 @@ serveur_ops_forge_amont_ac_depot: "{{ serveur_ops_racine }}/.ac-amont.crt" # # AUCUN DÉFAUT NE NOMME UN ÉCOSYSTÈME PARTICULIER (2026-08-24). # -# La première version listait ici `ops-patient0`. Tout écosystème qui aurait déployé un -# poste sans déclarer ses propres dépôts aurait donc cloné le génome de **patient 0** — +# La première version listait ici le dépôt d'un écosystème précis. Tout écosystème qui aurait +# déployé un poste sans déclarer ses propres dépôts aurait donc cloné le génome d'un **autre** — # silencieusement, et en croyant piloter le sien. C'est la faute que ce dépôt combat sous # tous ses déguisements : un défaut plausible qui rend un résultat faux sans rien dire. # diff --git a/roles/serveur_ops/tasks/main.yml b/roles/serveur_ops/tasks/main.yml index 624213b..5e38ddc 100644 --- a/roles/serveur_ops/tasks/main.yml +++ b/roles/serveur_ops/tasks/main.yml @@ -2,7 +2,7 @@ # UN POSTE QUI NE SAIT PAS SUR QUOI IL TRAVAILLE N'A RIEN À PILOTER. # # On exige explicitement ce qu'il pilote, plutôt que de retomber sur un défaut : le -# défaut nommait patient 0, et un écosystème distrait aurait cloné le génome d'un autre +# défaut nommait un écosystème précis, et un écosystème distrait aurait cloné le génome d'un autre # sans qu'aucune erreur ne le signale. # # DEUX FORMES DE RUNNER, ET UNE SEULE ÉTAIT PRÉVUE (2026-08-25). @@ -318,7 +318,7 @@ # # UN POSTE D'EXPLOITATION QUI APPELLE galaxy.ansible.com POUR SE CONSTRUIRE N'EST PAS # SOUVERAIN. Mesure du 2026-08-23, premier deploiement : `ansible-galaxy collection -# install` a echoue depuis l'overlay de patient 0 — +# install` a echoue depuis l'overlay d'un écosystème — # `SSL: UNEXPECTED_EOF_WHILE_READING` — parce que la frontiere ne laisse pas passer ce # flux, et c'est tres bien ainsi. Ouvrir une regle vers un serveur americain pour que # l'ecosysteme sache se reconstruire aurait ete la mauvaise reponse. diff --git a/scripts/devis_opnsense.py b/scripts/devis_opnsense.py index 06deb5e..efacb9a 100644 --- a/scripts/devis_opnsense.py +++ b/scripts/devis_opnsense.py @@ -849,8 +849,8 @@ def construire(tenants: list[tuple[str, str, dict]]) -> dict: # un droit d'entree general. Et la regle ne suffit pas a lire : sans la cle TSIG de # sa relation, le primaire refuse le transfert. # SEULEMENT LES LOCATAIRES QUI PUBLIENT (resserre le 2026-09-16). La premiere - # version prenait l'autoritatif de TOUS les locataires du site : Patient0, qui n'a - # aucune zone publique, recevait une ouverture 5300 depuis le serveur public. Rien + # version prenait l'autoritatif de TOUS les locataires du site : un locataire sans + # zone publique recevait une ouverture 5300 depuis le serveur public. Rien # n'y ecoutait — mais un chemin ouvert vers une machine qui n'en a pas besoin est # exactement ce que le moindre privilege refuse. def _publie(_nom_tenant: str) -> bool: diff --git a/scripts/devis_placement.py b/scripts/devis_placement.py index 66b3c02..42643a2 100644 --- a/scripts/devis_placement.py +++ b/scripts/devis_placement.py @@ -47,7 +47,7 @@ def placement_du_tenant() -> tuple[dict, Path | None]: """Les valeurs de placement declarees par le tenant VISE. SETOPS_INSTANCE d'abord ; le symlink `instance/` n'en est que le cas courant. Code en - dur, il rendait ce devis incapable de regarder un AUTRE tenant : viser patient 0 + dur, il rendait ce devis incapable de regarder un AUTRE tenant : viser un autre tenant mesurait en silence le placement de l'instance montee, et rendait un verdict juste pour le mauvais tenant (mesure du 2026-08-20 — les deux avaient les memes quatre valeurs, ce qui est exactement la circonstance ou l'erreur ne se voit pas). diff --git a/scripts/exporter_cles.py b/scripts/exporter_cles.py index 3de8451..80ff325 100644 --- a/scripts/exporter_cles.py +++ b/scripts/exporter_cles.py @@ -3,7 +3,7 @@ CE QUE CE SCRIPT PROTEGE, ET POURQUOI C'EST LE PLUS URGENT (mesure du 2026-09-05). -Le CODE de Set-OPS est replique trois fois : `eregion`, la forge du site, patient 0. Les +Le CODE de Set-OPS est replique deux fois : `eregion` et la forge du site. Les voutes chiffrees y sont aussi — le coffre est solide. Les CLES qui ouvrent ce coffre, elles, vivent dans six fichiers de `~/.config`, 357 diff --git a/scripts/inventory_rules.py b/scripts/inventory_rules.py index 9e9d195..562ce6c 100644 --- a/scripts/inventory_rules.py +++ b/scripts/inventory_rules.py @@ -272,8 +272,7 @@ def integrations_de(srv: dict, services_hote: set[str] | None = None, UNIVERSELLE N'EST POSEE QUE SI SON SERVICE CENTRAL EXISTE ICI (2026-08-22). Pourquoi cette regle a manque. « Tout hote est mesure » est vrai dans un ecosysteme qui - porte un Prometheus. Dans un ecosysteme qui n'en a pas — un patient 0 minimal, une - petite offre — la meme phrase pose sur chaque machine un client qui n'a personne a qui + porte un Prometheus. Dans un ecosysteme qui n'en a pas — une petite offre — la meme phrase pose sur chaque machine un client qui n'a personne a qui parler, et le controle de dependances refuse le deploiement. Le moteur supposait l'ecosysteme COMPLET ; c'est la troisieme fois que cette hypothese se paie, apres les intrants (P32) et les bases (P35). diff --git a/scripts/prouver.py b/scripts/prouver.py index 0f6414e..198885f 100644 --- a/scripts/prouver.py +++ b/scripts/prouver.py @@ -1072,7 +1072,7 @@ def preuve_base_par_consommateur() -> tuple[bool, str]: """ # INSTANCE, pas le symlink en dur : sans cela cette preuve mesurait toujours # l'instance montee, quelle que soit celle qu'on visait (2026-08-22, en verifiant - # patient 0 — elle a rendu un verdict juste sur le mauvais ecosysteme). + # un autre ecosysteme — elle a rendu un verdict juste sur le mauvais ecosysteme). plan = INSTANCE / "plan" if not (plan / "bases-donnees.yml").is_file(): return True, "Aucun registre de bases : rien a verifier." @@ -1475,7 +1475,7 @@ def preuve_resolution_unique() -> tuple[bool, str]: def preuve_edge_porte_ses_noms() -> tuple[bool, str]: """Tout ecosysteme qui PUBLIE des noms sert un certificat qui les porte. - POURQUOI CETTE PREUVE EXISTE (2026-08-23). L'edge de patient 0 publiait sa forge + POURQUOI CETTE PREUVE EXISTE (2026-08-23). L'edge d'un ecosysteme publiait sa forge derriere `ssl-cert-snakeoil.pem` — le certificat auto-signe de Debian. Le service repondait, la page s'affichait apres un avertissement, `make prouver` etait vert : rien, nulle part, ne signalait que la publication n'etait pas de confiance. Le premier @@ -3905,8 +3905,8 @@ def preuve_amorcage_suit_le_site() -> tuple[bool, str]: a quinze couches de sa cause. CE QUE CETTE PREUVE NE FAIT PAS : juger une adresse qui ne designe pas le site. Un - tenant peut legitimement s'amorcer sur un resolveur public — `OPS-Technolibre` et - `OPS-Patient0` visent `9.9.9.9`, et c'est un choix, pas un oubli. On ne verifie que + tenant peut legitimement s'amorcer sur un resolveur public — `OPS-Technolibre` + vise `9.9.9.9`, et c'est un choix, pas un oubli. On ne verifie que les valeurs qui PRETENDENT designer une machine du site : meme troisieme octet de zone, autre deuxieme octet. Une adresse etrangere au site n'est pas notre affaire. """ @@ -4227,7 +4227,7 @@ def preuve_remise_tenue() -> tuple[bool, str]: des empreintes, jamais des valeurs. CE QU'ELLE NE JUGE PAS. Un ecosysteme SANS registre : tous ne sont pas remis, et - plusieurs ne le seront jamais — le lab, patient 0, l'ecosysteme de l'hebergeur + plusieurs ne le seront jamais — le lab, l'ecosysteme de l'hebergeur lui-meme. Exiger un registre partout ferait du bruit la ou il n'y a rien a tenir. ET CE QU'ELLE NE PEUT PAS PROUVER : que l'hebergeur ne puisse PLUS entrer. Le plan diff --git a/scripts/restaurer_cles.py b/scripts/restaurer_cles.py index c33a775..0649e42 100644 --- a/scripts/restaurer_cles.py +++ b/scripts/restaurer_cles.py @@ -3,8 +3,8 @@ POURQUOI CE SCRIPT DOIT POUVOIR VIVRE SUR LA CLE USB. -Le jour ou l'on s'en sert, le poste est mort. Le depot Set-OPS est replique — eregion, la -forge du site, patient 0 — mais le CLONER demande la cle SSH, qui est justement dans +Le jour ou l'on s'en sert, le poste est mort. Le depot Set-OPS est replique — eregion et la +forge du site — mais le CLONER demande la cle SSH, qui est justement dans l'archive qu'on essaie d'ouvrir. Une procedure de restauration qui vit dans le depot serait donc inaccessible exactement quand elle sert. diff --git a/wiki/Glossaire.md b/wiki/Glossaire.md index a307f2d..96a95dc 100644 --- a/wiki/Glossaire.md +++ b/wiki/Glossaire.md @@ -289,8 +289,7 @@ règles. Un par écosystème. ## L'état, et sa preuve **SQLite** — Une base de données qui tient dans **un fichier**, sans serveur ni compte. -Suffisante pour une petite forge — c'est ce que portait patient 0, dont les machines -n'existent plus. À l'inverse de +Suffisante pour une petite forge. À l'inverse de *PostgreSQL*, qui est un service à part entière — un serveur, une zone, un secret. **restic** — L'outil de sauvegarde chiffrée et dédupliquée. Cf. [Sauvegardes](Sauvegardes). diff --git a/wiki/La-preuve.md b/wiki/La-preuve.md index 9d09992..4b75e0f 100644 --- a/wiki/La-preuve.md +++ b/wiki/La-preuve.md @@ -101,7 +101,7 @@ parce que de l'intérieur d'un fichier, la copie locale a toujours l'air correct ### Ce que ça donnait -`make placement-plan` visait patient 0 et répondait : +`make placement-plan` visait un autre tenant et répondait : ``` Devis du placement — tenant « instance »