Un ecosysteme pouvait DETENIR son genome sans savoir l'executer. Le poste
d'exploitation porte Ansible epingle, le genome clone depuis SA PROPRE forge, et
une cle SSH qui n'appartient qu'a lui. Il n'emporte ni la voute ni son mot de
passe : la structure se reconstruit depuis la forge, les secrets depuis la
sauvegarde. Deux sources qu'un meme incident n'atteint pas ensemble.
Une machine neuve traverse tout le moteur sans rien heriter, et revele ce qu'un
etat anterieur masquait. Deux defauts silencieux en sont sortis.
setops_plan_dir pointait le lien `instance` en dur : neuf roles lisaient donc le
plan d'une AUTRE instance. Le plancher de patient 0 portait les FQDN de
Chezlepro, et son edge publiait server_name forge.chezlepro.internal. La
variable suit desormais l'inventaire reellement charge.
Trois instances sur quatre declaraient les SAN d'exposition de leur edge ; la
quatrieme et le modele public ne les avaient pas. La forge de patient 0 etait
donc publiee derriere le certificat auto-signe de Debian, sans que rien ne le
signale -- `git clone` fut le premier a refuser, a juste titre. P42 le reclame
maintenant pour tout ecosysteme qui declare un edge.
Le harnais a ecrit la moitie de ce role : 5 echecs sur la piece neuve, aucun
n'empechait le code de tourner, tous la rendaient invisible a la carte, au
graphe et au lecteur. 42 preuves, 0 echec.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`catalogue-services.md` est le document qu'on lit pour savoir ce que Set-OPS FAIT :
l'hebergeur d'un second site, un futur client, un mainteneur qui arrive. Verifie role par
role contre roles/, voici ce qu'il disait de faux.
- « Capacites futures encore a implementer : collaboration (Nextcloud/Collabora) et couche
web (frontal/dorsal) » — les quatre roles existent, collab-01, web-frontal-01 et
web-dorsal-01 sont ACTIFS, et les deux roles web sont codifies depuis les spikes du
2026-07-05.
- « La federation LDAP n'est pas automatisee dans le role ; Keycloak n'est pas expose » —
serveur_keycloak/tasks/federation-ldap.yml existe, et le plan declare
`expose: auth.<domaine>`.
- `infra-mail-01` : « Sendmail MTA » — c'est Dovecot ; Sendmail est retire depuis le
2026-07-04. La table des hotes datait d'avant la separation edge-mta / mailstore.
- `client_supervision` annonce comme integration — n'a JAMAIS eu ni role ni playbook. La
supervision ne pose rien sur les hotes : controles actifs depuis le coeur, resultats
passifs pousses par l'API (c'est backup-01 qui rapporte l'etat de ses depots).
- Une colonne « Role » decorative inventait des noms (`nextcloud`, `client_metriques`) : le
role porte le nom du GROUPE. Colonne retiree.
Et NEUF roles vivants ne figuraient dans aucune table — le socle, toute la pile courriel,
les sauvegardes, Icinga Web 2, oauth2-proxy, Unbound. Deux (`serveur_backup`,
`client_backup`) n'etaient nommes NULLE PART.
P38 — CE QUE P31 NE POUVAIT PAS VOIR. P31 verifie que tout est nomme et atteignable, pas
qu'un document dise vrai : une carte peut etre complete et perimee. P38 confronte le
catalogue au code dans les deux sens, et c'est la TABLE qui fait foi des deux cotes : tout
role figure dans une ligne de table (la prose ne suffit pas — la pile courriel y etait
racontee et introuvable pour qui lit un index), et tout groupe cite en table existe
reellement (role, ou playbook de groupe pour `serveur_durci`, qui en compose onze).
Deux exemptions nommees : la prose peut citer les roles RETIRES, sinon on ne peut plus
ecrire d'ou l'on vient ; et P38 ne juge pas si une description est JUSTE — cela se revoit
contre le CHANGELOG, le mecaniser serait se mentir.
EPROUVEE EN NEGATIF : rejouee contre la version d'avant, elle echoue en nommant les neuf
roles absents et les trois cases fantomes.
Le catalogue dit aussi desormais ou il s'arrete : la reconstruction prouve qu'une machine
nue atteint l'etat voulu, pas la tenue sous charge ; et l'usage reel de Nextcloud n'est pas
consigne comme preuve. Lacune nommee au passage : la dependance causale
serveur_web_frontal -> serveur_nginx n'est toujours pas declaree.
make prouver : 38 OK, 0 echec, 0 saute. make test inchange.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
La refonte de ce matin posait une convention. Une convention qu'on n'outille
pas tient tant que quelqu'un y pense : c'est le raisonnement de D-70, applique
au corpus documentaire.
Etat de depart mesure : 2 documents sur 34 declaraient leur lecteur. Les 32
autres disaient leur SUJET — ce qui avait enfoui le runbook de reprise le plus
utile du depot au §6 de autorisation.md.
Les 38 le declarent desormais, lecteur determine document par document et non
colle au gabarit : l'exploitant (devis, migration de tenant, cycle de vie,
gabarit d'or), le mainteneur (conceptions, registres, carte), le lecteur
externe (ecosysteme-chezlepro), l'agent IA (MISE-A-JOUR-CODEX-CLAUDE).
Deux exemptions DERIVEES, pas listees — un chemin en dur aurait vieilli a la
premiere page ajoutee : un document qui s'annonce genere, et un fragment sans
titre. Les 13 exemptes verifies un par un ; aucun document ecrit a la main
n'est exempte par accident. La preuve ne lit que l'EN-TETE, ce qui empeche
frontiere-opnsense.md et plan-et-generation.md — qui parlent de generation
dans leur corps — d'etre exemptes a tort.
Eprouvee dans les deux sens. Elle a echoue seule des sa premiere execution en
nommant deux documents que mon inventaire avait manques (docs/audit/). Puis
test negatif delibere : declaration retiree de meta-classe.md -> ECHEC la
nommant ; restauree -> OK.
Ce qu'elle ne teste pas : que le lecteur declare soit le BON. Ca se juge en
revue ; elle garantit qu'on a du y penser.
P01–P34. Comptes perimes corriges au passage (AGENTS.md et devis-services.md
annoncaient encore 30 preuves).
Verifie : prouver.py 0 (34 OK), plan-recette inchange.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Supprimés : roles/{applications,backup,database,identity,monitoring,
proxmox,storage,web}/ (README seuls, taxonomie abandonnée — l'archi est
plate serveur_*/client_*) et les playbooks-échafaudages debug sans rôle
(nextcloud, collabora, client_supervision, web_frontal, web_dorsal).
Aucun host n'utilise ces groupes ; l'intention des capacités futures
reste documentée dans docs/catalogue-services.md.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
oauth2-proxy (v7.15.3) place Keycloak devant toute app sans OIDC natif
(auth external, utilisateur via en-tête). Rôle paramétrable, réutilisable.
Éprouvé devant icingaweb2 (backend=external, X-Forwarded-Preferred-Username).
Prouvé : testmail → oauth2-proxy → Keycloak → icingaweb2 /dashboard,
connecté. Ferme le gap LDAP-direct d'icingaweb2.
Réglages appris : insecure_oidc_allow_unverified_email (IdP interne) ;
reverse-proxy passe X-Forwarded-* pas X-Auth-Request-* ; handler nginx en
restart (pas reload) — un changement d'adresse d'écoute n'est pas pris par
un reload gracieux.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
serveur_icingaweb2 installe + active businessprocess, crée le répertoire
des processus (éditable UI) et sème des processus BPM en IaC
(serveur_icingaweb2_bpm_processes). Format host;service éprouvé via les
fixtures du module.
Prouvé : processus « Supervision Chezlepro » (roll-up load/procs/swap/
ping4/ssh en ET) rend un état dans l'UI, backend IcingaDB (pas d'IDO).
Rôle re-prouvé (reset → recrée le processus). Pile Icinga = moteur +
Web 2 + BPM.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
App PHP (php8.4-fpm) + nginx local, exposée par l'edge (auto-dérivé).
Config par fichiers .ini (config/resources/authentication/roles + module
icingadb), pas d'assistant. Base IcingaDB via resoudre_base. Auth LDAP
direct (client_pki sur sup-01) — pas d'OIDC natif (SSO-proxy = raffinement).
Prouvé : testmail (LDAP) se connecte (/dashboard), module IcingaDB affiche
la supervision (hôte icinga). Déploiement failed=0 (frictions dans le
simulateur curl, pas le rôle). Reste : module BPM.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Déployé sur data-sql-01 : service actif, :6379, requirepass (vault_redis)
— accès sans auth refusé (NOAUTH), SET/GET avec auth OK. 🔧→⭐
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
serveur_grafana : config OIDC via GF_AUTH_GENERIC_OAUTH_* (client grafana,
realm chezlepro, secret vault_grafana_oidc). serveur_loki/prometheus/grafana
déployés sur obs-01. Fix serveur_loki : créer le groupe loki (paquet crée
l'user en nogroup).
Prouvé (flux authorization code headless via l'edge) : testmail (LDAP) se
connecte à Grafana par le SSO ; /api/user renvoie login/email/name fédérés
depuis LDAP. Chaîne LDAP → Keycloak → Grafana.
Gaps notés : enregistrement du client OIDC dans Keycloak fait via kcadm à la
main (à codifier) ; résolution keycloak→edge sur obs-01 = /etc/hosts manuel
(PowerDNS devrait porter les A d'exposition) ; mapping de rôles Grafana.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
PostgreSQL (data-sql-01) : écoute réseau + pg_hba VLAN, provisionne la
base keycloak depuis le registre bases-donnees.yml → binding app→base
prouvé en réel (base + rôle créés, mdp vault_bd_keycloak).
Keycloak 26.0.7 (id-sso-01) : mode prod, connecté à PostgreSQL (87 tables
du realm master écrites), token admin obtenu (auth adossée à la BD).
Maturité rafraîchie. Lacunes connues : fédération LDAP + edge nginx pas
encore câblés. Reste : DRY du bloc de résolution BD.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Après audit du dépôt : docs/carte-set-ops.md = point d'entrée « à lire
d'abord » (index du corpus) + catalogue des mécanismes transverses (2
directions de binding, pont de cert, résolution BD par registre,
socle-first, check-mode, voûte) avec où ils vivent. But : ne plus
re-découvrir l'existant.
Constat : la cruft était déjà inventoriée dans catalogue-services.md
(rôles-catégories inertes, échafaudages) — référencée, pas dupliquée.
catalogue-services « État d'implémentation » rafraîchi (rôles éprouvés
sur VM réelles : socle, PKI, LDAP, DNS, nginx, pile courriel).
Pointeur ajouté depuis architecture-set-ops.md.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>