Set-OPS-Public/docs/filiation-emancipation.md
Daniel Allaire 5bc3bceac1
Some checks failed
verifier / verifier (push) Has been cancelled
documentation : la tournee des 74 documents, parce qu un balayage ne lit pas
La revision a commence par un balayage par motifs — chemins morts, cibles make
absentes, comptes derives. Il a trouve une trentaine d ecarts et rate presque
tout le reste : un motif ne voit que ce qui s exprime en motif.

make hote-planifier en est l exemple. La cible EXISTE, donc le controle passait
au vert. C est une cible depreciee qui refuse et sort en 2, recommandee par
AGENTS.md, et qui contredit la REGLE D OR du meme fichier trois ecrans plus
haut. Il fallait lire pour la voir.

74 documents lus un par un. 66 corriges, 8 exacts.

CE QUI ETAIT FRANCHEMENT FAUX

AGENTS.md, la source d autorite, annoncait la flotte pas encore executee contre
des VM reelles. Elle a ete rasee et remontee depuis zero trois fois.
ecosysteme-chezlepro.md, le document montre a un client, portait la meme
phrase : il se sous-vendait gravement.

courriel-conception.md s ouvrait sur aucun role n est encore ecrit, au-dessus de
son propre paragraphe 1 qui les nomme. autorisation.md se terminait sur rien n
est construit alors qu il rapporte des mesures datees du role en fonctionnement.
hebergeur-exploitation.md disait rien n est fait d un depot qui existe.
filiation-emancipation.md se contredisait a deux ecrans de distance.

DES MODELES DECRITS D APRES UN MONDE ANTERIEUR

Le resolveur : cinq documents decrivaient un Unbound par VM en opt-in, trois le
donnaient en exemple d integration FACULTATIVE — il est universel depuis le
2026-08-24. L adressage de nomenclature-vm.md : reseau unique, VLAN 11-15, VMID
a cinq chiffres. Le nommage SDN de sdn-evpn.md contre le code : c est le wiki
qui avait raison.

CE QUI CASSE AU PREMIER ESSAI

Le nom du gabarit dore etait faux a quatre endroits, dont la procedure qui le
FABRIQUE et le critere R2 de l epreuve d operateur independant.
preparer-un-site-hebergeur.md avertissait qu une VM faite a la main serait
detruite : raser derive du plan, il ne la detruira jamais — le risque est l
inverse. Un mot de passe d essai en clair dans un depot public.

DEUX PREUVES ETENDUES, ET UNE QUI SE TROMPAIT ELLE-MEME

P57 couvre les groupes : elle a signale aussitot 29 groupes annonces au-dessus d
un tableau qui en cite 40. P29 confronte le tableau de authentification.md aux
declarations reelles : 12 annonces, 21 reels.

Et P57 imposait un chiffre faux — 56 preuves alors que le depot en porte 57, la
conditionnelle vivant hors de tout comptage. Un garde-fou qui fait respecter une
erreur ajoute l assurance a l erreur.

CE QUI RESTE, ET QU AUCUNE PREUVE NE TIENT

Deux comptes trouves a la main. Et une lacune reelle : rien ne garde les
meta/acces.yml — ni qu un service web-sso en porte un, ni que le groupe qu il
nomme existe. P29 tient les positions d authentification, personne ne tient les
habilitations.

make prouver : CONFORME, 56 OK, 0 echec, 1 saute. 0 lien mort.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-06 16:18:23 -04:00

12 KiB

Filiation, mutualisation, émancipation

Pour qui : l'architecte de la lignée et l'hébergeur qui abrite des écosystèmes tiers. Décrit les trois âges d'un écosystème et ce qu'ils impliquent au plan.

Le constat

Un écosystème ne naît pas autoportant. Il lui faut une forge pour lire son génome, une source d'artefacts pour ses paquets, un dépôt pour ses sauvegardes — et rien de tout cela n'existe la première seconde. Il emprunte donc à son hôte.

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

Trois astuces, une seule notion. Ce document la déclare.

Les trois âges

FILIATION       l'enfant emprunte à son parent ce qu'il ne porte pas encore
MUTUALISATION   un état DURABLE et CHOISI — on emprunte parce qu'on le veut
ÉMANCIPATION    l'écosystème porte tout lui-même

L'émancipation n'est pas une obligation. Un petit organisme peut rester mutualisé toute sa vie ; ce qui compte est qu'il puisse s'émanciper, et que la sortie ne soit ni un piège ni une reconstruction. C'est la différence entre un locataire et un captif.

Ce que ça veut dire pour les modèles

Un modèle sans forge n'est pas un modèle amputé : c'est un écosystème au premier âge, dont le runner lit le génome chez son hôte. L'ajout d'une forge n'est pas une correction, c'est une émancipation.

premier âge   serveur_ops_forge_externe: true   + l'adresse de la forge de l'hôte
émancipé      serveur_ops_forge_externe: false  + sa propre serveur_forgejo au plan

Ce que ça veut dire pour l'hébergeur

L'hébergeur ne vend plus seulement des machines : il vend l'abri pendant la jeunesse. Chaque service mutualisé est une ligne de facture, et chaque émancipation est une décision du client — jamais une rupture technique.

Pour une clientèle d'OBNL et de coopératives, c'est le bon geste : on entre à bas coût, on grandit vers l'autonomie, et on n'est jamais captif, puisque le génome est déjà chez soi dès le premier jour.

Ce qui est mutualisable, et ce qui ne l'est pas

service mutualisable remarque
forge (génome) oui serveur_ops_forge_externe
source d'artefacts oui client_artefacts se désactive seul si aucune n'existe
sauvegarde oui client_backup_cible pointe déjà hors de l'écosystème
observabilité oui l'hébergeur surveille ses locataires
relais courriel oui
DNS partiellement un sous-domaine délégué, pas la zone entière
PKI à trancher une AC intermédiaire signée par l'hôte est possible, mais l'AC définit l'identité de l'écosystème
identité (LDAP/SSO) le plus intime mutualiser l'annuaire, c'est confier ses gens
la voûte jamais les secrets ne se mutualisent pas, à aucun âge

L'insémination — le premier lien, et le seul que le SITE ait le droit d'avoir

Entre tenants, le zéro-confiance est le défaut : la frontière refuse tout ce qui n'est pas déclaré, et c'est cette règle qui rend l'hébergement mutualisé défendable. La parenté est la seule exception, et elle est asymétrique : un écosystème neuf ne peut pas s'amorcer lui-même. Quelqu'un doit poser sa première machine et lui donner de quoi continuer.

Ce geste s'appelle l'insémination :

le SITE matérialise        VNets, VM, routes, flux — le terrain
le SITE amorce ops-01      la première machine, et elle seule
le TENANT achève           ses autres machines, ses rôles, ses intégrations

Le partage d'intelligence qui le rend possible. Les deux runners portent le même moteur ; ils n'en consomment pas la même face :

ce qu'il lit du moteur ce qu'il en fait
runner du SITE roles/*/meta/flux.yml — la face réseau des rôles SDN, pare-feu Proxmox, frontière OPNsense
runner du TENANT tasks/, templates/, meta/integration.yml — la face machine configure ses services

C'est ce partage qui permet au SITE de poser les bonnes règles pour un tenant sans jamais lire sa configuration ni détenir sa voûte. Il sait de quoi les rôles ont besoin sur le fil ; il ignore ce qu'ils font sur la machine.

Ce que le lien doit être, pour ne pas devenir un pouvoir permanent :

  • étroit — vers le seul ops-01 du tenant, jamais vers ses autres machines ;
  • déclaré — dans meta/flux.yml, comme tout le reste, pour que la frontière et nftables le connaissent au lieu de le subir ;
  • borné par un acte, et cet acte appartient à un humain (voir ci-dessous).

Ce qui existe déjà sans être déclaré, au 2026-08-28. make creer-vm exige _instance-requise : pour matérialiser les VM d'un tenant, le runner du SITE doit basculer son symlink instance sur le dépôt de ce tenant — alors que son plan pose serveur_ops_instance: "" et que la doctrine dit qu'un SITE n'a pas de plan monté par ce lien. Le couplage est donc déjà là, et rien ne borne sur quels tenants il porte ni jusqu'à quand. Le déclarer, c'est le rendre limitable ; le taire ne l'a jamais empêché.

Ce que l'émancipation exige — et de qui

Basculer une déclaration ne suffit pas. Mais l'erreur symétrique est plus tentante encore : faire de l'émancipation un automatisme, que la machine déclencherait dès qu'elle constate que le tenant se reproduit sans son parent.

L'émancipation exige toujours la gouverne d'un humain. Le fruit de l'émancipation est livré à quelqu'un — un client qui reprend ses clés, sa forge, son écosystème. Sans quelqu'un pour le recevoir, il n'y a pas de livraison : seulement un lien qui tombe. Une émancipation qui se déclencherait toute seule ne serait pas une émancipation, ce serait une expulsion.

C'est déjà la forme des gestes lourds de ce dépôt : raser exige CONFIRMER=true et le nom de l'instance ; le mot de passe de la voûte se tape à l'exécution — « le seul objet que la reproduction exige d'un humain ». L'émancipation est le deuxième objet de cette liste.

D'où la répartition, qui ne se confond pas :

qui l'exécute
le lien de filiation — déclaré, étroit, visible au plan le moteur
le constat d'aptitude — « ce tenant se reproduit sans son parent » la machine — elle instruit, elle n'agit pas
l'acte d'émancipation — retirer le lien, remettre les clés l'humain, garde CONFIRMER=true
la preuve que le lien est coupé la machine, après l'acte

La quatrième ligne est celle qu'on oublie, et c'est elle qui décide si les trois autres ont servi. Sans elle, on croirait s'être émancipé en restant dépendant sans le savoir — exactement le défaut que ce dépôt traque partout ailleurs : un vert sur un périmètre vide. Une émancipation non prouvée est une émancipation non faite.

L'instrument de la quatrième ligne — make emancipation-prouver

Il existe depuis le 2026-09-01, et il coupe au lieu de sonder.

Vérifier que le service local répond ne prouve rien : tant que l'amont répond, une fonction qui marche ne dit pas d'où vient l'octet. L'instrument bloque donc l'amont — table nftables dédiée, retirée par un bloc always quoi qu'il arrive — puis refait marcher la chose.

Le même essai rend les deux verdicts, et c'est ce qui le rend honnête :

coupé, la fonction marche  ->  ÉMANCIPÉ, et c'est prouvé
coupé, la fonction casse   ->  PAS ÉMANCIPÉ, et la dépendance est prouvée RÉELLE

Le second n'est pas un échec de l'outil : c'est son contrôle négatif, rendu par la même commande. Une preuve d'émancipation incapable de montrer la dépendance qu'elle mesure ne prouverait rien le jour où elle passerait au vert.

Un témoin précède la coupure — la fonction marchait-elle seulement avant ? Sans lui, une panne préexistante se lirait comme une dépendance.

make emancipation-prouver SERVICE=artefacts HOTE=forge-01 CONFIRMER=true

Mesuré le jour de sa naissance : obs-01 ne résout plus rien dès que le résolveur du site est coupé — dépendance réelle ; forge-01 installe des paquets le cache du site coupé, listes vidées — émancipation prouvée sur ce service.

Forme attendue d'une déclaration

Tout service mutualisable doit se déclarer de la même façon, pour qu'un exploitant lise l'état de son écosystème d'un coup d'œil plutôt qu'en fouillant chaque rôle :

<service>_externe: true          # je l'emprunte
<service>_amont: "https://…"     # à qui

false — ou l'absence du couple — signifie chez moi. Le rôle refuse de démarrer si le drapeau est levé sans que l'amont soit nommé : emprunter sans dire à qui, c'est ne rien 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é.

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, et c'est ce que patient 0 garde : il porte un miroir du génome comme chaque écosystème. Ce qu'il perd, c'est le rang, pas la place.

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.

État — revu le 2026-09-06

Seule la forge porte cette déclaration complète (serveur_ops). Les autres services mutualisés le sont par des mécanismes antérieurs, cohérents mais non uniformes. Les aligner sur la forme ci-dessus reste à faire.

Des trois manques que cette section listait au 2026-08-28, deux sont comblés :

Manque du 2026-08-28 Aujourd'hui
l'instrument de preuve de la dernière ligne — « le lien est coupé » — n'existe pas make emancipation-prouver, depuis le 2026-09-01 (§ ci-dessus). Il coupe au lieu de sonder, et rend les deux verdicts.
la séparation des voûtes est organisationnelle, pas cryptographique — un seul mot de passe ouvre celle du site et celles des tenants Séparé le 2026-08-28 même : une voûte, une clé (~/.config/setops-vault-<dépôt>, scripts/voutes.py). L'ancien mot de passe unique n'ouvre plus rien. La séparation précédait nécessairement la distribution des clés aux runners : sinon, poser « la » clé sur le plus petit locataire lui donnait les secrets de l'hébergeur.
le lien d'insémination n'est pas déclaré Toujours vrai. Il existe, par le symlink instance du runner du SITE, sans borne ni visibilité. C'est le manque qui reste.

(Le paragraphe sur les voûtes se contredisait avec scripts/voutes.py — daté du même jour — et celui sur l'instrument avec la section qui le décrit, deux écrans plus haut. Un document qui se contredit lui-même à cette distance n'est plus lu comme une référence.)