Commit graph

345 commits

Author SHA1 Message Date
4f5a0b5696 pare-feu proxmox : poser les objets, puis activer VM par VM
--objets-seulement et --vm <vmid> : aucune des 26 VM des locataires n avait son
pare-feu actif ; tout activer d un coup ouvrait 26 pannes possibles a la fois.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 13:25:29 -04:00
0156596f01 P02 : une table du plan ne se coupe plus a son premier commentaire
_fusion_table traversait mal les commentaires interieurs a une entree :
chezlepro.ca (DNSSEC) etait coupee et ses enregistrements pris pour des entrees.
make verifier : CONFORME, 83 OK, 0 echec.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 13:17:52 -04:00
5f52dcb2b7 wireguard : rotation des cles de daniel-portable, sans afficher de privee
cle-appareil et config --cle/--vers ecrivent les secrets en 0600 ;
--portee restreint appliquer au tunnel vise. Nouvelles cles en service,
anciennes retirees, Technolibre intact.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 12:57:15 -04:00
4855cda294 voutes : elles sortent du poste, dans leur propre archive, relues
exporter_voutes.py et make voutes-exporter : les six voutes (gitignorees, sur
aucune forge) sont sur la cle USB, a cote des cles ; restauration eprouvee.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 12:53:14 -04:00
0551c4b4de exportateur postgresql de chezlepro pose ; les voutes ne sont pas sur les forges
vault_pg_exportateur ajoute a la voute de Chezlepro (hors depot), role redeploye,
pg_up 1 : plus aucun critique. La voute a ete redeposee sur le runner. Deux
phrases qui disaient les voutes repliquees sur les forges sont corrigees.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 12:41:14 -04:00
f5adffb0de sondes conditionnelles : attendues seulement la ou elles sont posees
seulement_si dans meta/supervision.yml, lu par le gabarit Icinga des sondes ;
garde test_sondes_conditionnelles. journaux-frontiere ne rougit plus a vie chez
les locataires ; Technolibre sans critique.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 12:31:17 -04:00
185b000c60 icinga : un service passif qui n a jamais rien recu passe au rouge
Gabarit setops-rapport-attendu : actif, dummy critique, check_interval = le
ttl que le noeud envoie. Prouve a t+60 s sur site-mon-01, deploye sur les trois
Icinga ; la garde test_fraicheur_icinga lie seuils et ttl.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 12:05:15 -04:00
478aab3eb8 pare-feu Proxmox : force dans l URL, et le retrait de t29 est pose
Proxmox refuse un corps sur DELETE (501) : aucun IPSet n etait jamais retire
par l applicateur. SDN, frontiere et pare-feu Proxmox ne portent plus rien de
l index 29 ; le journal dit comment, et ce qui reste (strophe FRR).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 10:08:22 -04:00
badbcd3971 pare-feu Proxmox : un tenant retire sort du perimetre, ses objets aussi
Les IPSets et groupes t29- restaient poses : le perimetre ne retenait que
les prefixes des tenants presents. Les etiquettes des zones retirees
(ANCIEN_NOMMAGE du SDN) y entrent, pour etre retirees. Et un cluster muet
arrete le plan au lieu de se lire vide.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 09:58:42 -04:00
fde604c2a5 pare-feu et pools Proxmox : les tenants du site, pas toute la federation
Les deux devis balayaient tous les dossiers freres. Le runner du site, qui
gardait un clone de patient 0, proposait de recreer ses groupes t29 ; le poste
comptait un dossier de CI comme tenant. La frontiere et le SDN filtraient deja
par underlay.tenants : ces deux-la suivent maintenant la meme liste.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 09:57:06 -04:00
6a7188290f sdn : un cluster muet n est pas un cluster vide, et t29 se retire
Le poste coupe du site, sdn-plan annoncait a creer : 33 — toutes les zones,
Chezlepro comprise. Une lecture en echec rendait un dict d erreur, que rep or []
parcourait comme une liste vide. La lecture s arrete maintenant, comme la frontiere.

t29 rejoint l ancien nommage : sortie du devis sans cela, la zone aurait ete
lue comme etrangere et laissee en place, avec ses VLAN 1291-1296.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 09:34:20 -04:00
c0f610be33 patient 0 efface : l index 29 est libere, et le site n ouvre plus rien a 10.29.0.0/16
Ses machines n existaient plus depuis le 2026-09-06 (D-83), mais son plan
restait sur disque : la federation lui reservait l index 29 et quatre machines
du site lui ouvraient SSH, apt, DNS et HTTPS. Les commentaires et documents
vivants gardent leur lecon sans le nommer ; les archives restent telles quelles.

Pas encore sur le reseau : les regles regenerees attendent le runner du site.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 21:55:27 -04:00
1d07a6cf80 runbooks : la recette tranche, le registre ne se compare plus a lui-meme
Un outil tiers veut n'offrir de ce moteur que ce qui n'agit pas. Le seul champ
qui le lui dise est `nature`. Il fallait donc qu'il ne mente pas, et il mentait
dans les deux sens.

`filiation` → `emancipation-prouver` se declarait « mesure » en portant
`fixes: {CONFIRMER: "true"}`. La cible tranche elle-meme — son refus dit
« cette preuve COUPE l'amont quelques secondes pour mesurer ». Un constat
rapporte ne rend pas inerte le geste qui l'obtient : l'etape passe a
`ecriture`.

Dans l'autre sens, trois cibles — flotte-creer, deployer-tout, reconstruire —
refusent sans confirmation sans que le registre le declare : un assistant les
lancait telles quelles, et sortait en 2. Comparer `nature` a `fixes` ne les
voyait pas, car c'est comparer deux champs ecrits par la meme main. `verifier`
lit desormais la RECETTE, qui ne ment pas.

Effet de bord traite : une etape qui agit barre celles qui la suivent dans la
console, alors qu'une « mesure » se debloque d'office. `depots-perimes` est
marque `facultative` — il nettoie ce que la filiation a laisse, il n'en est pas
le prealable.

`lister --json` rend le registre assemble d'un bloc, et le drapeau est refuse
hors de son action : rendre la prose humaine a qui demande du JSON est pire
qu'un refus. L'affichage humain ne bouge pas, et la preuve mesure ce qu'il
PORTE — un identifiant, un libelle, les marques de nature — et non seulement
qu'il n'est pas du JSON.

Valide : `verifier` a 0 ecart, test_runbooks.py 25/25, et sept des neuf
epreuves de `make test` ; test_raser et test_raser_resultat echouent sur
« Aucune instance montee », avant comme apres. Mesure : 127 etapes, dont 84 de
nature « mesure » — la surface qui n'agit pas.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RbXr5vv4Rat6PCPGG9GoG8
2026-09-25 17:54:03 -04:00
d461492623 adressage : le site est une flotte, et P20 le regarde enfin
L'exploitant a demande si l'adressage derive ne valait pas pour toute flotte, site compris.
Oui — decision du 12 septembre, index 37 pour le site. J'avais affirme le contraire a
l'entree (11) du CHANGELOG, en recopiant un commentaire perime de huit jours au lieu de
mesurer. Un commentaire perime se propage : celui-la s'etait aussi loge dans la docstring de
ConsoleSite.

P20 s'appelle « Adressage 100% derive du seed (aucun stocke) » et sa portee etait
« l'instance liee + les modeles » : elle ne regardait jamais le site, qui stockait
sous_reseau et passerelle pour ses sept zones. Elle juge desormais les deux natures d'un
underlay et refuse une entree qui ne declare pas la sienne — on ne peut pas juger ce qu'on
ne sait pas lire. Controle negatif joue : une zone remise a 10.36.31.0/24 est refusee, en
nommant l'index dont elle aurait du descendre.

Le loader derive sous_reseau et passerelle a la lecture, pour que rien ne change chez les
consommateurs. Mesure : 14 valeurs retirees du fichier, zero ecart sur ce qu'ils lisent, et
make underlay, devis-sdn et devis-reseau passent.

Valide : make test a 0 echec, P20 verte sur 2 nomenclatures et 7 zones de site. P02 et P60
restent, pour les raisons deja consignees.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-20 22:46:43 -04:00
cd0f94a50b console : un tronc, deux branches — assembler deux fois est ce qui fait deriver
Il y avait deux assembleurs de charge, un par sorte de console. Ils ont derive deux fois le
meme jour : en forme (serveurs valait [] d'un cote et {} de l'autre, et charger() levait),
puis en contenu (cinq registres servis vides alors que le site a SON plan — 9 serveurs,
21 applications, 2 bases, 1 domaine, tous invisibles).

Console assemble, une seule fois, et fixe les clefs et leurs formes. Les branches ne
decident que de ce qui leur appartient : d'ou vient le plan, d'ou vient l'inventaire, quels
pouvoirs elles portent. ConsoleLocataire configure, ConsoleSite materialise et sert
desormais son propre plan, ConsolePoste herite du locataire et sait en plus sur quelle
fabric poser.

Le role et la portee ne se confondent pas : le role est une propriete de la classe, la
portee se calcule depuis les pouvoirs. Un poste prive de la voute du site reste l'atelier du
mainteneur et n'engendre pourtant rien. Le decoupage a montre un trou aussitot : ConsolePoste
heritait du refus d'un locataire — « elle ne sait pas sur quelle fabric poser » — alors qu'il
monte la carte ; ce qui lui manque est la voute, et accuser la mauvaise absence fait chercher
au mauvais endroit.

Le jugement des assistants remonte dans le tronc : il etait ecrit dans la route qui liste ET
dans celle qui execute, et celle qui se trompe est toujours celle qui execute.

Valide : make test a 0 echec, 8 tests de rendu sous node dont deux neufs, console lancee pour
de vrai (13 serveurs, 24 applications, 17 runbooks, 127 etapes, 0 ecart). make verifier a
aussi attrape une faute que j'avais laissee passer sur depots_perimes.yml — risky-shell-pipe,
corrige. P02 et P60 restent, et P60 demande une republication du wiki.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-20 21:55:49 -04:00
859ac07a54 console de site : un vide doit avoir la forme de ce qu'il remplace
La console du runner de SITE-Chezlepro ne montrait rien. Elle a douze machines.

inventaire_api sert serveurs en LISTE, inventaire_api_du_site le servait en TABLE. Les deux
sont vides et la page ne les lit pas pareil : (data.serveurs || []).map trouve {} — truthy,
sans .map — et charger() leve. La console d'un site mourait avant sa premiere vue, et le
message accusait une methode manquante plutot qu'une forme qui ment.

Et la vue regardait au mauvais endroit : le registre vide est voulu, mais la page en tirait
le message d'un locataire sans serveurs et les douze machines servies dans hotes n'etaient
dessinees nulle part. Une console de site dessine desormais SES machines, en lecture seule,
avec leur adresse, leur VMID, leurs roles et leur point de vie ; le panneau droit dit ce
qu'elle peut et renvoie aux Assistants.

C'est le defaut du 16 septembre par une autre porte : la premiere fois l'inventaire etait
vide et la page dessinait ce vide comme un plan vide ; cette fois il est plein et c'est la
vue qui regarde ailleurs.

Ce qui a trouve la cause n'est pas une lecture mais le BANC : en donnant pour la premiere
fois a test_rendu_gui la charge d'une console de site, il a leve sur charger(). Sans lui
j'aurais livre une vue juste par dessus un charger() qui leve.

Valide : node --check sur le bloc script, 7 tests de rendu dont deux neufs, make test a 0
echec, runbooks.py verifier a 0 ecart, P81 et P83 vertes. P02 reste en echec pour la raison
anterieure.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-20 20:36:00 -04:00
4188cf5b6f la console mesure le pouvoir sur la voute, pas sur la carte
Le document des responsabilites attache chaque pouvoir a une voute : calculer n'en demande
aucune, configurer demande celle du tenant, materialiser celle du site. Le code lisait les
symlinks, c'est-a-dire les cartes. Le runner de Chezlepro-locataire montait la carte du
site sans en avoir jamais eu la voute : sa console se declarait poste et offrait 126 etapes
sur 126. Ces gestes seraient partis puis tombes sur un secret vide — un echec au milieu du
chemin, la ou un refus net aurait dit la verite avant de commencer.

contexte() derive desormais les pouvoirs des voutes presentes, et la portee decoule des
pouvoirs au lieu de les preceder. On ne prouve pas qu'une voute s'ouvre, le mot de passe se
tape a l'execution ; mais son absence est decisive et se mesure sans rien ouvrir. Lire une
carte reste permis : le pouvoir fabric suit toujours le symlink, consulter un miroir n'est
pas engendrer.

serveur_ops retire aussi le lien quand la fabric n'est plus declaree — il ne retirait rien,
et un runner gardait le pouvoir que son plan ne lui donnait plus. Il ne retire qu'un lien,
jamais un fichier : une vraie carte a cette place n'a pas ete ecrite par ce role, et il le
dit plutot que de detruire ce qui n'est pas le sien.

Valide : syntax-check et ansible-lint sur le role (profil production, 0/0), make test a 0
echec, P81 et P83 vertes. Six tests montent quatre faux disques et exigent la portee qui
leur revient, dont le defaut lui-meme : carte presente, voute absente, portee tenant.

Limite : P02 reste en echec pour la raison anterieure deja consignee.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-20 20:12:18 -04:00
d3a8124777 assistants : la portee se pese a l'etape, pas a la sequence
Mesure sur la console de TechnoLibre, portee tenant : 6 runbooks conduisibles sur 17, et
parmi les onze fermes, locataire-deployer et machine-une — c'est-a-dire le travail
quotidien d'un locataire. La cause : flotte-creer et creer-vm engendrent des VM et
exigent la fabric, et une portee declaree pour toute la sequence faisait basculer avec eux
des etapes voisines qui ne demandent que ce que le locataire possede deja.

Le runbook ne donne plus que le defaut ; l'etape qui exige davantage le declare. Le
locataire conduit sa sequence et bute precisement la ou il faut : sur la machine a
engendrer, pas sur le deploiement qui suit. La page ferme l'etape seule avec sa raison, et
la garde de la route lit la portee de l'etape visee par son index.

Un droit calcule sur l'ensemble se trompe toujours dans le meme sens : il refuse a
quelqu'un ce qu'il a le droit de faire, et le refus parait fonde puisqu'il nomme un vrai
manque. Il a fallu une console de locataire reelle pour le voir — sur le poste, qui porte
les deux liens, les dix-sept sequences s'affichaient conduisibles.

Valide : runbooks.py verifier a 0 ecart, make test a 0 echec (4 tests neufs, dont un qui
nomme le cas exact), P83 verte. P02 reste en echec pour la raison anterieure deja consignee.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-20 19:55:02 -04:00
f33b5be151 assistants : cent trente-deux cibles, et aucune ne disait dans quel ordre
La console offrait des boutons sans sequence. Rien n'y apprenait que site-creer precede
forge-amorcer, que le premier passage de site-deployer-tout s'arrete sur une forge vide
sans que ce soit un echec, ni que rien n'est pret avant valider : cet ordre vivait en
prose dans des documents que la console ne porte pas.

La vue Assistants conduit 17 runbooks et 126 etapes. Les 132 cibles documentees y sont,
chacune portee par un assistant ou exemptee avec son motif — une exemption muette est
refusee. Le registre ne recopie pas le Makefile : il declare l'ordre, la nature, la portee
et le pourquoi, et le libelle de chaque etape est lu dans le Makefile au moment de servir.

P83 est ecrite en meme temps que la liste, pas apres, parce qu'une liste qui suit une
autre prend du retard. Onze tests lui presentent des registres faux, un par forme de
retard, et exigent qu'elle les refuse.

Le navigateur ne nomme pas une commande, il nomme une place : la route lance ce que le
registre declare a cet index-la, avec les seules variables declarees. L'index compte, le
premier jour d'un site jouant site-deployer-tout deux fois. Une etape qui ecrit attend que
la precedente ait reussi ; une mesure reste toujours offerte, parce que mesurer apres un
echec est exactement ce qu'on fait ensuite.

Valide : runbooks.py verifier a 0 ecart, make test a 0 echec, les 83 preuves rejouees, et
la console lancee pour de vrai — 17 runbooks servis, six requetes malformees refusees une
a une, une etape de mesure executee de bout en bout avec son journal.

Limite, anterieure a ce travail : P02 (test_ecriture_plan) echoue sur domaines.yml, a
l'identique sur une copie de HEAD. Ajouter ou retirer un domaine public depuis la vue
Domaines leverait a l'enregistrement. Non corrige ici.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-20 16:31:16 -04:00
05b85ebd27 tunnel d'administration : TechnoLibre servi, et l'oeuf et la poule du premier pair
`pair-nouveau --locataire` refusait de proposer une adresse a un ecosysteme sans aucun pair,
soit exactement le premier. Le kit remis au client derive tout ce qu'il affiche.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 16:08:39 -04:00
be8c3917e5 acces d'administration : un tunnel par locataire, declare par lui, borne a lui
plan/acces.yml chez le locataire (cles publiques), reseau/port/instance derives de l'index.
La garde du devis refuse qu'un tunnel de locataire vise autre chose que son supernet : sans
elle, un ecosysteme s'ouvrirait un acces chez un voisin depuis son propre plan.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 16:01:54 -04:00
2a276fb6b4 tunnel d'administration : le SSH du site et la console de la frontiere manquaient
Eprouve en production : les locataires repondaient, le site non — son SSH vient de `flotte`
et vivait du rebond par la frontiere. Et rien ne designait la frontiere elle-meme, si bien
que monter le tunnel faisait perdre le moyen de le corriger. Une regle par port : OPNsense
refuse deux ports dans un champ.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 15:26:23 -04:00
d90513ca91 acces d'administration : un tunnel WireGuard nominatif, pas le runner en rebond
Le runner detient la voute et les cles SSH : en faire la porte des humains reunirait deux
pouvoirs que le depot separe. Instance `admins` a cote du tunnel site-a-site, un pair par
personne et par appareil, cles publiques seules au plan. Le reseau du tunnel est un reseau
d'administration : pare-feux d'hote, contrat des locataires et regles de bordure en derivent.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 14:42:48 -04:00
ee386dca00 materiel : la frontiere expose ses temperatures, seul le Prometheus du site les lit
os-node_exporter sur la patte de supervision, declare dans la carte du boitier : cible et
hote Icinga en derivent. Les flux vers la frontiere ne s'ouvrent plus a tous pour un role
qui n'est pas le socle.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 10:20:46 -04:00
49ceb81a4d materiel : un catalogue de capteurs, un tableau Grafana, un verdict Icinga
Les hyperviseurs exposaient temperatures, ventilateurs, SMART et usure NVMe sans que rien
les regarde. scripts/materiel.py porte capteurs et seuils ; Grafana en tire le tableau
Materiel, Icinga un service materiel par hyperviseur. Premier verdict : le disque sda de
gandalf (OSD Ceph) a 56 secteurs en attente, stables.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 10:13:43 -04:00
c1d0d9b1a7 frontiere : publier un service du site, port public et redirection
Un flux externe porte port (la machine) et port_public (l'Internet). Le devis emet la
redirection et sa regle WAN, garde qu'elles aillent ensemble ; l'applicateur reconcilie
d_nat et encode les champs imbriques. DNS public : WAN:53 -> site-dnspub-01:1053 (dnsdist).
Plan lu : 4 objets a creer, rien d'autre ; pas encore applique.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 22:38:39 -04:00
712ad9f630 DNSSEC : le locataire signe, avec la cle de sa voute
Cle CSK ECDSA P-256 tiree dans la voute du locataire, importee par le role, DS calcule
sans la machine. Refus de changer la cle ou de retirer la signature tant qu'un DS est
publie. SOA-EDIT EPOCH : INCEPTION-EPOCH aurait laisse expirer les signatures du site.
CAA sur chezlepro.ca, sonde des signatures au site, P18 deplie vault_dnssec_<zone>.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 22:09:21 -04:00
63780645a7 zones publiques : le courriel dans la zone, et un devis avant de basculer
Une zone publique ne portait que des A d'exposition ; basculer chezlepro.ca aurait coupe
son MX, son SPF et son DMARC. Les enregistrements se declarent au plan, valides et rendus ;
le serveur de noms porte le nom que le site declare (dns1.chezlepro.ca), parce que
ns1.chezlepro.ca existe deja en production. make dns-bascule-devis compare le plan au DNS
en service : 0 perdu sur les deux zones, deux prealables restants.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 21:54:49 -04:00
19bbadfb11 DNS public en production : cinq fautes que seule la production montrait
Applicateur de frontiere : ecrire n est pas charger, le chemin rien a faire charge
desormais. site-verifier compare enfin playbooks/site.yml, regenere avec le groupe.
Base TSIG dans un repertoire a pdns et pdnsutil en pdns (journal SQLite). Flux UDP 5300 :
le secondaire demande le SOA avant de transferer, garde dans P82. socket-dir de
pdns@public, et le failed_when qui taisait la notification est retire. Eprouve sur les
machines : 2 zones sur 2 tirees automatiquement, NOTIFY compte, zone interne refusee.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 18:35:36 -04:00
788c5073dc DNS public, phase 1 : le locataire ecrit, le site sert
Role serveur_dns_public (secondaire public, transfert signe TSIG, aucune zone interne) ;
serveur_powerdns exerce enfin autorite primaire-cache dans une instance pdns@public a part,
pour que le site ne puisse jamais interroger la zone .internal. Relations derivees des plans
des locataires, mots de flux dns_public_site et primaires_dns_locataires. Eprouve avant
d ecrire : allow-axfr-ips et TSIG sont alternatifs, le primaire notifie aussi ses NS, le
serial fige aurait gele le secondaire. P82 refuse l exposition sans DNSSEC.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 18:08:20 -04:00
8456d298bf la page cesse de proposer ce que le serveur refuse
Un seul entonnoir pour les quatre gestes d hote (lancer), POUVOIR_PAR_MODE qui
rattache chaque mode a son pouvoir, et des boutons qui demeurent mais inertes,
avec leur raison en infobulle. Les panneaux de fabric sont marques lecture seule
chez un locataire : ils viennent d une copie locale qui avait deja diverge. P81
refuse en plus une page qui aurait perdu POUVOIR_PAR_MODE.

Deux fautes attrapees en route : le banc de rendu a vu un TypeError a l ouverture
(ma garde adoptait pour un contexte tout ce qu on lui donnait) la ou node --check
restait vert ; et une couleur illisible, vue sur une capture, pas dans le code.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 14:57:39 -04:00
e46fa198fd la console dit sa portee : un site n affichait aucune de ses machines
Servie par le runner d un SITE, la console montrait zero serveur sans une erreur :
serveur_ops retire le lien instance sur un hebergeur, charger_yaml rend un
inventaire vide sur un fichier absent, et la page dessinait ce vide comme un plan
vide. La portee se DERIVE des deux symlinks (instance = je configure, underlay =
je materialise), jamais d un reglage declare. Une console de site sert desormais
son inventaire dynamique ; POUVOIR_REQUIS exige un pouvoir pour chaque route POST
et le refus dit pourquoi ; la page nomme la console. P81 refuse une portee sans
source d inventaire, un site sans machines, et toute route qui echapperait a la
table.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 14:36:59 -04:00
0cbb9fdb4a remise au client : deux temps, un outil, une garde
Livrer se terminait par une phrase — tes cles te seront remises separement — et
rien n ecrivait la suite. Temps 1 l identite (sa cle de voute, sa voute, sa racine
d AC), temps 2 la machine a echeance (sa cle entre, la notre sort, voute re-cletee,
secrets tournes). scripts/remise.py refuse une destination interne, un paquet sans
racine d AC, et tout ce qui n est pas l ecosysteme monte. Le registre remise.yml
declare enfin le responsable designe (D-18). P80 refuse un registre incomplet, un
second temps echu, un second temps declare fait sans revocation au plan, et un
secret dans un fichier versionne.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 11:16:27 -04:00
85c7f9710b P79 : une derivation qui ne trouve rien ne passe plus pour un succes
Sept replis des deux derniers jours, un temoin chacun, lu hors de la derivation
qu'il juge : jumeaux d'amorcage, patte de zone, edge d'exposition, certificat
bouchon, rechargement, sortie vers l'Internet, regles d'hote par instance.
Eprouvee par reinjection de chaque faute ; a trouve deux flux-genere perimes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 18:37:38 -04:00
e93e8f4c1d console chez les locataires, collision de noms, et un fichier ecrase
Les deux locataires declarent leur console derriere oauth2-proxy. En oidc le
vestibule n ecoute que la boucle locale : le gabarit annoncait cette protection
en s en remettant au pare-feu, qui ouvrait le port depuis l edge — la console
etait joignable sans passer par la passerelle.

COLLISION REELLE : serveur_oauth2_proxy est mono-instance par machine, et la
table des noms publics etait indexee par GROUPE. La passerelle de la vigie se
croyait la console ; son URL de retour OIDC aurait vise l autre machine. Une
application nomme un COUPLE (machine, role). P67 ne le voyait pas parce qu elle
indexait comme la derivation qu elle garde — une garde qui reproduit le
raisonnement qu elle verifie ne verifie rien.

ET J AI ECRASE group_vars/serveur_ops.yml sans le regarder : 68 lignes
detruites, deux preuves tombees, et une explication fausse construite dessus. Le
git diff qui m avait rassure portait un glob developpe par le shell parent : il
n a rien matche et n a rien dit. Une commande qui ne trouve rien et une commande
qui trouve que rien n a change rendent le meme silence.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-15 11:47:50 -04:00
0529951381 la console d exploitation est allumee, et publiee par l edge
console.genese.internal : 401 sans justificatif, la console avec. Le site est le
premier ecosysteme a servir son GUI par un nom, en TLS verifie.

Le vestibule reste, et c est le contraire d une contradiction avec la veille :
Icinga Web 2 a une page de connexion, donc on lui a retire le sien ; le GUI de
Set-OPS sert sa page a qui la demande, jeton inclus, donc le vestibule EST sa
seule serrure. Verifie sur la machine : le GUI n ecoute que 127.0.0.1:8765, seul
le 8090 du vestibule est publie.

Controle dans les deux sens — une serrure ne se prouve qu en la forcant et en
l ouvrant. Et la sonde console-ops exige un REFUS sur une requete anonyme, parce
qu un 200 y serait la pire des reponses.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-15 10:32:48 -04:00
51dae506fb icingaweb2 : le backend natif remplace un vestibule de trop
L exploitant : Icinga Web 2 permet nativement de gerer des comptes ; ce genre
d intervention n est pertinente que pour integrer Icinga a Keycloak chez les
tenants.

Le mode locale posait un auth_basic nginx devant le backend external. Ca
marchait, et ca reinventait une page de connexion devant une application qui en
a une — en privant l exploitant de la gestion des comptes dans l interface. Un
vestibule n a de sens que devant une application qui ne sait pas
s authentifier ; le GUI de Set-OPS est dans ce cas, Icinga Web 2 non.

Mode db : backend natif, groupes natifs, base a elle (les tables du moteur sont
reecrites par ses migrations). Le moteur pose UN compte d amorcage et ne
l ecrase jamais. D-66 redevient applicable sans annuaire, les groupes vivant en
base.

Deux pieges du renommage : une garde ecrite en negation a cesse de garder, et le
bloc de la base pose apres le rendu des .ini a produit un echec CENSURE par
no_log.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-15 08:49:32 -04:00
95dc225037 l edge publie : trois noms en TLS verifie de bout en bout
expositions n etait resolu nulle part — ni par le pare-feu d hote, qui ne filtre
pas l egress, ni par le devis de frontiere. Il n avait jamais eu besoin de
l etre : chez un locataire le trafic edge vers amont ne traverse pas le boitier.
Au site il le traverse. Une declaration peut dormir des mois avant que la
premiere fabric ne la reveille.

Une regle par amont, avec son port. Jamais une regle large : ouvrir l edge sur
tout le site annulerait ce qu une zone de publication separee cherche a obtenir.

La meme faute qu hier, avalee de la meme facon : U au lieu de underlay_mod, et
un except Exception large a transforme le NameError en note plausible. Resserre
a OSError/ValueError — une faute de frappe doit faire du bruit.

Le schema de proxy_pass suit maintenant le port, et l amont TLS est VERIFIE
contre l AC interne : relayer en TLS sans verifier ne fait que deplacer la
confiance.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-15 07:50:21 -04:00
fae3cc8838 l edge servait du snakeoil, et deux ecritures d une meme regle
Le certificat bouchon de Debian sur les trois noms. serveur_nginx l a pour
defaut, avec un commentaire d avant la PKI ; un locataire le remplace en
group_vars, l inventaire du site est dynamique et n en a pas. Les autres replis
rendaient un service muet — celui-la rend du TLS qui RESSEMBLE a du TLS : le
cadenas s affiche et rien n est prouve.

site_inventaire construisait sa propre liste d expositions, avec edge = le
groupe de l application. Vrai tant que le site n avait pas d edge. client_pki
retient un FQDN si son edge est un groupe de cet hote : aucun ne correspondait,
et le certificat ne portait que le nom de la machine. La boucle est remplacee
par un appel a expositions_des_applications.

Et la cicatrice de site-forge-01 — un cert renouvele n atteint personne tant que
son consommateur n est pas recharge — a ete refaite sur la machine suivante.

Les 6 noms sont maintenant servis et verifies contre l AC du site.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-14 21:44:03 -04:00
4f68182ac6 l edge du site est debout, et quatre replis silencieux l ont retarde
Les quatre defauts ont la MEME forme : un repli qui rend un succes au lieu d un
refus.

1. Le gabarit dore porte l adresse du cache d avant le renumerotage, et
   site_inventaire derivait dns_amorcage sans deriver son jumeau
   artefacts_amorcage. Le site fournissait cette valeur a ses locataires sans se
   la donner a lui-meme.

2. opnsense_if_zones ignorait la zone neuve, et _if_de retombe sur l ancienne
   patte PLATE : 20 regles posees sur vlan030, correctes et jamais rencontrees.
   Le fichier documentait deja le meme incident un mois plus tot.

3. serveur_nginx chargeait domaines.yml sans condition — un SITE ne publie rien
   a l Internet et n a pas ce registre. Il releve maintenant ce qui existe.

4. Sans registre de domaines, l edge d une exposition retombe sur le GROUPE DE
   L APPLICATION, jamais serveur_nginx : le vhost genere faisait 43 octets et le
   deploiement rendait vert. Une derivation qui ne trouve rien ne se distingue
   pas d une derivation qui n a rien a trouver.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-14 20:57:09 -04:00
5ecce4282a une console pour le site, et un repli qui ouvrait vers l Internet
Icinga Web 2 gagne un troisieme mode, locale : nginx authentifie en HTTP Basic
et pose REMOTE_USER, l application le croit. Un SITE n a ni annuaire ni Keycloak
— ce sont des services d ecosysteme. Ni backend LDAP ni backend de groupes : un
backend qui vise une ressource inexistante fait echouer chaque ouverture de
session. L habilitation nomme alors une personne, entorse a D-66 ecrite plutot
que contournee.

Deux pieges en chemin : resoudre_annuaire etait appele sans condition et tombait
sur NoneType has no len (default sans son second argument ne remplace pas None),
et le flux du role ne nommait que l edge — le site n en a pas, donc personne ne
pouvait entrer. serveur_grafana portait deja la reponse.

LE DEFAUT DU DEVIS : une sortie vers un role ABSENT de l ecosysteme retombait
sur !SETOPS_INTERNES, la forme de vers l Internet. La frontiere aurait autorise
la console a parler LDAPS a n importe quelle machine du monde, pour joindre un
annuaire qui n existe pas. C est une source vide ouvre le port, cote
destination. Trois regles du meme defaut etaient DEJA posees pour postfix.

La frontiere n est pas ecrite : elle porte la production, et le devis attend un
mot.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 19:11:22 -04:00
c308c9c5b0 TLS des bases : le consommateur suit son serveur, il ne le devine plus
La supervision du SITE etait morte depuis 11:10 et rien ne le disait. icingadb
refuse par pg_hba — hostssl impose cote serveur, connexion en clair cote client.
icinga2 tournait, redis tournait, les sondes poussaient, et rien n atteignait la
base : les verdicts se calculaient dans le vide.

La cause est une seconde liste tenue a la main. tls_force allume hostssl ; chaque
consommateur avait SON interrupteur a allumer dans les group_vars. Chezlepro
avait les trois, le site avait le premier. serveur_forgejo disait pire que rien :
sslmode disable ecrit en dur, le contraire de ce que le serveur imposait.

resoudre_base expose resoudre_base_db_tls_force, lu dans les hostvars de la
machine qui PORTE la base. Les trois interrupteurs en derivent. Un serveur qui
ne declare rien ne force rien : on ne casse pas un ecosysteme qui n a pas
bascule.

P78 refuse une valeur ecrite chez un consommateur, et nomme les deux roles sans
reglage TLS plutot que de rendre un vert muet sur eux.

Apres : icingadb active, TLSv1.3 vu par PostgreSQL, 16 hotes et 88 services en
base. Les cinq sondes des marqueurs du site, INCONNU faute de deploiement,
rapportent leur phrase.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-14 18:42:21 -04:00
d4bc3e48b7 nom public : la garde ne regardait qu un cote de la cloture
Le plan du site expose observatoire.genese.internal ; serveur_grafana devinait
grafana.<domaine>. Grafana fabriquait son root_url, ses liens d alerte et son
URL de retour OIDC avec un nom que rien ne sert.

C est mot pour mot le defaut du 2026-09-10, quatre jours plus tard, de l autre
cote : instancier derive <groupe>_hostname depuis ce jour-la et P67 le garde,
mais tous deux ne connaissent que l instance montee — donc un locataire.
L inventaire du site n en derivait aucun. Quatre devinettes sur cinq tombaient
juste par convention, et c est ce qui rendait le defaut invisible.

site_inventaire.py derive les cinq noms du plan. P67 lit maintenant les deux
inventaires — celui du site est dynamique, donc elle l EXECUTE au lieu de lire
sa source. Eprouvee dans les deux sens : 10 services sur 2 inventaires.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-14 17:47:36 -04:00
392da4d3f5 fiche : les panneaux etaient caches derriere l exportateur
Le tableau des panneaux vivait DANS la condition de l exportateur. Le premier
role a declarer des panneaux sans exportateur — client_metrique, dont le job
node est universel — affichait « aucun exportateur declare » et cachait ses
quatre panneaux.

Une fiche qui tait ce qu un role declare est pire qu une fiche absente : elle
affirme que rien n existe.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-14 16:34:51 -04:00
311f33d6f6 grafana : les panneaux declares deviennent des tableaux
La moitie qui manquait. Les roles declaraient leurs panneaux, Prometheus en
derivait ses cibles, les expressions repondaient, et rien ne les assemblait.

serveur_grafana lit les memes meta/metriques.yml que serveur_prometheus et en
assemble un tableau par role — la raison du panneau devient sa description dans
Grafana. Moisson des tableaux orphelins, prefixe setops-role- pour ne jamais
toucher un tableau ecrit a la main, JSON valide avant d etre pose (Grafana ne
tombe pas sur un tableau illisible : il le saute en silence).

client_metrique declare quatre panneaux sans exportateur — le cas symetrique.
Celui qui compte : la memoire disponible, depuis que le ballon est actif.

Eprouve sur le site : les deux tableaux charges dans le stockage unifie, un
temoin orphelin retire, les quatre panneaux de flotte a 10 series chacun.

Un panneau etait faux — /var/lib/lxcfs rapporte toujours zero octet libre et un
min() en meurt. Corrige en liste blanche : un montage inconnu manque au graphe,
ce qui se voit, au lieu de l ecraser.

P77 garde la table des unites : une unite inventee retombe sur short, lisible et
fausse. 76 OK.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-14 16:32:30 -04:00
aac74f6043 supervision : les huit derniers roles, et deux defauts que l epreuve a trouves
Les 33 roles serveur_* declarent maintenant une sonde. Les huit qui manquaient
sont ceux dont la verite ne ressemble pas a « ce service repond-il ».

Quatre marqueurs du site : ce que tasks/main.yml verifie UNE FOIS au deploiement
cesse d etre vrai sans que rien ne tombe. La racine du cache se retrouve chainee,
la forge du genome repond en n ayant plus rien dedans, un locataire n est plus
admis a resoudre, l isolation d un depot glisse.

serveur_ops_site ne sert rien : il detient un pouvoir. La sonde verifie que la
carte est la, que la voute du site est chiffree et que sa cle est en 0600 — sans
lire le contenu d aucun des trois.

serveur_icingaweb2 surveille la vitrine de la supervision elle-meme : si la
console meurt, tout reste vert et l exploitant est aveugle.

DEFAUT 1 — quatre gabarits qu Ansible aurait refuse de rendre. Jinja lit le
{# de ${#tableau[@]} comme un debut de commentaire. Le depot connaissait le
remede et l appliquait la ou quelqu un s etait fait prendre, nulle part ailleurs.
P76 rend desormais chaque gabarit de role, avec les delimiteurs qu Ansible en
tirerait — pas une recherche de motif.

DEFAUT 2 — la doctrine promettait 54 greffons et citait check_pgsql. La flotte a
monitoring-plugins-basic : 53, sans check_pgsql ni check_dns ni check_ldap. Le
paquet qui les porte traine samba et snmp sur chaque machine. Un greffon absent
sort en 127, qui n est pas un code Nagios.

21 controles negatifs sur les machines reelles du site. ansible-lint production
0/91, harnais 75 OK.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-14 15:43:52 -04:00
f307a23345 le wiki suit le genome : un locataire n en est pas depositaire
Decision : seuls les SITES portent la forge, le cache APT et les artefacts. Meme
geste que le retrait de serveur_artefacts d un plan de locataire, un cran plus
loin — le site fournit tout ce dont un tenant a besoin pour venir au monde.

La generalisation de forge_amorcer a un locataire est revenue en arriere : elle
implementait le modele ecarte, et la garder en ferait un piege.

ma_forge ne derive plus MA forge mais la forge qui porte MON genome. Le signal
est deja au plan : serveur_ops_forge_externe dit je lis mon genome ailleurs. Qui
le declare consulte, il ne republie pas.

Reste vrai : une forge de locataire peut exister pour LE CODE DE SES GENS —
c est l offre Atelier. Ce n est pas l endroit ou vit le moteur.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-14 14:41:23 -04:00
8574b7b540 wiki : chaque runner publie pour SA forge
J allais centraliser — un controleur poussant vers N forges, un temoin portant
une liste. Ca aurait demande un acces sur chaque forge depuis un seul poste, et
fait du temoin un fait global que personne ne detient.

Le modele suit la ligne du reste : chacun sert les siens. Sans WIKI_REMOTE,
l adresse se derive du nom que le plan monte expose pour serveur_forgejo.

Deux notions a ne pas confondre : la forge AMONT ou l on LIT le genome, et MA
forge ou l on SERT les siens. Le runner d un locataire lit chez son hebergeur et
sert chez lui.

WIKI_REMOTE l emporte toujours : le poste du mainteneur n est le runner d aucun
ecosysteme et publie vers le domicile public du projet.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-14 14:26:29 -04:00
d76ce574f0 fiches de role au wiki : 68 generees, l index, et trois gardes qui ont mordu
Generees depuis ce que chaque role declare, avec un schema mermaid et la raison
de chaque ligne. Une section vide est une information : l index recompte ce que
la flotte ne declare pas — 36 sans flux, 40 sans sonde, 67 sans metrique.

La charte du wiki disait de ne pas recopier le depot, pour eviter la derive. Le
motif ne vaut pas pour une page qui relit sa source ; l exception est nommee
plutot que prise en silence.

La navigation exigeait une citation DIRECTE alors que son motif parle
d atteignabilite. L exigence litterale interdisait toute page d index — la garde
forcait a degrader ce qu elle protegeait. Elle suit maintenant les liens de
proche en proche, et son motif reconnait le souligne : un motif trop etroit ne
rend pas une garde prudente, il la rend aveugle.

Et le compte du wiki serait passe de 27 a 96 : une fiche generee n est pas une
unite d apprentissage.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-14 14:09:13 -04:00
a4a8fc6065 fiche_role : la fiche d un role, generee depuis ce qu il declare
68 roles. Autant de pages faites a la main seraient perimees avant la fin du
mois — c est le defaut que ce depot traque partout sous le nom une liste qui
suit une autre prend du retard.

La fiche lit meta/flux, supervision, metriques, empreinte, authentification. Un
schema mermaid au centre, puis les tableaux, et chaque ligne porte la RAISON que
le role a declaree.

Une section vide est une information, pas un defaut de la fiche : elle devient
la carte de ce qui reste a faire, tenue a jour toute seule.

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