--- # LES RUNBOOKS DE CONSTRUCTION — l'ordre des gestes, et pourquoi celui-la. # # CE QUE CE FICHIER AJOUTE AU MAKEFILE, ET CE QU'IL NE REPETE PAS. # # Les 132 cibles documentees du Makefile disent chacune CE QU'ELLE FAIT. Aucune ne dit # dans quel ORDRE, ni pourquoi maintenant, ni ce qu'il faut avoir mesure avant. Cette # connaissance-la vivait en prose dans `docs/runbooks-exploitation.md`, # `docs/implanter-un-tenant-sur-un-site.md` et `docs/preparer-un-site-hebergeur.md` — et # la console offrait des boutons sans sequence. # # ON NE RECOPIE PAS LE LIBELLE D'UNE CIBLE. `scripts/runbooks.py` va le lire dans le # Makefile au moment de servir. Un libelle recopie ici serait une seconde liste, et une # liste qui suit une autre prend du retard sur elle. Ce fichier ne porte donc que ce que # le Makefile ne peut pas porter : l'ordre, la nature du geste, la portee, le pourquoi. # # LA GARDE EST ECRITE AVEC LA LISTE, PAS APRES. `python3 scripts/runbooks.py verifier` # (et P83) refusent qu'une cible documentee ne soit ni portee par un runbook ni exemptee # avec un motif. Sans cela, la console cacherait des pouvoirs que le moteur possede. # # NATURE D'UNE ETAPE # mesure n'ecrit rien, rejouable sans consequence, proposee meme apres un echec # ecriture change l'etat du monde ; exige que l'etape precedente ait reussi # destructif detruit ; exige une confirmation ecrite en plus de CONFIRMER=true # # PORTEE D'UN RUNBOOK — ce que la MACHINE porte, au sens de `contexte()` : # tenant un ecosysteme est monte (`instance/`) : on le configure # site une fabric est montee (`underlay.yml`) : on materialise # poste les deux — l'atelier du mainteneur # toute ni l'un ni l'autre n'est requis # # LA PORTEE SE PESE A L'ETAPE (2026-09-20). Un runbook donne le defaut ; une etape qui # exige davantage le declare avec son propre `portee:`. Mesure faite sur la console de # TechnoLibre : declaree au seul runbook, une unique etape qui materialise (`flotte-creer`, # `creer-vm`) faisait basculer TOUTE la sequence en `poste` — et un locataire ne pouvait # plus deployer sa propre flotte, ce qui est exactement son metier. Le locataire conduit # donc sa sequence, et bute precisement la ou il faut : sur la machine a engendrer. # CE QUE LA CONSOLE DOIT DEMANDER A L'EXPLOITANT. Une variable absente d'ici est refusee # par la garde : la console ne saurait pas quoi afficher, et un champ libre sans invite # est une invitation a se tromper. variables: HOTE: invite: "La machine" source: hotes # la liste vient de l'inventaire actif GROUPE: invite: "Le groupe (role)" source: groupes NOM: invite: "Nom du dossier de l'ecosysteme" exemple: "OPS-Machin" MODELE: invite: "Modele de depart" source: modeles INSTANCE: invite: "Nom de l'ecosysteme a detruire (il doit etre ecrit en toutes lettres)" SITE: invite: "Depot du site a detruire (ecrit en toutes lettres)" TENANT: invite: "Dossier du locataire a amorcer" exemple: "OPS-Machin" DEPOT: invite: "Un seul depot (vide = tous ceux que le runner porte)" facultatif: true VERS: invite: "Repertoire de destination (une cle chiffree, hors du poste)" ARCHIVE: invite: "Fichier d'archive a restaurer" CIBLE: invite: "Hote ou adresse a sonder" SERVICE: invite: "Le lien dont on prouve la coupure" valeurs: [artefacts, genome, resolveur] ROLE: invite: "Un seul role (vide = tous)" facultatif: true LIMITE: invite: "Motif d'hotes" facultatif: true RECU_PAR: invite: "Qui recoit la remise (nom complet)" COURRIEL: invite: "Courriel de la personne qui recoit" DANS: invite: "Jours avant le second temps" facultatif: true JEU: invite: "Le jeu d'etat (openldap, postgresql, nextcloud... — voir restauration-etat)" DEPUIS: invite: "Reprendre a cette etape (vide = depuis le debut)" valeurs: [sauvegarder, raser, creer, inseminer, armer, monter, parefeu, bilan] facultatif: true ARMER: invite: "Armer sans marquer la pause" valeurs: [oui] facultatif: true VMID: invite: "Identifiant Proxmox de la VM" DIALECTE: invite: "Dialecte du commutateur" valeurs: [cisco, binardat] facultatif: true PARALLELE: invite: "Combien de VM a la fois" facultatif: true runbooks: # ───────────────────────────────────────────────────────────────────────────── - id: site-premier-jour titre: "Le premier jour d'un site" portee: site doc: docs/runbooks-exploitation.md but: >- Faire naitre un site hebergeur depuis une fabric nue : les machines, puis le moteur, puis la forge qui permettra aux locataires de se reproduire. L'ordre n'est pas une preference — le premier passage s'ARRETE sur une forge vide, et c'est normal. etapes: - cible: underlay nature: mesure pourquoi: >- La fabric declaree tient-elle debout toute seule ? Rien ne sert de creer des machines sur un plan d'adressage qui se contredit. - cible: underlay-plan nature: mesure pourquoi: >- Le declare face au REEL, par l'API du cluster et une sonde TCP. C'est ici qu'on apprend qu'un pont n'existe pas, pas au milieu de la creation des VM. - cible: site-creer nature: ecriture fixes: {CONFIRMER: "true"} duree: "~9 min" pourquoi: >- Les machines du site, depuis l'underlay. Elles naissent ; elles ne repondent pas encore. - cible: site-deployer-tout nature: ecriture fixes: {CONFIRMER: "true"} duree: "~20 min" pourquoi: >- Premier passage. Il va jusqu'a `serveur_ops` et s'arrete sur la forge vide : ce n'est pas un echec, c'est le maillon suivant. - cible: forge-amorcer nature: ecriture fixes: {CONFIRMER: "true"} duree: "~45 s" pourquoi: >- La forge tourne et n'a ni organisation ni depot. Sans cet amorcage, le runner clone le vide et le deploiement ne finira jamais. - cible: site-deployer-tout nature: ecriture fixes: {CONFIRMER: "true"} duree: "~4 min" pourquoi: >- Second passage. Celui-ci doit finir a zero echec ; s'il n'y arrive pas, c'est un vrai defaut, plus un maillon manquant. - cible: publier nature: ecriture variables: [DEPOT] pourquoi: >- Le geste quotidien : eregion ET la forge du site, puis la verification. Un `git push` seul laisse la forge du site en retard sans que rien le dise. - cible: genome-pousser nature: ecriture variables: [DEPOT] pourquoi: >- La forge du site FAIT AUTORITE : tant qu'elle est en retard, tout ecosysteme qui s'y reproduit reproduit un moteur perime. - cible: routes-fabric-etat nature: mesure pourquoi: >- Les hyperviseurs routent-ils toutes les zones ? Une zone non routee ne se voit qu'au moment ou un locataire y pose sa premiere machine. - cible: gabarit-etat nature: mesure pourquoi: >- Sans gabarit conforme, aucun locataire ne pourra cloner quoi que ce soit ici. # ───────────────────────────────────────────────────────────────────────────── - id: site-tenir titre: "Tenir un site en etat" portee: site doc: docs/hebergeur-exploitation.md but: >- Les gestes reguliers de l'hebergeur : porter le genome a jour, appliquer un role aux machines du site, et regarder ce que la fabric fait vraiment. etapes: - cible: genome-etat nature: mesure pourquoi: >- Ce que la forge porte, face au poste. Un ecart ici se paie chez TOUS les locataires qui clonent ensuite. - cible: genome-pousser nature: ecriture variables: [DEPOT] pourquoi: "Remettre la forge au niveau du poste, depot par depot si besoin." - cible: site-appliquer nature: ecriture variables: [GROUPE] pourquoi: >- Rejouer un role sur les machines du site — c'est ainsi qu'un runner reprend le genome courant, rien ne le tire tout seul. - cible: site-decrire nature: mesure pourquoi: "Ce que l'underlay declare comme machines de l'hebergeur." - cible: site-inventaire nature: mesure pourquoi: "L'inventaire dynamique du site, tel qu'Ansible le voit — pas tel qu'on l'imagine." - cible: site-intrants nature: mesure pourquoi: "Ce que ce site expose a ses locataires, derive et non declare deux fois." - cible: fiches-site-deposer nature: ecriture pourquoi: >- Deposer chez chaque locataire la fiche que le site lui destine. Son runner n'a pas le depot du site : c'est par elle que son inventaire se genere sans lui. A commiter dans le depot de chaque locataire. - cible: site-verifier nature: mesure pourquoi: "Le playbook du site correspond-il encore aux couches declarees ?" - cible: site nature: ecriture pourquoi: "Regenerer playbooks/site.yml quand les couches ont bouge." - cible: routes-fabric-etat nature: mesure pourquoi: "Une route de zone manquante est invisible jusqu'au premier invite qui la traverse." - cible: locataire-creer nature: ecriture variables: [TENANT, PARALLELE] fixes: {CONFIRMER: "true"} pourquoi: >- Cloner les VM d'un locataire NOMME, d'apres la face reseau qu'il publie : le runner du site materialise sans monter son depot. Memes machines, memes parametres que `flotte-creer` sur l'instance montee (P93, P94). - cible: locataire-raser nature: destructif variables: [TENANT, INSTANCE] fixes: {CONFIRMER: "true"} pourquoi: >- Detruire les VM d'un locataire NOMME, d'apres sa face : les memes VMID que le plan derive (P94). Son nom court s'ecrit en toutes lettres, comme pour `raser`. - cible: site-raser nature: destructif variables: [SITE] fixes: {CONFIRMER: "true"} pourquoi: >- Detruire les VM du SITE. A ne faire que sur un site de chantier : la reconstruction est prouvee, elle n'est pas gratuite. # ───────────────────────────────────────────────────────────────────────────── - id: locataire-naitre titre: "Faire naitre un ecosysteme de locataire" portee: tenant doc: docs/multi-instances.md but: >- Du modele au plan monte : creer le dossier de l'ecosysteme, le rendre actif, puis generer son inventaire. Tout l'adressage descend du seed `index` — on ne l'ecrit jamais a la main. etapes: - cible: instance-modeles nature: mesure pourquoi: "Quels modeles de depart existent, avant d'en choisir un." - cible: instances nature: mesure pourquoi: >- Les ecosystemes deja decouverts, et surtout les COLLISIONS d'index : deux ecosystemes sur le meme seed se marcheraient dessus en silence. - cible: instance-creer nature: ecriture variables: [NOM, MODELE] pourquoi: "Le dossier de l'ecosysteme, depuis un modele, avec son index reserve." - cible: instance-utiliser nature: ecriture variables: [NOM] pourquoi: >- Basculer le symlink `instance/`. C'est lui qui decide QUEL ecosysteme la console configure — et quelle voute elle ouvrira. - cible: instance-courante nature: mesure pourquoi: "Verifier vers quoi on pointe avant d'ecrire quoi que ce soit." - cible: intrants-verifier nature: mesure pourquoi: >- Tout intrant qu'un role EXIGE est-il fourni ? Un intrant manquant ne se voit sinon qu'au milieu d'un deploiement. - cible: ports-verifier nature: mesure pourquoi: "Deux roles co-localises qui reclament le meme port ne cohabiteront pas." - cible: instancier nature: mesure pourquoi: >- Generer hosts.yml depuis le plan SANS l'appliquer — on regarde le diff avant de le prendre. - cible: instancier-appliquer nature: ecriture pourquoi: >- Prendre l'inventaire genere. `hosts.yml` est un ARTEFACT : on edite le plan, on ne le corrige jamais a la main. - cible: inventaire-verifier nature: mesure pourquoi: "L'inventaire se parse-t-il, voute dechiffree ? Sinon rien ne partira." # ───────────────────────────────────────────────────────────────────────────── - id: locataire-materialiser titre: "Preparer le terrain d'un locataire sur la fabric" portee: site doc: docs/implanter-un-tenant-sur-un-site.md but: >- Tout ce que l'HEBERGEUR pose avant qu'un locataire puisse exister : le placement, les pools, le SDN, les pare-feux et la frontiere. Chaque devis se mesure avant de s'appliquer — un devis qu'on applique sans l'avoir lu est un pari. etapes: - cible: placement-plan nature: mesure pourquoi: >- Le noeud, le stockage, le pont et le gabarit existent-ils VRAIMENT sur ce cluster ? C'est la premiere chose qui manque, et la derniere qu'on regarde. - cible: devis-proxmox-pools nature: mesure pourquoi: "Un pool par locataire, derive du plan — la cloison la plus simple." - cible: devis-proxmox-pools-verifier nature: mesure pourquoi: "Le devis tient-il ses propres regles avant qu'on le pose ?" - cible: devis-sdn nature: mesure pourquoi: "Zone, VNets et sous-reseaux, derives du seed de l'ecosysteme." - cible: devis-sdn-verifier nature: mesure pourquoi: "Relire le devis SDN avant de toucher au reseau du cluster." - cible: sdn-plan nature: mesure pourquoi: "L'ecart entre le SDN en service et ce devis — ce qui manque, ce qui est perime." - cible: sdn-appliquer nature: ecriture fixes: {CONFIRMER: "true"} pourquoi: >- Reconcilier : creer ce qui manque et RETIRER ce qui est perime. Le retrait est la moitie qu'on oublie. - cible: flux nature: ecriture pourquoi: >- Regenerer le registre des flux et les regles nftables depuis les `meta/flux.yml` des roles. Tout ce qui suit en descend. - cible: face-reseau-publier nature: ecriture pourquoi: >- Publier ce que ce locataire demande a son site (`face-reseau.yml`) : ses machines, ses zones, ses flux deja resolus. Le site ne lit plus que ce fichier. Apres `flux`, et a commiter dans le depot du locataire. - cible: devis-proxmox-fw nature: mesure pourquoi: "Le pare-feu est-ouest intra-locataire, derive du registre des flux." - cible: devis-proxmox-fw-verifier nature: mesure pourquoi: "Relire ce devis avant de le poser sur le cluster." - cible: proxmox-fw-plan nature: mesure pourquoi: "L'ecart entre le pare-feu en service et le devis." - cible: proxmox-fw-appliquer nature: ecriture fixes: {CONFIRMER: "true"} pourquoi: "Poser IPSets, groupes et affectations — et retirer ce qui ne se declare plus." - cible: proxmox-fw-eprouver nature: mesure variables: [TENANT, HOTE] pourquoi: >- Avant d'activer le pare-feu d'UNE VM : les regles du devis tiennent-elles face aux flux que la VM recoit REELLEMENT ? Une VM reconstruite a perdu ses options. - cible: proxmox-fw-activer-vm nature: ecriture variables: [TENANT, HOTE] fixes: {CONFIRMER: "true"} pourquoi: >- Activer une VM a la fois, matrice avant et apres, Icinga lu. Chaque defaut du 2026-09-28 ne s'est montre qu'a l'activation d'UNE VM. - cible: devis-opnsense nature: mesure pourquoi: "La frontiere nord/sud, derivee du meme registre de flux." - cible: devis-opnsense-verifier nature: mesure pourquoi: "Relire le devis de frontiere : c'est la porte de l'exterieur." - cible: frontiere-plan nature: mesure pourquoi: "Ce que la frontiere porte aujourd'hui, face a ce devis." - cible: frontiere-appliquer nature: ecriture fixes: {CONFIRMER: "true"} pourquoi: >- Reconcilier la frontiere. Les routes creees ETEINTES ont deja coute une journee : une route eteinte compte « posee » et ne route rien. - cible: devis-reseau nature: mesure variables: [DIALECTE] pourquoi: >- Le devis des commutateurs physiques (VLANs, SVIs, ACLs). Il se pose a la main sur le materiel — le moteur ne configure pas les switches. - cible: frontiere-mesurer nature: mesure pourquoi: >- La frontiere refuse-t-elle ce qui n'est pas declare ? Un connect() qui aboutit ne prouve rien : seule la LIVRAISON compte. # ───────────────────────────────────────────────────────────────────────────── - id: locataire-deployer titre: "Materialiser et deployer la flotte d'un locataire" portee: tenant doc: docs/vm-lifecycle.md but: >- Des VM au service rendu : creer les machines manquantes, deployer couche par couche, puis mesurer. Rien n'est « pret » avant la recette. etapes: - cible: flotte-creer nature: ecriture portee: poste variables: [PARALLELE] fixes: {CONFIRMER: "true"} pourquoi: >- Les VM manquantes, clonees depuis le gabarit dore. VMID, IP et VLAN sont DERIVES du plan : on ne les saisit nulle part. - cible: monter-flotte nature: ecriture duree: "long" fixes: {CONFIRMER: "true"} pourquoi: >- Des VM qui viennent de naitre (ou de renaitre) a la flotte recettee : flux, AC et DNS d'abord, tout le reste, puis `valider`. C'est la sequence du runner apres une reconstruction ; chaque proprietaire d'etat y remet celui d'avant. - cible: deployer-tout nature: ecriture duree: "long" fixes: {CONFIRMER: "true"} pourquoi: >- Toute la flotte, dans l'ordre des couches. L'ordre vient du graphe de dependances, pas d'une liste tenue a la main. - cible: deployer-groupe nature: ecriture variables: [GROUPE] facultative: true pourquoi: >- Un seul role, sur toute la flotte. C'est le geste d'apres : quand un role a change et qu'on ne veut pas tout rejouer. - cible: appliquer nature: ecriture variables: [GROUPE] facultative: true pourquoi: >- Appliquer un groupe a la flotte. Meme usage que `deployer-groupe`, par le chemin court — sans le graphe des couches. - cible: verifier-deploiement nature: mesure pourquoi: "L'etat de la flotte apres coup — avant de croire que c'est fini." - cible: valider nature: mesure pourquoi: >- La recette de validation sur la flotte. C'est elle qui autorise le mot « pret », pas l'absence d'erreur rouge. # ───────────────────────────────────────────────────────────────────────────── - id: machine-une titre: "Ajouter ou reprendre une seule machine" portee: tenant doc: docs/vm-lifecycle.md but: >- Le cycle d'UNE machine, du plan au service : la voir derivee, la creer, la deployer, la verifier. Le meme chemin sert pour une machine neuve et pour une machine a reprendre. etapes: - cible: hote-afficher nature: mesure variables: [HOTE] pourquoi: >- Tout ce que le plan derive pour cette machine — avant de la creer, pour verifier qu'on va bien poser ce qu'on croit. - cible: creer-vm nature: ecriture portee: poste variables: [HOTE] duree: "~4 min 30" pourquoi: "Cloner depuis le gabarit et ATTENDRE que la machine reponde." - cible: deployer nature: ecriture variables: [HOTE] pourquoi: "Les roles de cette machine, couche par couche, dans l'ordre du graphe." - cible: verifier-hote nature: mesure variables: [HOTE] pourquoi: "Le playbook de verification sur cette machine seule." - cible: cloner-vm nature: ecriture portee: poste variables: [HOTE, VMID] facultative: true pourquoi: >- Cloner SANS passer par le plan. Chemin de reprise : a n'emprunter que lorsque le plan ne peut pas encore deriver la machine. # ───────────────────────────────────────────────────────────────────────────── - id: flotte-refaire titre: "Raser et reconstruire un ecosysteme" portee: tenant doc: docs/vm-lifecycle.md but: >- La preuve la plus dure du moteur : detruire un ecosysteme et le refaire depuis le code seul. A ne lancer que sur un chantier — la prod vit ailleurs. etapes: - cible: reconstruire-locataire nature: destructif portee: poste duree: "long" variables: [TENANT, DEPUIS, ARMER] fixes: {CONFIRMER: "true"} pourquoi: >- TOUT, d'une commande, depuis le poste : sauvegarder, raser et recreer (runner du site), amorcer, armer, monter (runner du locataire, etat remis), pare-feu, bilan. Arret a la premiere etape en echec ; `DEPUIS` reprend. Les etapes ci-dessous sont les memes, une a une. - cible: sauvegarder-maintenant nature: ecriture pourquoi: >- Deposer l'etat de chaque noeud JUSTE AVANT de raser. La reconstruction remet le dernier instantane anterieur a la naissance des machines : sans ce depot, c'est celui de la nuit, et la journee est perdue. - cible: raser nature: destructif portee: poste variables: [INSTANCE] fixes: {CONFIRMER: "true"} pourquoi: >- Detruire les VM derivees du plan. Le nom de l'ecosysteme s'ecrit en toutes lettres : c'est le seul garde-fou qui resiste a un clic distrait. - cible: reconstruire nature: ecriture portee: poste duree: "long" fixes: {CONFIRMER: "true"} pourquoi: >- Refaire tout depuis zero : les VM, puis le deploiement complet — ou chaque role proprietaire REMET l'etat de l'incarnation precedente (AC, annuaire, bases, Nextcloud, courriel, DKIM). Si le code ne suffit pas, c'est ici qu'on l'apprend. - cible: restauration-etat nature: mesure pourquoi: >- Ce que chaque jeu est devenu : restaure (et depuis quel instantane), neuf, en place. Un jeu EN ATTENTE bloque la sauvegarde de son noeud — c'est voulu. - cible: restauration-renoncer nature: destructif variables: [HOTE, JEU] fixes: {CONFIRMER: "true"} pourquoi: >- Ecarter l'etat d'avant d'un jeu, sans le remettre. La sauvegarde reprend, et l'ancien etat sortira de la retention : une decision, pas une reparation. - cible: valider nature: mesure pourquoi: "Une reconstruction sans recette n'a rien prouve." - cible: parefeu-verifier-flotte nature: mesure portee: poste variables: [INSTANCE] pourquoi: >- La sonde `connectivite` est-elle saine sur chaque VM ? C'est le prealable : une VM clonee nait sans ses options de pare-feu, et on n'active que sur une flotte saine. - cible: parefeu-activer-flotte nature: ecriture portee: poste variables: [INSTANCE] fixes: {CONFIRMER: "true"} pourquoi: >- Tout activer d'un coup, puis lire la sonde `connectivite` que chaque VM rapporte a la minute : seul ce qui change apres l'activation compte. Environ trois minutes. # ───────────────────────────────────────────────────────────────────────────── - id: gabarit titre: "Le gabarit dore" portee: site doc: docs/procedure-template-debian13-proxmox.md but: >- La VM de reference que toute la flotte clone. Elle nait en q35/OVMF et ne se convertit jamais : convertir depuis i440fx casse interfaces et disques. etapes: - cible: gabarit-etat nature: mesure pourquoi: "Le gabarit porte-t-il ce que le SITE declare ? A regarder avant d'y toucher." - cible: preparer-modele nature: ecriture duree: "long" pourquoi: "Preparer la VM de reference, celle qui sera clonee pour chaque hote." - cible: verifier-modele nature: mesure pourquoi: "Le gabarit tient-il ses promesses avant qu'on le capture ?" - cible: nettoyer-modele nature: destructif fixes: {CONFIRMER: "true"} pourquoi: >- Nettoyer avant capture. Destructif pour la VM de reference : ce qui est efface ne se retrouve pas. # ───────────────────────────────────────────────────────────────────────────── - id: mesurer titre: "Mesurer sans rien ecrire" portee: tenant doc: docs/devis-services.md but: >- Les devis de service : ils confrontent ce que le plan derive a ce que le systeme rend VRAIMENT, et sortent en erreur s'il y a un ecart. Une tache verte ne prouve pas qu'un service rend son service. etapes: - cible: identite-plan nature: mesure pourquoi: "L'identite deployee face a ce que le plan derive." - cible: certificats-plan nature: mesure pourquoi: >- Les certificats sur disque face a ceux reellement SERVIS. Un cert renouvele mais non recharge reste perime en memoire. - cible: expositions-plan nature: mesure pourquoi: "Chaque exposition du plan repond-elle, depuis l'edge et depuis le poste ?" - cible: expositions-etat nature: mesure pourquoi: "Chaque exposition est-elle servie sous un certificat qui la porte ?" - cible: courriel-plan nature: mesure pourquoi: "La chaine Postfix → LDAP → Dovecot → IMAP, de bout en bout." - cible: postgresql-plan nature: mesure pourquoi: "Le chiffrement impose et la portee reelle des acces." - cible: mtu-mesurer nature: mesure pourquoi: "L'invite porte-t-il le MTU de sa zone ? Un MTU faux ne se voit qu'aux gros paquets." - cible: versions-mesurer nature: mesure pourquoi: "De combien nos epinglages ont-ils vieilli face aux amonts ?" - cible: ports-verifier nature: mesure pourquoi: "Deux roles co-localises revendiquent-ils le meme port ?" - cible: intrants-verifier nature: mesure pourquoi: "Un intrant exige et non fourni est une panne differee." - cible: flux-verifier nature: mesure pourquoi: "Le registre des flux correspond-il encore aux `meta/flux.yml` des roles ?" - cible: site-intrants-verifier nature: mesure pourquoi: "Le locataire monte suit-il encore les intrants de son site ?" - cible: sonder nature: mesure variables: [CIBLE] pourquoi: >- Sonder une cible et DIRE ce qui distingue absence, politique et frontiere. Un « echec » nu ecrase ces trois causes et envoie chercher la panne ailleurs. - cible: faits nature: mesure variables: [LIMITE] pourquoi: "Les faits Ansible de la flotte, quand une hypothese demande un fait." # ───────────────────────────────────────────────────────────────────────────── - id: recette titre: "La recette — avant de dire « pret »" portee: tenant doc: docs/audit/plan-de-recette.md but: >- Ce qui separe « ca a tourne sans erreur » de « c'est livrable ». Les preuves lisent le depot ; la recette interroge la flotte. Il faut les deux. etapes: - cible: verifier nature: mesure pourquoi: "Rejouer les preuves sans reecrire le rapport — la verification rapide." - cible: prouver nature: mesure pourquoi: >- Executer les preuves et ECRIRE le rapport date. C'est le document qu'on montre, et celui qu'on relit dans six mois. - cible: valider nature: mesure pourquoi: "La recette de validation sur la flotte reelle." - cible: verifier-deploiement nature: mesure pourquoi: "L'etat de la flotte, apres coup." - cible: inventaire nature: mesure pourquoi: "L'inventaire se verifie et se montre — lab puis production." # ───────────────────────────────────────────────────────────────────────────── - id: acces-admin titre: "L'acces d'administration (tunnel WireGuard)" portee: site doc: docs/acces-administration.md but: >- Un tunnel nominatif par locataire, declare par lui et borne a lui. Sans garde, un ecosysteme s'ouvrirait un acces chez son voisin depuis son propre plan. etapes: - cible: vpn-admin-plan nature: mesure pourquoi: "Ce que la frontiere porte aujourd'hui, face aux pairs declares au plan." - cible: vpn-admin-appliquer nature: ecriture fixes: {CONFIRMER: "true"} pourquoi: "Poser l'instance et les pairs declares — et retirer ceux qui ne le sont plus." # ───────────────────────────────────────────────────────────────────────────── - id: dns-public titre: "Le DNS public et sa signature" portee: tenant doc: docs/dns-interne.md but: >- Publier les zones du locataire, signees avant d'etre exposees. Les DS partent chez le registraire : c'est le seul maillon que le moteur ne peut pas poser lui-meme. etapes: - cible: dnssec-verifier nature: mesure pourquoi: "Une cle en voute pour chaque zone signee, et des DS conformes au registre." - cible: dnssec-ds nature: mesure pourquoi: >- Les DS a remettre au registraire, calcules depuis la voute du locataire. A porter a la main chez le registraire : aucun automate ne le fera. - cible: dns-bascule-devis nature: mesure pourquoi: >- Basculer nos serveurs de noms changerait-il quelque chose ? Le plan face au DNS reellement en service, avant de toucher a la delegation. # ───────────────────────────────────────────────────────────────────────────── - id: filiation titre: "Filiation, insemination, emancipation" portee: tenant doc: docs/filiation-emancipation.md but: >- D'ou vient cet ecosysteme, de quoi depend-il encore, et que faut-il couper pour qu'il tienne seul. L'emancipation se mesure ; elle ne se decrete pas. etapes: - cible: genome nature: mesure pourquoi: "Les depots requis a la reproduction de cet ecosysteme, et leur etat." - cible: genome-inscrire nature: ecriture pourquoi: "Inscrire la parente dans l'instance — sans quoi la filiation n'est qu'un souvenir." - cible: genome-verifier nature: mesure pourquoi: "La parente inscrite tient-elle encore ? Le code de sortie repond." - cible: inseminer nature: ecriture variables: [TENANT, HOTE] pourquoi: >- Le SITE amorce le runner d'un locataire, SANS ses secrets. Trois murs connus : apt, pip, et le genome lui-meme. - cible: depots-perimes nature: destructif fixes: {CONFIRMER: "true"} # FACULTATIVE, SINON ELLE BARRE LA PREUVE QUI LA SUIT. La console # debloque d'office une etape « mesure » ; toute autre attend que la # precedente non facultative ait REUSSI dans la session. Un menage # qu'on peut ne pas avoir a faire — aucun depot perime ce jour-la — # rendrait alors l'emancipation injouable. Le ménage n'est pas un # prealable a la preuve : il nettoie ce que la filiation a laisse. facultative: true pourquoi: >- Un depot raye du plan reste sur le disque du runner, qui garde de quoi lire un ecosysteme qu'il ne declare plus. Trois choses ne sont jamais retirees : ce qui n'est pas un depot git, ce qui porte des modifications non validees, et ce qui porte des commits qu'aucun distant ne porte. - cible: emancipation-prouver # ECRITURE, ET NON MESURE, MALGRE LE MOT « PROUVER ». La cible COUPE # l'amont quelques secondes pour mesurer : elle refuse d'ailleurs sans # CONFIRMER=true, et le dit. Le fait qu'elle rapporte un constat ne la # rend pas inerte. Declarée « mesure », elle se serait offerte a tout # outil qui ne propose que ce qui n'agit pas. nature: ecriture variables: [SERVICE, HOTE] fixes: {CONFIRMER: "true"} pourquoi: >- Prouver qu'un lien est coupe, en le coupant. La coupure est retiree quoi qu'il arrive, mais la fonction eprouvee peut echouer pendant ce temps. La mesure instruit ; l'humain decide. Une emancipation automatique serait une expulsion. # ───────────────────────────────────────────────────────────────────────────── - id: remise titre: "La remise au client" portee: poste doc: docs/remise-au-client.md but: >- Deux temps qui ne se confondent pas : le paquet qu'on remet, puis le re-cle qui mesure la revocation reelle. Tant que le temps 2 n'est pas fait, on detient encore les cles de quelqu'un d'autre. etapes: - cible: remise-recenser nature: mesure pourquoi: "Ce qu'une remise emporterait, sans rien ecrire. A lire avant de fabriquer." - cible: remise-paquet nature: ecriture variables: [VERS] pourquoi: "Temps 1 : le paquet chiffre, et relu apres ecriture." - cible: remise-inscrire nature: ecriture variables: [RECU_PAR, COURRIEL, DANS] pourquoi: >- Inscrire la remise chez le locataire : qui a recu, quand, et dans combien de jours le second temps est du. - cible: remise-verifier nature: mesure pourquoi: "Temps 1 fait ? Temps 2 du, ou echu ? La seule reponse qui compte est datee." - cible: remise-recleer nature: ecriture fixes: {CONFIRMER: "true"} pourquoi: >- Temps 2 : mesurer la revocation REELLE, puis estampiller. On ne coche pas cette case, on la mesure. # ───────────────────────────────────────────────────────────────────────────── - id: cles titre: "Les cles hors du poste" portee: poste doc: docs/sortir-les-cles-du-poste.md but: >- Ce qui n'existe QUE sur le poste meurt avec lui : les CLES, et les VOUTES qu'elles ouvrent (gitignorees, donc sur aucune forge). Les deux sortent, sur un support qu'on relit — et on refait l'operation a chaque voute nouvelle ou modifiee. etapes: - cible: cles-recenser nature: mesure pourquoi: "Ce qui n'existe que sur ce poste, sans rien ecrire. La liste fait peur, c'est le but." - cible: cles-exporter nature: ecriture variables: [VERS] pourquoi: "Sortir les cles, chiffrees, et les RELIRE apres ecriture." - cible: voutes-recenser nature: mesure pourquoi: "Les voutes de ce poste, et leur empreinte. Une voute en clair est refusee avant tout." - cible: voutes-exporter nature: ecriture variables: [VERS] pourquoi: >- Sortir les voutes, deja chiffrees, dans leur propre archive, et la RELIRE. Sans elles, les cles restaurees n'ouvrent rien (2026-09-28). - cible: cles-compagnons nature: ecriture variables: [VERS] pourquoi: >- Deposer le script de restauration sur la cle. Une archive qu'on ne sait pas rouvrir dans cinq ans n'est pas une sauvegarde. - cible: cles-restaurer nature: ecriture variables: [ARCHIVE] pourquoi: "Remettre les cles en place. A eprouver AVANT d'en avoir besoin." - cible: depot-hors-site nature: ecriture variables: [VERS] pourquoi: >- Copier le depot de sauvegarde HORS du site. Le site heberge du chiffre et ne peut pas le juger : la verification suit la cle. # ───────────────────────────────────────────────────────────────────────────── - id: lire-le-plan titre: "Lire le plan et ce qu'il derive" portee: tenant doc: docs/plan-et-generation.md but: >- Tout ce qui se regarde sans rien changer : les registres du plan, leur validation, et l'inventaire qui en descend. Le premier geste devant un ecosysteme qu'on ne connait pas. etapes: - cible: serveurs nature: mesure pourquoi: "Les serveurs declares au plan." - cible: serveurs-verifier nature: mesure pourquoi: "Le registre des serveurs tient-il ses regles ?" - cible: applications nature: mesure pourquoi: "Les applications declarees au plan." - cible: applications-verifier nature: mesure pourquoi: "Le registre des applications tient-il ses regles ?" - cible: bases nature: mesure pourquoi: "Les bases de donnees declarees au plan." - cible: bases-verifier nature: mesure pourquoi: "Le registre des bases tient-il ses regles ?" - cible: domaines nature: mesure pourquoi: "Les domaines declares au plan." - cible: domaines-verifier nature: mesure pourquoi: "Le registre des domaines tient-il ses regles ?" - cible: inventaire-lister nature: mesure pourquoi: "L'inventaire complet, en JSON — la verite generee." - cible: inventaire-graphe nature: mesure pourquoi: "Le graphe des groupes : qui herite de quoi." - cible: inventaire-hote nature: mesure variables: [HOTE] pourquoi: "Les variables derivees d'une machine, telles qu'Ansible les verra." - cible: inventaire-lab nature: mesure pourquoi: "Le graphe de l'inventaire de laboratoire." - cible: inventaire-production nature: mesure pourquoi: "Le graphe de l'inventaire de production." - cible: config nature: mesure pourquoi: "La configuration Proxmox telle que le moteur la lit." # ───────────────────────────────────────────────────────────────────────────── - id: depot-verifier titre: "Verifier le depot avant de livrer" portee: toute doc: AGENTS.md but: >- Ce que le depot se doit a lui-meme : syntaxe, lint, tests, schema, fiches. Rien n'est « pret » sans au moins la syntaxe du playbook touche et l'entree de CHANGELOG. etapes: - cible: syntaxe nature: mesure pourquoi: "La syntaxe de TOUS les playbooks. Jamais declarer pret si elle echoue." - cible: lint nature: mesure pourquoi: "`ansible-lint` sur tout le depot." - cible: test nature: mesure pourquoi: "Les tests unitaires de derivation — nomenclature et inventaire." - cible: ci nature: mesure pourquoi: >- Verifier le depot comme la CI, sur un modele public monte a l'ecart : sans jamais toucher a l'ecosysteme monte. - cible: schema nature: ecriture pourquoi: >- Regenerer le schema du plan depuis les registres et les validateurs. C'est lui qui construit les formulaires : un champ nouveau apparait sans toucher a l'interface. - cible: fiches nature: ecriture variables: [ROLE] pourquoi: "Regenerer la fiche de chaque role, depuis le role lui-meme." - cible: plan-recette nature: ecriture pourquoi: "Regenerer le plan de recette depuis le wiki." - cible: wiki-publier nature: ecriture pourquoi: "Publier le wiki vers la forge, une fois qu'il dit vrai." # CE QUE LA CONSOLE N'OFFRE PAS, ET POURQUOI. Une exemption muette serait un oubli # deguise : chaque ligne porte son motif, et la garde refuse une exemption vide. hors_assistant: aide: >- Aide en ligne de commande. La console porte la meme information autrement — chaque etape affiche le libelle lu dans le Makefile. ansible-runtime: >- Prerequis interne, appele par les cibles qui deploient. L'offrir seul donnerait un bouton qui ne fait rien de visible. inventaire-ui: >- C'est cette console elle-meme. Un bouton qui la relance depuis elle-meme n'a pas d'objet. syntaxe-modele: "Couverte par `syntaxe`, qui passe tous les playbooks d'un coup." syntaxe-verification-modele: "Couverte par `syntaxe`." syntaxe-nettoyage: "Couverte par `syntaxe`." syntaxe-verification-hote: "Couverte par `syntaxe`." syntaxe-groupes: "Couverte par `syntaxe`." syntaxe-proxmox: "Couverte par `syntaxe`." model-creer: >- Fabrique un MODELE d'ecosysteme — un geste de mainteneur du moteur, pas d'exploitant. Il se fait au poste, en connaissance du catalogue des modeles. serveurs-bootstrap: >- Chemin de REPRISE : reconstitue le plan depuis un inventaire existant. Il ecrit par dessus le plan, et ne doit pas etre a un clic d'un exploitant qui explore. applications-bootstrap: >- Meme raison que `serveurs-bootstrap` : amorcage de reprise, pas geste courant. cacher-paquets: >- Se fait EN LIGNE depuis le poste, avant de partir sur un site hors ligne. Le runner, lui, est deja derriere la frontiere : le bouton serait au mauvais endroit. ca-racine: >- Recupere la racine de l'AC pour l'installer sur un poste. L'empreinte doit etre verifiee A LA MAIN avant installation — un bouton encouragerait a sauter ce controle. ca-empreinte: >- Le temoin de comparaison de `ca-racine`. Meme raison : il se lit, il ne se clique pas.