Set-OPS-Public/docs/runbooks-exploitation.md

494 lines
26 KiB
Markdown
Raw Normal View History

# Runbooks d'exploitation — Set-OPS
> **Pour qui :** l'exploitant, face à une situation. Pas le mainteneur, pas l'apprenant.
> Le *pourquoi* vit dans les autres `docs/` ; la version pédagogique, dans le wiki. Ici,
> uniquement le *comment faire*.
>
> Tu viens de reprendre l'écosystème et tu ne sais pas par où entrer ?
> Wiki → **Reprendre l'écosystème**.
---
## 1. Un certificat a expiré / le login SSO est cassé
**Symptôme** : connexion à une app via le SSO échoue *après* le login ; log Grafana/app :
`tls: failed to verify certificate: x509: certificate has expired`.
**Cause fréquente** : le cert step-ca a été **renouvelé sur disque** mais le service (nginx sur
l'edge) **n'a pas été rechargé** → il sert l'ancien cert en mémoire.
**Diagnostic-réflexe** — comparer le cert *servi* au cert *fichier* :
```bash
# SERVI (en mémoire par nginx)
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
echo | openssl s_client -connect infra-edge-01.chezlepro.internal:443 -servername keycloak.chezlepro.internal 2>/dev/null \
| openssl x509 -noout -enddate
# FICHIER (sur disque)
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
openssl x509 -in /etc/step/certs/infra-edge-01.chezlepro.internal.crt -noout -enddate
```
Dates différentes (servi < fichier) ⇒ nginx sert un cert périmé.
**Fix immédiat** : `systemctl reload nginx` sur l'edge (idem `postfix`/`dovecot`/`slapd` selon le
service touché).
**Fix permanent (déjà en place)** : `client_pki_reload_services` recharge les vrais consommateurs
après chaque renouvellement — edge→nginx, mail→postfix/dovecot, annuaire→slapd. Vérifier :
`systemctl cat cert-renewer@$(hostname -f).service | grep ExecStartPost`.
Voir aussi l'unité wiki *PKI & confiance* (⑤ le renouvellement).
---
## 2. Donner Explore/Editor à un opérateur dans Grafana (RBAC)
Par défaut, un utilisateur SSO est **Viewer** (dashboards seulement, pas Explore). Pour l'élever :
1. Déclarer l'assignation dans l'inventaire de l'instance (group_vars `serveur_keycloak`) :
```yaml
serveur_keycloak_role_assignments:
- { user: <uid>, role: grafana-editor } # ou grafana-admin
```
2. Redéployer Keycloak (`make deployer` sur le nœud SSO) — kcadm **à chaud, sans coupure**.
3. L'utilisateur doit **se déconnecter/reconnecter** (Grafana applique le rôle à la connexion).
Mapping (défaut du rôle grafana) : `grafana-admin`→Admin, `grafana-editor`→Editor, sinon Viewer
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
(`serveur_grafana_oidc_role_path`).
> **Préférer le groupe à la personne — et c'est construit, pas un idéal.** Les groupes LDAP
> sont projetés dans Keycloak et émis en claim (`tasks/groupes-ldap.yml`, `claim-groupes.yml`),
> et `roles/serveur_grafana/meta/acces.yml` déclare déjà `sysadmin ⇒ Admin`,
> `personnel ⇒ Viewer`. Ajouter quelqu'un au **groupe** lui ouvre Grafana, Forgejo, Icinga et
> le courriel d'un seul geste — alors qu'une assignation nominative crée une dette qu'on
> découvre le jour du départ, service par service. L'assignation explicite ci-dessus reste
> le geste de dépannage, pas la façon normale d'accorder un accès. Voir `docs/autorisation.md` §5.
---
## 3. « Connection timed out during banner exchange » — le message qui accuse le réseau
**Symptôme** : Ansible marque un ou plusieurs hôtes injoignables, avec ce message. On soupçonne
le réseau, la route ou le pare-feu. **C'est presque toujours autre chose.**
**Pourquoi le message trompe.** À travers la frontière, la poignée TCP aboutit *toujours* — le
pare-feu y répond lui-même sans relayer (voir `frontiere-opnsense.md`). L'échec ne peut donc
pas se présenter comme un « connection refused » franc : il se manifeste plus tard, au moment
où le serveur devrait annoncer sa bannière SSH. D'où un message qui parle de délai réseau pour
un hôte qui, souvent, n'a jamais rien reçu.
**Les trois causes, par fréquence :**
1. **La VM n'est pas encore là.** `make creer-vm` rend la main dès que Proxmox a *démarré* la
VM, pas quand elle répond. C'est le cas normal, quotidien, et aucun correctif ne l'abolira :
les attentes actives du `Makefile` existent pour ça.
2. **`sshd` refuse une rafale.** `MaxStartups` / `MaxSessions` trop serrés coupent des
connexions parfaitement légitimes — deux déploiements interrompus le 2026-08-09, sur des
hôtes qui n'avaient ni redémarré ni perdu leur réseau. Réglés par
`ssh_hardening_max_startups` (`10:30:60`) et `ssh_hardening_max_sessions` (`10`), avec
l'arbitrage expliqué dans `roles/ssh_hardening/defaults/main.yml`.
3. **Le réseau, vraiment** — le cas le plus rare, et le dernier à examiner.
**Ce qui tranche, dans l'ordre :**
```
make hote-afficher HOTE=<nom> # l'hôte existe-t-il au plan ?
ssh -v ansible@<ip> 2>&1 | tail -20 # où la négociation s'arrête exactement
```
Une bannière (`SSH-2.0-OpenSSH…`) prouve que le chemin est bon et que le problème est
applicatif. **Aucun `connect()` ne prouvera quoi que ce soit ici** — il réussit vers le vide.
---
## 4. Brander une instance Forgejo (identité visuelle)
Activer dans l'inventaire (group_vars `serveur_forgejo`) :
```yaml
serveur_forgejo_branding: true
serveur_forgejo_app_name: "Forge Chezlepro"
serveur_forgejo_theme: "forgejo-dark"
serveur_forgejo_meta_description: "…"
```
Puis redéployer. Le rôle déploie le dossier `custom/` officiel (logo/favicon aurore, accent CSS par
variables, page d'accueil brandée) — léger, résistant aux MAJ (aucune classe interne touchée).
Note : ne s'applique qu'aux Forgejo **gérées par Set-OPS**.
recette : la donnee REVIENT — restauration eprouvee, pas seulement sauvegarde On savait que la donnee partait et arrivait. Pas qu'elle revenait. Trois charges critiques eprouvees : - cles de l'AC (infra-pki-01) : restauration + comparaison OCTET POUR OCTET, 12 fichiers, 11 identiques, root_ca_key et intermediate_ca_key compris. Seul ecart : db/000000.vlog, le journal badger de step-ca, qui avance a chaque emission. Attendu. - annuaire (idm-01) : slapadd -u (essai a blanc) sur le LDIF restaure — REJOUABLE, 7 entrees dont uid=sysadmin. - bases (data-sql-01) : section forgejo REJOUEE dans une base d'epreuve — 0 erreur, 130 tables, comptes reels. Production verifiee intacte apres. Controles negatifs : un LDIF corrompu fait sortir slapadd en 1 ; la garde SQL a refuse une section mal decoupee. LE PIEGE pg_dumpall : il ecrit CREATE DATABASE <suivante> AVANT le \connect correspondant. Decouper « du \connect X au \connect suivant » emporte un ordre visant une AUTRE base. Ma premiere decoupe l'a fait ; la garde a refuse de rejouer. Consigne dans runbooks-exploitation.md §5. valider.yml ne ment plus : il exigeait une restauration de TOUS les noeuds client_backup, donc echouait sur ceux qui ne detiennent rien et sur les depots vides. Quatre verdicts desormais (OK / A CONFIRMER / SANS OBJET / ECHEC), ALIGNES sur ceux de la supervision. Et il prouve que l'annuaire est rejouable, pas seulement present. make valider : 0 echec sur toute la flotte. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 09:50:51 -04:00
## 5. Restaurer — et d'abord : prouver qu'on peut
### 5.0 La reconstruction remet l'état (depuis le 2026-09-30)
Jusqu'au 2026-09-30, **une reconstruction repartait d'un état neuf** : nouvelle racine
d'AC, annuaire vierge (`sysadmin` au mot de passe d'amorçage), bases, Nextcloud et courriel
vides. Les instantanés se restauraient pour *prouver* qu'ils s'ouvrent, jamais pour être
remis en service.
Désormais **chaque rôle propriétaire remet l'état de l'incarnation précédente**, au moment
où il le créerait neuf — la bonne séquence vient des couches de déploiement :
| Rôle | Quand | Condition « vierge » |
|---|---|---|
| `serveur_step_ca` | avant `step ca init` | pas de `ca.json` — et la voûte doit ouvrir les clés restaurées |
| `serveur_postgresql` | juste après la création des bases | base sans table (hors `nextcloud`, `icinga`) |
| `serveur_openldap` | en fin de rôle (schéma et `ppolicy` chargés) | aucune entrée hors la racine |
| `serveur_dovecot` | après le répertoire des boîtes | répertoire vide |
| `serveur_rspamd` | avant la génération DKIM | pas de clé DKIM |
| `serveur_forgejo` | avant l'arborescence de données | répertoire vide |
| `serveur_nextcloud` | **en fin de rôle** : base + fichiers + config ensemble, puis `occ upgrade` | pas de `config.php` au départ, base vide |
| `serveur_web_frontal` / `_dorsal` | après leur racine | racine vide |
**L'instantané remis** est le dernier pris **avant la naissance de la machine** (date de
sa clé d'hôte SSH). Un état en place n'est jamais écrasé d'office. Chaque jeu laisse un
marqueur dans `/etc/setops/restauration/<jeu>` ; ce qui a été remplacé est mis de côté dans
`/var/backups/setops-avant-restauration/`.
**La sauvegarde refuse de déposer** (code 3) tant qu'un état d'avant n'a été ni remis ni
écarté : sinon `restic forget --keep-daily` chasserait l'instantané d'avant au profit de
l'état neuf du même jour.
Les gestes :
```
make sauvegarder-maintenant # JUSTE AVANT de raser : sinon on perd la journée
make restauration-etat [HOTE=...] # ce que chaque jeu est devenu
make restauration-renoncer HOTE=.. JEU=.. CONFIRMER=true # écarter un état, sans le remettre
-e client_backup_restauration_instantane=<id> # imposer un instantané, par hôte
```
Sur un nœud, sans Ansible : `setops-restaurer etat`, et les répétitions qui ne touchent à
rien — `setops-restaurer annuaire --essai <base_dn>`, `base <nom> --vers epreuve`,
`fichiers --vers /var/tmp/epreuve <chemin>`.
recette : la donnee REVIENT — restauration eprouvee, pas seulement sauvegarde On savait que la donnee partait et arrivait. Pas qu'elle revenait. Trois charges critiques eprouvees : - cles de l'AC (infra-pki-01) : restauration + comparaison OCTET POUR OCTET, 12 fichiers, 11 identiques, root_ca_key et intermediate_ca_key compris. Seul ecart : db/000000.vlog, le journal badger de step-ca, qui avance a chaque emission. Attendu. - annuaire (idm-01) : slapadd -u (essai a blanc) sur le LDIF restaure — REJOUABLE, 7 entrees dont uid=sysadmin. - bases (data-sql-01) : section forgejo REJOUEE dans une base d'epreuve — 0 erreur, 130 tables, comptes reels. Production verifiee intacte apres. Controles negatifs : un LDIF corrompu fait sortir slapadd en 1 ; la garde SQL a refuse une section mal decoupee. LE PIEGE pg_dumpall : il ecrit CREATE DATABASE <suivante> AVANT le \connect correspondant. Decouper « du \connect X au \connect suivant » emporte un ordre visant une AUTRE base. Ma premiere decoupe l'a fait ; la garde a refuse de rejouer. Consigne dans runbooks-exploitation.md §5. valider.yml ne ment plus : il exigeait une restauration de TOUS les noeuds client_backup, donc echouait sur ceux qui ne detiennent rien et sur les depots vides. Quatre verdicts desormais (OK / A CONFIRMER / SANS OBJET / ECHEC), ALIGNES sur ceux de la supervision. Et il prouve que l'annuaire est rejouable, pas seulement present. make valider : 0 echec sur toute la flotte. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 09:50:51 -04:00
> Éprouvé le 2026-08-12 sur Chezlepro. `make valider` rejoue la partie automatisable ;
> la restauration d'une base reste manuelle, et porte un piège décrit plus bas.
**Ce que `make valider` prouve tout seul**, pour chaque nœud détenteur d'état : le dernier
instantané se restaure, il en sort des fichiers, et — pour l'annuaire — qu'il est
**rejouable** (`slapadd -u`, essai à blanc, rien n'est écrit). Verdicts possibles :
| Verdict | Sens |
|---|---|
| `OK` | restauré, et non vide |
| `À CONFIRMER` | restauré, mais l'instantané n'emporte **aucun fichier** — légitime si ce nœud n'a pas encore de données, à trancher par un humain |
| `SANS OBJET` | ce nœud ne détient rien de non régénérable |
| `ÉCHEC` | la restauration elle-même a échoué |
### Restaurer les clés de l'autorité (`infra-pki-01`)
```
export RESTIC_REPOSITORY=$(grep -oP 'RESTIC_REPOSITORY="\K[^"]+' /usr/local/sbin/setops-sauvegarder.sh)
export RESTIC_PASSWORD_FILE=/etc/setops/restic.pass
t=$(mktemp -d); restic restore latest --target "$t"
diff -r "$t/etc/step-ca" /etc/step-ca
```
Mesuré : **12 fichiers, 11 identiques octet pour octet**, `root_ca_key` et
`intermediate_ca_key` compris. Le seul écart attendu est `db/000000.vlog` — le journal de
la base badger de step-ca, qui avance à **chaque** émission de certificat.
### Rejouer une base depuis `pg_dumpall` — LE PIÈGE
`pg_dumpall` écrit `CREATE DATABASE <suivante>` **avant** le `\connect` correspondant.
Découper « du `\connect X` au `\connect` suivant » emporte donc un ordre qui vise une
**autre** base. Couper aussi sur `CREATE DATABASE` et sur `DROP DATABASE` (avec `--clean`,
la section de `nextcloud` finissait par `DROP DATABASE postgres;` — 2026-09-30), et **vérifier avant de rejouer** :
recette : la donnee REVIENT — restauration eprouvee, pas seulement sauvegarde On savait que la donnee partait et arrivait. Pas qu'elle revenait. Trois charges critiques eprouvees : - cles de l'AC (infra-pki-01) : restauration + comparaison OCTET POUR OCTET, 12 fichiers, 11 identiques, root_ca_key et intermediate_ca_key compris. Seul ecart : db/000000.vlog, le journal badger de step-ca, qui avance a chaque emission. Attendu. - annuaire (idm-01) : slapadd -u (essai a blanc) sur le LDIF restaure — REJOUABLE, 7 entrees dont uid=sysadmin. - bases (data-sql-01) : section forgejo REJOUEE dans une base d'epreuve — 0 erreur, 130 tables, comptes reels. Production verifiee intacte apres. Controles negatifs : un LDIF corrompu fait sortir slapadd en 1 ; la garde SQL a refuse une section mal decoupee. LE PIEGE pg_dumpall : il ecrit CREATE DATABASE <suivante> AVANT le \connect correspondant. Decouper « du \connect X au \connect suivant » emporte un ordre visant une AUTRE base. Ma premiere decoupe l'a fait ; la garde a refuse de rejouer. Consigne dans runbooks-exploitation.md §5. valider.yml ne ment plus : il exigeait une restauration de TOUS les noeuds client_backup, donc echouait sur ceux qui ne detiennent rien et sur les depots vides. Quatre verdicts desormais (OK / A CONFIRMER / SANS OBJET / ECHEC), ALIGNES sur ceux de la supervision. Et il prouve que l'annuaire est rejouable, pas seulement present. make valider : 0 echec sur toute la flotte. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 09:50:51 -04:00
```
awk '/^\\connect forgejo$/{f=1;next} f && (/^\\connect /||/^CREATE DATABASE /||/^DROP DATABASE /){exit} f' \
recette : la donnee REVIENT — restauration eprouvee, pas seulement sauvegarde On savait que la donnee partait et arrivait. Pas qu'elle revenait. Trois charges critiques eprouvees : - cles de l'AC (infra-pki-01) : restauration + comparaison OCTET POUR OCTET, 12 fichiers, 11 identiques, root_ca_key et intermediate_ca_key compris. Seul ecart : db/000000.vlog, le journal badger de step-ca, qui avance a chaque emission. Attendu. - annuaire (idm-01) : slapadd -u (essai a blanc) sur le LDIF restaure — REJOUABLE, 7 entrees dont uid=sysadmin. - bases (data-sql-01) : section forgejo REJOUEE dans une base d'epreuve — 0 erreur, 130 tables, comptes reels. Production verifiee intacte apres. Controles negatifs : un LDIF corrompu fait sortir slapadd en 1 ; la garde SQL a refuse une section mal decoupee. LE PIEGE pg_dumpall : il ecrit CREATE DATABASE <suivante> AVANT le \connect correspondant. Decouper « du \connect X au \connect suivant » emporte un ordre visant une AUTRE base. Ma premiere decoupe l'a fait ; la garde a refuse de rejouer. Consigne dans runbooks-exploitation.md §5. valider.yml ne ment plus : il exigeait une restauration de TOUS les noeuds client_backup, donc echouait sur ceux qui ne detiennent rien et sur les depots vides. Quatre verdicts desormais (OK / A CONFIRMER / SANS OBJET / ECHEC), ALIGNES sur ceux de la supervision. Et il prouve que l'annuaire est rejouable, pas seulement present. make valider : 0 echec sur toute la flotte. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 09:50:51 -04:00
toutes-bases.sql > section.sql
grep -qE '^(DROP|CREATE|ALTER) DATABASE|^\\connect' section.sql \
&& { echo "REFUS : ordre hors-perimetre"; exit 1; }
runuser -u postgres -- createdb epreuve_restauration
runuser -u postgres -- psql -q -d epreuve_restauration -f section.sql
runuser -u postgres -- psql -tAd epreuve_restauration -c "select count(*) from information_schema.tables where table_schema='public'"
runuser -u postgres -- dropdb epreuve_restauration
```
Mesuré sur `forgejo` : rejeu en **0 erreur**, **130 tables**, et les comptes réels
(`forgejo-admin`, `sysadmin`). Production vérifiée intacte après coup.
**Ne jamais rejouer un `pg_dumpall` entier sur un cluster vivant** : il contient les
`DROP DATABASE` de toutes les bases. Une restauration réelle se fait sur un cluster neuf.
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
## 6. La bascule d'adressage de la fabric (D-77) — FAITE
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
> **Cette section décrivait une transition en cours jusqu'au 2026-09-06.** Elle est
> terminée : mesuré le 2026-08-22, **`10.0.0.0/24` n'existe plus** — ni `10.0.0.1`, ni
> `10.0.0.41` ne répondent. Le plan d'administration est `10.17.0.0/24` : la frontière y
> répond en `10.17.0.1` sur un port physique à elle, les commutateurs sont en `10.17.0.3`
> et `.4` avec cette passerelle par défaut, le poste de l'exploitant en `10.17.0.17`. Le
> renumérotage du tenant (`10.27` → `10.17`) est fait lui aussi.
>
> On garde la **méthode**, parce qu'elle est ce qui a permis de le faire sans coupure, et
> qu'un autre site la rejouera :
>
> **Ajouter avant de retirer, jamais l'inverse.** Un point de routage qui change d'adresse
> d'un coup coupe simultanément l'exploitant, les commutateurs qui l'ont en passerelle par
> défaut, et l'outil qui devait faire la bascule. La seconde adresse a donc vécu à côté de
> l'ancienne (`ipalias`), et l'ancienne n'est tombée qu'en **dernier**.
>
> **Distinguer une destination d'un chemin (D-78).** Un réseau qui n'est **jamais** une
> destination — seulement un chemin — n'a aucune raison d'être unique entre deux hébergeurs :
> il sort de l'espace dérivé, vers `192.168.<vlan>.0/24`. Seule la **gestion** doit rester
> unique d'un site à l'autre, parce que le poste de l'exploitant, un VPN et demain un lien
> inter-sites doivent l'atteindre.
>
> **Appliqué pour le transport VXLAN seulement, à ce jour** (mesuré le 2026-09-06) :
> `underlay-vxlan` est bien en `192.168.50.0/24`. Le **transit** (`10.0.4.0/24`, VLAN 40) et
> le **stockage** (`10.11.5-7.x`, VLAN 5/6/7) sont encore dans l'ancien espace. Ce n'est pas
> une urgence — ces réseaux ne quittent jamais leur site — mais la carte doit dire ce qui est,
> pas ce qui a été décidé. Un **site neuf** se monte directement au schéma final : il n'a
> aucune transition à subir.
>
> **Un plan d'adressage ne doit pas dépendre de l'ordre d'une migration.** Le VLAN de
> transport est passé de 11 à 50 — non parce que 11 était mauvais, mais parce que
> `192.168.11.0/24` est occupé par le contrôle de la grappe. Faire dépendre un plan
> d'adressage de l'**ordre** d'une migration est exactement la dette qui se paie un an
> plus tard.
### Ce qui reste, et qui n'est PAS un reliquat de la bascule
Les hyperviseurs gardent **deux** plans, et c'est voulu :
| Plan | Réseau | Ce qu'il porte |
|---|---|---|
| administration | `10.17.0.0/24` (`vmbr3`, segment physique) | les **équipements** et l'exploitant ; **aucune VM ne peut y naître** (aucun pont ne le touche, et le validateur refuse qu'on y déclare une machine) |
| contrôle de la grappe | `192.168.11.0/24` (`vmbr0`, carte dédiée) | l'**interface web Proxmox** et le dialogue entre nœuds — c'est par là qu'on atteint `ansible@192.168.11.4x` |
> **Le `/24` de gestion vit à l'intérieur du `/16` du tenant, et ce n'est pas un conflit.**
> Les zones d'un tenant commencent au 3ᵉ octet 16 ; la bande 0-15 est libre pour la fabric,
> et la route connectée du `/24` est plus spécifique que celle du `/16` — la règle du
> préfixe le plus long, pas une coïncidence. Il faut cependant le **déclarer**
> (`bande_basse_de:` dans `underlay.yml`), sinon le validateur ne peut pas distinguer ce
> chevauchement voulu d'un chevauchement accidentel.
D-88 : le noeud du gabarit, point unique de la REPRODUCTION Question de l exploitant : le modele vit sur vishnu, les clones sur asgard, qu arriverait-il si vishnu tombait ? Mesuree, la reponse se coupe en deux. LES DONNEES SURVIVENT. Le pool CephNVMe est en size=3 / min_size=2 avec des OSD sur les trois hotes, et les images du gabarit y sont repliquees. L image reste lisible avec un noeud en moins, et les quatorze VM d un ecosysteme tournent ailleurs sans s apercevoir de rien. LA REPRODUCTION, NON. La configuration du gabarit porte le nom du noeud dans son chemin - /etc/pve/nodes/vishnu/qemu-server/9006.conf - et le clonage appelle nodes/vishnu/... Noeud eteint, aucune VM nouvelle ne peut naitre. Or la reproduction est ce que ce depot existe pour garantir. La decision est d ASSUMER la dependance et de la rendre COURTE, pas de la supprimer : depuis la migration du gabarit sur stockage partage ce matin, la remise en route est un deplacement de fichier de configuration, sans mouvement de donnees. Un benefice qu on n avait pas cherche : la migration sur Ceph a raccourci une panne qu on n avait pas encore nommee. Documentee en trois endroits, parce qu un seul ne suffit pas : D-88 pour nommer la dependance, le runbook section 7 pour la manoeuvre et l ordre des gestes, et le bloc gabarit du plan du site - c est la que l exploitant lit noeud: vishnu. Ce qui n est PAS fait et qui est dit : rien ne MESURE cette dependance. gabarit_etat compare le declare au reel, il ne demande pas si le noeud du gabarit heberge autre chose que le gabarit. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-10 17:51:15 -04:00
## 7. Le nœud qui porte le gabarit tombe — la reproduction s'arrête
**Symptôme.** Aucune VM nouvelle ne peut naître. `make creer-vm`, `make flotte-creer` et
`make reconstruire` échouent au clonage. Les machines existantes, elles, ne bronchent pas.
**Ce qui se passe.** Le gabarit doré vit sur un nœud nommé — `vishnu` chez l'hébergeur de
référence — et sa configuration porte ce nom dans son chemin même :
```
/etc/pve/nodes/vishnu/qemu-server/9006.conf
```
Le clonage appelle `nodes/vishnu/qemu/9006/clone` : c'est l'API de **ce nœud-là** qui doit
répondre. Nœud éteint, API muette, aucune naissance.
**Ce qui ne se passe PAS, et qu'il faut savoir avant de paniquer.** Les données du gabarit
ne sont pas perdues. Mesure du 2026-09-10 :
```
pool CephNVMe size=3 min_size=2
OSD sur les trois hôtes : asgard, gandalf, vishnu
base-9006-disk-0, base-9006-disk-1 présentes dans le pool
```
L'image est répliquée trois fois et reste lisible avec un nœud en moins. Et les quatorze VM
d'un écosystème tournent ailleurs, sur leurs propres disques Ceph : elles ne s'aperçoivent
de rien.
> **`vishnu` n'est pas un point unique de défaillance pour l'exploitation. Il l'est pour la
> reproduction** — et la reproduction est ce que ce dépôt existe pour garantir.
**La manœuvre.** Deux gestes, quelques minutes, aucun mouvement de données :
```bash
# 1. re-héberger la configuration sur un nœud debout
mv /etc/pve/nodes/vishnu/qemu-server/9006.conf \
/etc/pve/nodes/asgard/qemu-server/9006.conf
# 2. le déclarer, sinon la garde refusera
# SITE-Chezlepro/plan/10-intrants.yml : gabarit.noeud: asgard
```
Puis vérifier :
```bash
make gabarit-etat # doit rendre « Conforme »
```
**Pourquoi c'est aussi court.** Parce que le disque du gabarit vit sur un stockage
**partagé** depuis le 2026-09-10 : le déplacement ne bouge qu'un fichier de configuration.
Sur un stockage local, il aurait fallu recopier 16 Go — ou refabriquer le gabarit.
**L'ordre compte.** Déplacer sans déclarer laisse `gabarit_etat` en écart ; déclarer sans
déplacer fait échouer le clonage sur un nœud qui ne détient pas le modèle. Faire les deux,
dans cet ordre.
**Ce que cette section ne fait pas.** Elle ne supprime pas la dépendance : elle la rend
connue et courte. Deux remèdes de fond existent, aucun n'est appliqué :
- **déplacer le gabarit là où vivent déjà les VM** — ça ne supprime pas le point unique,
ça cesse d'en avoir *deux* (le nœud des VM et celui du modèle) ;
- **une garde** qui refuse quand le nœud du gabarit n'héberge aucune machine de la flotte,
c'est-à-dire quand la reproduction dépend d'un nœud qui ne porte rien d'autre.
*Une dépendance qu'on documente sans la mesurer reste une dépendance qu'on découvrira au
mauvais moment.*
## 8. Les contrôles à la demande — ce que `make prouver` ne peut pas voir
`make prouver` est **statique** : il lit le dépôt, zéro appel réseau. C'est ce qui le rend
rejouable partout, par n'importe qui, et présentable comme pièce justificative. Le prix de
cette propriété : il ne peut rien dire de ce qui ne s'observe qu'en ouvrant une connexion.
Quatre contrôles comblent ce creux. Aucun ne corrige quoi que ce soit — ils regardent, et
rendent `0` si tout concorde.
| Contrôle | Ce qu'il compare | Le piège qu'il attrape |
| --- | --- | --- |
| `make expositions-etat` | Expositions du plan ↔ **SAN du certificat servi** ↔ code du vhost | Un renommage déployé partout **sauf** dans le certificat |
| `make gabarit-etat` | Gabarit déclaré ↔ VM modèle réelle | Le modèle a dérivé de ce que le plan promet |
| `make routes-fabric-etat` | Zones déclarées ↔ routes déclarées ↔ routes vivantes | Une route **vivante mais non déclarée** — elle part au redémarrage |
| `make frontiere-plan` | Registre des flux ↔ règles de la frontière | Une règle posée à la main, qu'aucune déclaration ne porte |
Ajouter `SITE=1` à `expositions-etat` pour interroger l'écosystème du SITE plutôt que
l'instance montée.
### Pourquoi `expositions-etat` existe
Renommer une exposition touche cinq choses. Quatre suivent au déploiement ; la cinquième,
non :
```
serveur_powerdns la zone publie le nouveau nom ✓
serveur_keycloak le client OIDC accepte le retour ✓
le service il fabrique ses URL avec le bon nom ✓ (P67)
serveur_nginx le vhost répond sur le nouveau nom ✓
client_pki le SAN du certificat porte le nom ✗ il faut le rejouer
```
Le symptôme est trompeur : le site répond, la page s'affiche, et c'est le **navigateur**
qui refuse — avec une erreur de certificat que personne ne relie à un renommage fait la
veille. Mesuré deux fois le 2026-09-10, sur `grafana → observatoire` puis `icinga → vigie`.
Le contrôle regarde **dans les deux sens**. Un nom resté dans le SAN après avoir quitté le
plan est un nom que le certificat continue d'authentifier : c'est exactement ce qu'avait
laissé le premier renommage, jusqu'au passage de `client_pki`.
> Un `INJOIGNABLE` ne condamne pas le service : il dit que **ce poste** n'a pas pu ouvrir
> la connexion. Les zones du SITE ne sont pas routées depuis le plan d'administration du
> locataire — le mur est la frontière, pas le vhost.
le site reconstruit depuis zero : 7/7, 0 echec, et seize corrections SITE-Chezlepro n avait jamais ete rase. La limite qu on repetait partout — l infrastructure d accueil n a jamais ete reconstruite depuis zero — se lisait comme de la prudence. C etait seize defauts que rien d autre n aurait pu reveler. Un locataire naît dans un monde deja peuple : le site lui fournit paquets, noms, genome, heure et depot. Un site n a personne au-dessus, sauf sa frontiere. Onze des seize murs viennent de la. DEUX CAPACITES QUI N EXISTAIENT PAS. make site-raser — rien ne detruisait les machines du site, donc la limite etait un trou d outillage. make forge-amorcer — la forge naît vide et le runner y clone ; l amorcage part du poste, seul endroit qui detienne alors le genome. TROIS GARDES QUI VERIFIAIENT LA FORME. La plus couteuse des familles : elles donnent l apparence d une verification. Le resolveur comparait des adresses au lieu de mesurer si la resolution aboutit, et protegeait ainsi l etat casse. L administration etait reconnue a son port. Un flux a deux paires n obtenait qu une branche. UN ECART DE SECURITE. Le PostgreSQL du site servait le certificat auto-signe de Debian, sans reseaux autorises ni hostssl — invisible tant qu aucun client n exigeait la verification. Le defaut n a pas casse la construction : la construction a revele le defaut. UN ACCES ACCIDENTEL. Celui de l exploitant tenait au chevauchement d adressage que le renumerotage a supprime. Separer les index n a pas cause le probleme, il a retire le hasard qui le masquait. La sequence du premier jour est ecrite : runbooks §9, avec les seize murs et ce que chacun enseigne. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-12 19:08:31 -04:00
trois reconstructions : trouver, verifier, prouver — 37 min 24 au tour 3 Tour 1 8 passages ~2 h 30 16 defauts Tour 2 3 passages 53 min 2 defauts Tour 3 2 passages 37 min 0 LE TOUR 2 EST CELUI QUI COMPTE LE PLUS. J avais annonce deux passages ; il en fallait trois, parce que les deux blocages connus sont EN SERIE : on ne peut pas amorcer une forge qui ne tourne pas, et elle ne tourne qu apres la convergence de la cle. Un runbook ecrit d apres un recit de depannage contenait une erreur qu aucune relecture n aurait montree — il fallait le SUIVRE pour la voir. DEUX MURS DE PLUS, invisibles au tour 1. site-creer rend la main avant que les machines repondent (3 min 20 mesurees). Et les cles d hote changent a chaque reconstruction : accept-new couvre la premiere rencontre, jamais un changement. LE CYCLE DE LA CLE EST DENOUE. Aucun ordre de couches n y pouvait rien — les certificats doivent venir tot. C est la propriete du geste qui a change de main : serveur_forgejo revendique la cle au moment ou il cree le groupe. client_pki garde la sienne et la repose a chaque passage, parce que step reecrit la cle a chaque renouvellement. Gain : un passage entier et 300 secondes d attente perdue. forge-amorcer purge desormais l entree perimee de l hote que GIT va contacter, lu dans git remote get-url — pas celle de l API, qui peut etre un tunnel. Et il rend les quatre premieres lignes de stderr : n afficher que la derniere m a coute un aller-retour, git terminant toujours par un message generique. Le runbook porte les six etapes du tour 3 avec leurs durees reelles et les dix-huit murs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-12 20:55:59 -04:00
## 9. Le premier jour d'un site — la séquence, et les dix-huit murs
le site reconstruit depuis zero : 7/7, 0 echec, et seize corrections SITE-Chezlepro n avait jamais ete rase. La limite qu on repetait partout — l infrastructure d accueil n a jamais ete reconstruite depuis zero — se lisait comme de la prudence. C etait seize defauts que rien d autre n aurait pu reveler. Un locataire naît dans un monde deja peuple : le site lui fournit paquets, noms, genome, heure et depot. Un site n a personne au-dessus, sauf sa frontiere. Onze des seize murs viennent de la. DEUX CAPACITES QUI N EXISTAIENT PAS. make site-raser — rien ne detruisait les machines du site, donc la limite etait un trou d outillage. make forge-amorcer — la forge naît vide et le runner y clone ; l amorcage part du poste, seul endroit qui detienne alors le genome. TROIS GARDES QUI VERIFIAIENT LA FORME. La plus couteuse des familles : elles donnent l apparence d une verification. Le resolveur comparait des adresses au lieu de mesurer si la resolution aboutit, et protegeait ainsi l etat casse. L administration etait reconnue a son port. Un flux a deux paires n obtenait qu une branche. UN ECART DE SECURITE. Le PostgreSQL du site servait le certificat auto-signe de Debian, sans reseaux autorises ni hostssl — invisible tant qu aucun client n exigeait la verification. Le defaut n a pas casse la construction : la construction a revele le defaut. UN ACCES ACCIDENTEL. Celui de l exploitant tenait au chevauchement d adressage que le renumerotage a supprime. Separer les index n a pas cause le probleme, il a retire le hasard qui le masquait. La sequence du premier jour est ecrite : runbooks §9, avec les seize murs et ce que chacun enseigne. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-12 19:08:31 -04:00
> **Écrit le 2026-09-12**, au sortir de la première reconstruction d'un site depuis zéro.
> Avant elle, `SITE-Chezlepro` n'avait jamais été rasé : il avait été monté par ajouts
> successifs, sur des semaines, avec un service déjà debout à chaque étape.
>
> La limite qu'on répétait — « l'infrastructure d'accueil n'a jamais été reconstruite
trois reconstructions : trouver, verifier, prouver — 37 min 24 au tour 3 Tour 1 8 passages ~2 h 30 16 defauts Tour 2 3 passages 53 min 2 defauts Tour 3 2 passages 37 min 0 LE TOUR 2 EST CELUI QUI COMPTE LE PLUS. J avais annonce deux passages ; il en fallait trois, parce que les deux blocages connus sont EN SERIE : on ne peut pas amorcer une forge qui ne tourne pas, et elle ne tourne qu apres la convergence de la cle. Un runbook ecrit d apres un recit de depannage contenait une erreur qu aucune relecture n aurait montree — il fallait le SUIVRE pour la voir. DEUX MURS DE PLUS, invisibles au tour 1. site-creer rend la main avant que les machines repondent (3 min 20 mesurees). Et les cles d hote changent a chaque reconstruction : accept-new couvre la premiere rencontre, jamais un changement. LE CYCLE DE LA CLE EST DENOUE. Aucun ordre de couches n y pouvait rien — les certificats doivent venir tot. C est la propriete du geste qui a change de main : serveur_forgejo revendique la cle au moment ou il cree le groupe. client_pki garde la sienne et la repose a chaque passage, parce que step reecrit la cle a chaque renouvellement. Gain : un passage entier et 300 secondes d attente perdue. forge-amorcer purge desormais l entree perimee de l hote que GIT va contacter, lu dans git remote get-url — pas celle de l API, qui peut etre un tunnel. Et il rend les quatre premieres lignes de stderr : n afficher que la derniere m a coute un aller-retour, git terminant toujours par un message generique. Le runbook porte les six etapes du tour 3 avec leurs durees reelles et les dix-huit murs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-12 20:55:59 -04:00
> depuis zéro » — se lisait comme de la prudence. C'était **dix-huit défauts** que rien
le site reconstruit depuis zero : 7/7, 0 echec, et seize corrections SITE-Chezlepro n avait jamais ete rase. La limite qu on repetait partout — l infrastructure d accueil n a jamais ete reconstruite depuis zero — se lisait comme de la prudence. C etait seize defauts que rien d autre n aurait pu reveler. Un locataire naît dans un monde deja peuple : le site lui fournit paquets, noms, genome, heure et depot. Un site n a personne au-dessus, sauf sa frontiere. Onze des seize murs viennent de la. DEUX CAPACITES QUI N EXISTAIENT PAS. make site-raser — rien ne detruisait les machines du site, donc la limite etait un trou d outillage. make forge-amorcer — la forge naît vide et le runner y clone ; l amorcage part du poste, seul endroit qui detienne alors le genome. TROIS GARDES QUI VERIFIAIENT LA FORME. La plus couteuse des familles : elles donnent l apparence d une verification. Le resolveur comparait des adresses au lieu de mesurer si la resolution aboutit, et protegeait ainsi l etat casse. L administration etait reconnue a son port. Un flux a deux paires n obtenait qu une branche. UN ECART DE SECURITE. Le PostgreSQL du site servait le certificat auto-signe de Debian, sans reseaux autorises ni hostssl — invisible tant qu aucun client n exigeait la verification. Le defaut n a pas casse la construction : la construction a revele le defaut. UN ACCES ACCIDENTEL. Celui de l exploitant tenait au chevauchement d adressage que le renumerotage a supprime. Separer les index n a pas cause le probleme, il a retire le hasard qui le masquait. La sequence du premier jour est ecrite : runbooks §9, avec les seize murs et ce que chacun enseigne. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-12 19:08:31 -04:00
> d'autre n'aurait pu révéler.
trois reconstructions : trouver, verifier, prouver — 37 min 24 au tour 3 Tour 1 8 passages ~2 h 30 16 defauts Tour 2 3 passages 53 min 2 defauts Tour 3 2 passages 37 min 0 LE TOUR 2 EST CELUI QUI COMPTE LE PLUS. J avais annonce deux passages ; il en fallait trois, parce que les deux blocages connus sont EN SERIE : on ne peut pas amorcer une forge qui ne tourne pas, et elle ne tourne qu apres la convergence de la cle. Un runbook ecrit d apres un recit de depannage contenait une erreur qu aucune relecture n aurait montree — il fallait le SUIVRE pour la voir. DEUX MURS DE PLUS, invisibles au tour 1. site-creer rend la main avant que les machines repondent (3 min 20 mesurees). Et les cles d hote changent a chaque reconstruction : accept-new couvre la premiere rencontre, jamais un changement. LE CYCLE DE LA CLE EST DENOUE. Aucun ordre de couches n y pouvait rien — les certificats doivent venir tot. C est la propriete du geste qui a change de main : serveur_forgejo revendique la cle au moment ou il cree le groupe. client_pki garde la sienne et la repose a chaque passage, parce que step reecrit la cle a chaque renouvellement. Gain : un passage entier et 300 secondes d attente perdue. forge-amorcer purge desormais l entree perimee de l hote que GIT va contacter, lu dans git remote get-url — pas celle de l API, qui peut etre un tunnel. Et il rend les quatre premieres lignes de stderr : n afficher que la derniere m a coute un aller-retour, git terminant toujours par un message generique. Le runbook porte les six etapes du tour 3 avec leurs durees reelles et les dix-huit murs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-12 20:55:59 -04:00
>
> **Trois reconstructions complètes** ont été nécessaires : la première pour les trouver,
> la deuxième pour vérifier les correctifs — elle en a révélé deux de plus, invisibles
> tant que l'état n'était pas assez neuf — et la troisième pour prouver la séquence.
>
> | | Passages | Durée | Défauts trouvés |
> |---|---|---|---|
> | Tour 1 | 8 | ~2 h 30 | 16 |
> | Tour 2 | 3 | 53 min | 2 |
> | Tour 3 | **2** | **37 min 24** | **0** |
>
> La séquence ci-dessous est celle du troisième tour. Elle est mesurée, pas reconstituée.
le site reconstruit depuis zero : 7/7, 0 echec, et seize corrections SITE-Chezlepro n avait jamais ete rase. La limite qu on repetait partout — l infrastructure d accueil n a jamais ete reconstruite depuis zero — se lisait comme de la prudence. C etait seize defauts que rien d autre n aurait pu reveler. Un locataire naît dans un monde deja peuple : le site lui fournit paquets, noms, genome, heure et depot. Un site n a personne au-dessus, sauf sa frontiere. Onze des seize murs viennent de la. DEUX CAPACITES QUI N EXISTAIENT PAS. make site-raser — rien ne detruisait les machines du site, donc la limite etait un trou d outillage. make forge-amorcer — la forge naît vide et le runner y clone ; l amorcage part du poste, seul endroit qui detienne alors le genome. TROIS GARDES QUI VERIFIAIENT LA FORME. La plus couteuse des familles : elles donnent l apparence d une verification. Le resolveur comparait des adresses au lieu de mesurer si la resolution aboutit, et protegeait ainsi l etat casse. L administration etait reconnue a son port. Un flux a deux paires n obtenait qu une branche. UN ECART DE SECURITE. Le PostgreSQL du site servait le certificat auto-signe de Debian, sans reseaux autorises ni hostssl — invisible tant qu aucun client n exigeait la verification. Le defaut n a pas casse la construction : la construction a revele le defaut. UN ACCES ACCIDENTEL. Celui de l exploitant tenait au chevauchement d adressage que le renumerotage a supprime. Separer les index n a pas cause le probleme, il a retire le hasard qui le masquait. La sequence du premier jour est ecrite : runbooks §9, avec les seize murs et ce que chacun enseigne. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-12 19:08:31 -04:00
### Ce qui rend un site différent d'un locataire
Un locataire naît dans un monde déjà peuplé : le site lui fournit les paquets, les noms,
le génome, l'heure et le dépôt de sauvegarde. **Un site n'a personne au-dessus de lui**,
sauf sa frontière. Tout ce qu'un locataire reçoit, un site doit se le donner — et pendant
qu'il se le donne, il ne l'a pas.
C'est de là que viennent onze des quinze murs.
### La séquence, dans l'ordre
```bash
# 0. AVANT TOUT — l'état sort du bâtiment
make depot-hors-site VERS=<support hors site>
trois reconstructions : trouver, verifier, prouver — 37 min 24 au tour 3 Tour 1 8 passages ~2 h 30 16 defauts Tour 2 3 passages 53 min 2 defauts Tour 3 2 passages 37 min 0 LE TOUR 2 EST CELUI QUI COMPTE LE PLUS. J avais annonce deux passages ; il en fallait trois, parce que les deux blocages connus sont EN SERIE : on ne peut pas amorcer une forge qui ne tourne pas, et elle ne tourne qu apres la convergence de la cle. Un runbook ecrit d apres un recit de depannage contenait une erreur qu aucune relecture n aurait montree — il fallait le SUIVRE pour la voir. DEUX MURS DE PLUS, invisibles au tour 1. site-creer rend la main avant que les machines repondent (3 min 20 mesurees). Et les cles d hote changent a chaque reconstruction : accept-new couvre la premiere rencontre, jamais un changement. LE CYCLE DE LA CLE EST DENOUE. Aucun ordre de couches n y pouvait rien — les certificats doivent venir tot. C est la propriete du geste qui a change de main : serveur_forgejo revendique la cle au moment ou il cree le groupe. client_pki garde la sienne et la repose a chaque passage, parce que step reecrit la cle a chaque renouvellement. Gain : un passage entier et 300 secondes d attente perdue. forge-amorcer purge desormais l entree perimee de l hote que GIT va contacter, lu dans git remote get-url — pas celle de l API, qui peut etre un tunnel. Et il rend les quatre premieres lignes de stderr : n afficher que la derniere m a coute un aller-retour, git terminant toujours par un message generique. Le runbook porte les six etapes du tour 3 avec leurs durees reelles et les dix-huit murs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-12 20:55:59 -04:00
# 1. Le résolveur d'amorçage, DÉCLARÉ dans le plan du site AVANT de créer quoi que ce soit
le site reconstruit depuis zero : 7/7, 0 echec, et seize corrections SITE-Chezlepro n avait jamais ete rase. La limite qu on repetait partout — l infrastructure d accueil n a jamais ete reconstruite depuis zero — se lisait comme de la prudence. C etait seize defauts que rien d autre n aurait pu reveler. Un locataire naît dans un monde deja peuple : le site lui fournit paquets, noms, genome, heure et depot. Un site n a personne au-dessus, sauf sa frontiere. Onze des seize murs viennent de la. DEUX CAPACITES QUI N EXISTAIENT PAS. make site-raser — rien ne detruisait les machines du site, donc la limite etait un trou d outillage. make forge-amorcer — la forge naît vide et le runner y clone ; l amorcage part du poste, seul endroit qui detienne alors le genome. TROIS GARDES QUI VERIFIAIENT LA FORME. La plus couteuse des familles : elles donnent l apparence d une verification. Le resolveur comparait des adresses au lieu de mesurer si la resolution aboutit, et protegeait ainsi l etat casse. L administration etait reconnue a son port. Un flux a deux paires n obtenait qu une branche. UN ECART DE SECURITE. Le PostgreSQL du site servait le certificat auto-signe de Debian, sans reseaux autorises ni hostssl — invisible tant qu aucun client n exigeait la verification. Le defaut n a pas casse la construction : la construction a revele le defaut. UN ACCES ACCIDENTEL. Celui de l exploitant tenait au chevauchement d adressage que le renumerotage a supprime. Separer les index n a pas cause le probleme, il a retire le hasard qui le masquait. La sequence du premier jour est ecrite : runbooks §9, avec les seize murs et ce que chacun enseigne. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-12 19:08:31 -04:00
# plan/10-intrants.yml : dns_amorcage: <patte de la frontière>
# Sans lui, les machines pointent sur le DNS du site — qui est l'une d'elles.
trois reconstructions : trouver, verifier, prouver — 37 min 24 au tour 3 Tour 1 8 passages ~2 h 30 16 defauts Tour 2 3 passages 53 min 2 defauts Tour 3 2 passages 37 min 0 LE TOUR 2 EST CELUI QUI COMPTE LE PLUS. J avais annonce deux passages ; il en fallait trois, parce que les deux blocages connus sont EN SERIE : on ne peut pas amorcer une forge qui ne tourne pas, et elle ne tourne qu apres la convergence de la cle. Un runbook ecrit d apres un recit de depannage contenait une erreur qu aucune relecture n aurait montree — il fallait le SUIVRE pour la voir. DEUX MURS DE PLUS, invisibles au tour 1. site-creer rend la main avant que les machines repondent (3 min 20 mesurees). Et les cles d hote changent a chaque reconstruction : accept-new couvre la premiere rencontre, jamais un changement. LE CYCLE DE LA CLE EST DENOUE. Aucun ordre de couches n y pouvait rien — les certificats doivent venir tot. C est la propriete du geste qui a change de main : serveur_forgejo revendique la cle au moment ou il cree le groupe. client_pki garde la sienne et la repose a chaque passage, parce que step reecrit la cle a chaque renouvellement. Gain : un passage entier et 300 secondes d attente perdue. forge-amorcer purge desormais l entree perimee de l hote que GIT va contacter, lu dans git remote get-url — pas celle de l API, qui peut etre un tunnel. Et il rend les quatre premieres lignes de stderr : n afficher que la derniere m a coute un aller-retour, git terminant toujours par un message generique. Le runbook porte les six etapes du tour 3 avec leurs durees reelles et les dix-huit murs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-12 20:55:59 -04:00
# Et `nftables_admin_ssh: [<plan d'administration>]`, sans quoi l'exploitant ne
# pourra pas atteindre ce qu'il vient de construire.
le site reconstruit depuis zero : 7/7, 0 echec, et seize corrections SITE-Chezlepro n avait jamais ete rase. La limite qu on repetait partout — l infrastructure d accueil n a jamais ete reconstruite depuis zero — se lisait comme de la prudence. C etait seize defauts que rien d autre n aurait pu reveler. Un locataire naît dans un monde deja peuple : le site lui fournit paquets, noms, genome, heure et depot. Un site n a personne au-dessus, sauf sa frontiere. Onze des seize murs viennent de la. DEUX CAPACITES QUI N EXISTAIENT PAS. make site-raser — rien ne detruisait les machines du site, donc la limite etait un trou d outillage. make forge-amorcer — la forge naît vide et le runner y clone ; l amorcage part du poste, seul endroit qui detienne alors le genome. TROIS GARDES QUI VERIFIAIENT LA FORME. La plus couteuse des familles : elles donnent l apparence d une verification. Le resolveur comparait des adresses au lieu de mesurer si la resolution aboutit, et protegeait ainsi l etat casse. L administration etait reconnue a son port. Un flux a deux paires n obtenait qu une branche. UN ECART DE SECURITE. Le PostgreSQL du site servait le certificat auto-signe de Debian, sans reseaux autorises ni hostssl — invisible tant qu aucun client n exigeait la verification. Le defaut n a pas casse la construction : la construction a revele le defaut. UN ACCES ACCIDENTEL. Celui de l exploitant tenait au chevauchement d adressage que le renumerotage a supprime. Separer les index n a pas cause le probleme, il a retire le hasard qui le masquait. La sequence du premier jour est ecrite : runbooks §9, avec les seize murs et ce que chacun enseigne. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-12 19:08:31 -04:00
trois reconstructions : trouver, verifier, prouver — 37 min 24 au tour 3 Tour 1 8 passages ~2 h 30 16 defauts Tour 2 3 passages 53 min 2 defauts Tour 3 2 passages 37 min 0 LE TOUR 2 EST CELUI QUI COMPTE LE PLUS. J avais annonce deux passages ; il en fallait trois, parce que les deux blocages connus sont EN SERIE : on ne peut pas amorcer une forge qui ne tourne pas, et elle ne tourne qu apres la convergence de la cle. Un runbook ecrit d apres un recit de depannage contenait une erreur qu aucune relecture n aurait montree — il fallait le SUIVRE pour la voir. DEUX MURS DE PLUS, invisibles au tour 1. site-creer rend la main avant que les machines repondent (3 min 20 mesurees). Et les cles d hote changent a chaque reconstruction : accept-new couvre la premiere rencontre, jamais un changement. LE CYCLE DE LA CLE EST DENOUE. Aucun ordre de couches n y pouvait rien — les certificats doivent venir tot. C est la propriete du geste qui a change de main : serveur_forgejo revendique la cle au moment ou il cree le groupe. client_pki garde la sienne et la repose a chaque passage, parce que step reecrit la cle a chaque renouvellement. Gain : un passage entier et 300 secondes d attente perdue. forge-amorcer purge desormais l entree perimee de l hote que GIT va contacter, lu dans git remote get-url — pas celle de l API, qui peut etre un tunnel. Et il rend les quatre premieres lignes de stderr : n afficher que la derniere m a coute un aller-retour, git terminant toujours par un message generique. Le runbook porte les six etapes du tour 3 avec leurs durees reelles et les dix-huit murs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-12 20:55:59 -04:00
# 2. Les VM, depuis l'underlay ~9 min
make site-creer CONFIRMER=true
le site reconstruit depuis zero : 7/7, 0 echec, et seize corrections SITE-Chezlepro n avait jamais ete rase. La limite qu on repetait partout — l infrastructure d accueil n a jamais ete reconstruite depuis zero — se lisait comme de la prudence. C etait seize defauts que rien d autre n aurait pu reveler. Un locataire naît dans un monde deja peuple : le site lui fournit paquets, noms, genome, heure et depot. Un site n a personne au-dessus, sauf sa frontiere. Onze des seize murs viennent de la. DEUX CAPACITES QUI N EXISTAIENT PAS. make site-raser — rien ne detruisait les machines du site, donc la limite etait un trou d outillage. make forge-amorcer — la forge naît vide et le runner y clone ; l amorcage part du poste, seul endroit qui detienne alors le genome. TROIS GARDES QUI VERIFIAIENT LA FORME. La plus couteuse des familles : elles donnent l apparence d une verification. Le resolveur comparait des adresses au lieu de mesurer si la resolution aboutit, et protegeait ainsi l etat casse. L administration etait reconnue a son port. Un flux a deux paires n obtenait qu une branche. UN ECART DE SECURITE. Le PostgreSQL du site servait le certificat auto-signe de Debian, sans reseaux autorises ni hostssl — invisible tant qu aucun client n exigeait la verification. Le defaut n a pas casse la construction : la construction a revele le defaut. UN ACCES ACCIDENTEL. Celui de l exploitant tenait au chevauchement d adressage que le renumerotage a supprime. Separer les index n a pas cause le probleme, il a retire le hasard qui le masquait. La sequence du premier jour est ecrite : runbooks §9, avec les seize murs et ce que chacun enseigne. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-12 19:08:31 -04:00
trois reconstructions : trouver, verifier, prouver — 37 min 24 au tour 3 Tour 1 8 passages ~2 h 30 16 defauts Tour 2 3 passages 53 min 2 defauts Tour 3 2 passages 37 min 0 LE TOUR 2 EST CELUI QUI COMPTE LE PLUS. J avais annonce deux passages ; il en fallait trois, parce que les deux blocages connus sont EN SERIE : on ne peut pas amorcer une forge qui ne tourne pas, et elle ne tourne qu apres la convergence de la cle. Un runbook ecrit d apres un recit de depannage contenait une erreur qu aucune relecture n aurait montree — il fallait le SUIVRE pour la voir. DEUX MURS DE PLUS, invisibles au tour 1. site-creer rend la main avant que les machines repondent (3 min 20 mesurees). Et les cles d hote changent a chaque reconstruction : accept-new couvre la premiere rencontre, jamais un changement. LE CYCLE DE LA CLE EST DENOUE. Aucun ordre de couches n y pouvait rien — les certificats doivent venir tot. C est la propriete du geste qui a change de main : serveur_forgejo revendique la cle au moment ou il cree le groupe. client_pki garde la sienne et la repose a chaque passage, parce que step reecrit la cle a chaque renouvellement. Gain : un passage entier et 300 secondes d attente perdue. forge-amorcer purge desormais l entree perimee de l hote que GIT va contacter, lu dans git remote get-url — pas celle de l API, qui peut etre un tunnel. Et il rend les quatre premieres lignes de stderr : n afficher que la derniere m a coute un aller-retour, git terminant toujours par un message generique. Le runbook porte les six etapes du tour 3 avec leurs durees reelles et les dix-huit murs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-12 20:55:59 -04:00
# 3. ATTENDRE QU'ELLES REPONDENT — `site-creer` ne le fait pas ~3 min
until ansible -i scripts/site_inventaire.py all,'!<hyperviseurs>' -m ping >/dev/null 2>&1
do sleep 10; done
# 4. Passage 1 — va jusqu'à `serveur_ops`, s'arrête sur la forge vide ~20 min
V="$(dirname "$(readlink -f underlay.yml)")/underlay.vault.yml"
ansible-playbook -i scripts/site_inventaire.py playbooks/site.yml -e "@$V"
# 5. Amorcer la forge — elle tourne, elle est vide ~45 s
le site reconstruit depuis zero : 7/7, 0 echec, et seize corrections SITE-Chezlepro n avait jamais ete rase. La limite qu on repetait partout — l infrastructure d accueil n a jamais ete reconstruite depuis zero — se lisait comme de la prudence. C etait seize defauts que rien d autre n aurait pu reveler. Un locataire naît dans un monde deja peuple : le site lui fournit paquets, noms, genome, heure et depot. Un site n a personne au-dessus, sauf sa frontiere. Onze des seize murs viennent de la. DEUX CAPACITES QUI N EXISTAIENT PAS. make site-raser — rien ne detruisait les machines du site, donc la limite etait un trou d outillage. make forge-amorcer — la forge naît vide et le runner y clone ; l amorcage part du poste, seul endroit qui detienne alors le genome. TROIS GARDES QUI VERIFIAIENT LA FORME. La plus couteuse des familles : elles donnent l apparence d une verification. Le resolveur comparait des adresses au lieu de mesurer si la resolution aboutit, et protegeait ainsi l etat casse. L administration etait reconnue a son port. Un flux a deux paires n obtenait qu une branche. UN ECART DE SECURITE. Le PostgreSQL du site servait le certificat auto-signe de Debian, sans reseaux autorises ni hostssl — invisible tant qu aucun client n exigeait la verification. Le defaut n a pas casse la construction : la construction a revele le defaut. UN ACCES ACCIDENTEL. Celui de l exploitant tenait au chevauchement d adressage que le renumerotage a supprime. Separer les index n a pas cause le probleme, il a retire le hasard qui le masquait. La sequence du premier jour est ecrite : runbooks §9, avec les seize murs et ce que chacun enseigne. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-12 19:08:31 -04:00
export SETOPS_FORGE_MDP=… # jamais en argument de ligne de commande
make forge-amorcer CONFIRMER=true
trois reconstructions : trouver, verifier, prouver — 37 min 24 au tour 3 Tour 1 8 passages ~2 h 30 16 defauts Tour 2 3 passages 53 min 2 defauts Tour 3 2 passages 37 min 0 LE TOUR 2 EST CELUI QUI COMPTE LE PLUS. J avais annonce deux passages ; il en fallait trois, parce que les deux blocages connus sont EN SERIE : on ne peut pas amorcer une forge qui ne tourne pas, et elle ne tourne qu apres la convergence de la cle. Un runbook ecrit d apres un recit de depannage contenait une erreur qu aucune relecture n aurait montree — il fallait le SUIVRE pour la voir. DEUX MURS DE PLUS, invisibles au tour 1. site-creer rend la main avant que les machines repondent (3 min 20 mesurees). Et les cles d hote changent a chaque reconstruction : accept-new couvre la premiere rencontre, jamais un changement. LE CYCLE DE LA CLE EST DENOUE. Aucun ordre de couches n y pouvait rien — les certificats doivent venir tot. C est la propriete du geste qui a change de main : serveur_forgejo revendique la cle au moment ou il cree le groupe. client_pki garde la sienne et la repose a chaque passage, parce que step reecrit la cle a chaque renouvellement. Gain : un passage entier et 300 secondes d attente perdue. forge-amorcer purge desormais l entree perimee de l hote que GIT va contacter, lu dans git remote get-url — pas celle de l API, qui peut etre un tunnel. Et il rend les quatre premieres lignes de stderr : n afficher que la derniere m a coute un aller-retour, git terminant toujours par un message generique. Le runbook porte les six etapes du tour 3 avec leurs durees reelles et les dix-huit murs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-12 20:55:59 -04:00
# 6. Passage 2 — doit finir à 0 échec ~4 min
ansible-playbook -i scripts/site_inventaire.py playbooks/site.yml -e "@$V"
le site reconstruit depuis zero : 7/7, 0 echec, et seize corrections SITE-Chezlepro n avait jamais ete rase. La limite qu on repetait partout — l infrastructure d accueil n a jamais ete reconstruite depuis zero — se lisait comme de la prudence. C etait seize defauts que rien d autre n aurait pu reveler. Un locataire naît dans un monde deja peuple : le site lui fournit paquets, noms, genome, heure et depot. Un site n a personne au-dessus, sauf sa frontiere. Onze des seize murs viennent de la. DEUX CAPACITES QUI N EXISTAIENT PAS. make site-raser — rien ne detruisait les machines du site, donc la limite etait un trou d outillage. make forge-amorcer — la forge naît vide et le runner y clone ; l amorcage part du poste, seul endroit qui detienne alors le genome. TROIS GARDES QUI VERIFIAIENT LA FORME. La plus couteuse des familles : elles donnent l apparence d une verification. Le resolveur comparait des adresses au lieu de mesurer si la resolution aboutit, et protegeait ainsi l etat casse. L administration etait reconnue a son port. Un flux a deux paires n obtenait qu une branche. UN ECART DE SECURITE. Le PostgreSQL du site servait le certificat auto-signe de Debian, sans reseaux autorises ni hostssl — invisible tant qu aucun client n exigeait la verification. Le defaut n a pas casse la construction : la construction a revele le defaut. UN ACCES ACCIDENTEL. Celui de l exploitant tenait au chevauchement d adressage que le renumerotage a supprime. Separer les index n a pas cause le probleme, il a retire le hasard qui le masquait. La sequence du premier jour est ecrite : runbooks §9, avec les seize murs et ce que chacun enseigne. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-12 19:08:31 -04:00
```
trois reconstructions : trouver, verifier, prouver — 37 min 24 au tour 3 Tour 1 8 passages ~2 h 30 16 defauts Tour 2 3 passages 53 min 2 defauts Tour 3 2 passages 37 min 0 LE TOUR 2 EST CELUI QUI COMPTE LE PLUS. J avais annonce deux passages ; il en fallait trois, parce que les deux blocages connus sont EN SERIE : on ne peut pas amorcer une forge qui ne tourne pas, et elle ne tourne qu apres la convergence de la cle. Un runbook ecrit d apres un recit de depannage contenait une erreur qu aucune relecture n aurait montree — il fallait le SUIVRE pour la voir. DEUX MURS DE PLUS, invisibles au tour 1. site-creer rend la main avant que les machines repondent (3 min 20 mesurees). Et les cles d hote changent a chaque reconstruction : accept-new couvre la premiere rencontre, jamais un changement. LE CYCLE DE LA CLE EST DENOUE. Aucun ordre de couches n y pouvait rien — les certificats doivent venir tot. C est la propriete du geste qui a change de main : serveur_forgejo revendique la cle au moment ou il cree le groupe. client_pki garde la sienne et la repose a chaque passage, parce que step reecrit la cle a chaque renouvellement. Gain : un passage entier et 300 secondes d attente perdue. forge-amorcer purge desormais l entree perimee de l hote que GIT va contacter, lu dans git remote get-url — pas celle de l API, qui peut etre un tunnel. Et il rend les quatre premieres lignes de stderr : n afficher que la derniere m a coute un aller-retour, git terminant toujours par un message generique. Le runbook porte les six etapes du tour 3 avec leurs durees reelles et les dix-huit murs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-12 20:55:59 -04:00
**Total mesuré : 37 min 24** pour sept machines, de rien du tout à un site complet.
le site reconstruit depuis zero : 7/7, 0 echec, et seize corrections SITE-Chezlepro n avait jamais ete rase. La limite qu on repetait partout — l infrastructure d accueil n a jamais ete reconstruite depuis zero — se lisait comme de la prudence. C etait seize defauts que rien d autre n aurait pu reveler. Un locataire naît dans un monde deja peuple : le site lui fournit paquets, noms, genome, heure et depot. Un site n a personne au-dessus, sauf sa frontiere. Onze des seize murs viennent de la. DEUX CAPACITES QUI N EXISTAIENT PAS. make site-raser — rien ne detruisait les machines du site, donc la limite etait un trou d outillage. make forge-amorcer — la forge naît vide et le runner y clone ; l amorcage part du poste, seul endroit qui detienne alors le genome. TROIS GARDES QUI VERIFIAIENT LA FORME. La plus couteuse des familles : elles donnent l apparence d une verification. Le resolveur comparait des adresses au lieu de mesurer si la resolution aboutit, et protegeait ainsi l etat casse. L administration etait reconnue a son port. Un flux a deux paires n obtenait qu une branche. UN ECART DE SECURITE. Le PostgreSQL du site servait le certificat auto-signe de Debian, sans reseaux autorises ni hostssl — invisible tant qu aucun client n exigeait la verification. Le defaut n a pas casse la construction : la construction a revele le defaut. UN ACCES ACCIDENTEL. Celui de l exploitant tenait au chevauchement d adressage que le renumerotage a supprime. Separer les index n a pas cause le probleme, il a retire le hasard qui le masquait. La sequence du premier jour est ecrite : runbooks §9, avec les seize murs et ce que chacun enseigne. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-12 19:08:31 -04:00
**La voûte se passe en `-e @`** — `make site-appliquer` la dérive du symlink `underlay.yml`,
mais il n'existe aucune cible qui déploie le site EN ENTIER. Un `ansible-playbook` direct
l'oublie, et l'échec parle d'une assertion, jamais d'un fichier manquant.
trois reconstructions : trouver, verifier, prouver — 37 min 24 au tour 3 Tour 1 8 passages ~2 h 30 16 defauts Tour 2 3 passages 53 min 2 defauts Tour 3 2 passages 37 min 0 LE TOUR 2 EST CELUI QUI COMPTE LE PLUS. J avais annonce deux passages ; il en fallait trois, parce que les deux blocages connus sont EN SERIE : on ne peut pas amorcer une forge qui ne tourne pas, et elle ne tourne qu apres la convergence de la cle. Un runbook ecrit d apres un recit de depannage contenait une erreur qu aucune relecture n aurait montree — il fallait le SUIVRE pour la voir. DEUX MURS DE PLUS, invisibles au tour 1. site-creer rend la main avant que les machines repondent (3 min 20 mesurees). Et les cles d hote changent a chaque reconstruction : accept-new couvre la premiere rencontre, jamais un changement. LE CYCLE DE LA CLE EST DENOUE. Aucun ordre de couches n y pouvait rien — les certificats doivent venir tot. C est la propriete du geste qui a change de main : serveur_forgejo revendique la cle au moment ou il cree le groupe. client_pki garde la sienne et la repose a chaque passage, parce que step reecrit la cle a chaque renouvellement. Gain : un passage entier et 300 secondes d attente perdue. forge-amorcer purge desormais l entree perimee de l hote que GIT va contacter, lu dans git remote get-url — pas celle de l API, qui peut etre un tunnel. Et il rend les quatre premieres lignes de stderr : n afficher que la derniere m a coute un aller-retour, git terminant toujours par un message generique. Le runbook porte les six etapes du tour 3 avec leurs durees reelles et les dix-huit murs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-12 20:55:59 -04:00
**Deux passages, et le second ne sert qu'à la forge.** Le premier va jusqu'à la couche 45
sur 46 ; seul `serveur_ops` manque, faute de génome dans une forge neuve.
> **Il en fallait TROIS avant le 2026-09-12.** `client_pki` posait les droits de la clé
> d'hôte pour le groupe `git`, que le paquet de Forgejo crée dans une couche postérieure :
> au premier passage la clé restait fermée, Forgejo ne démarrait pas — après **300 secondes
> d'attente perdue** — et il fallait un passage entier pour qu'il démarre, un autre pour la
> forge. Aucun ordre de couches ne dénoue ce cycle ; c'est la **propriété du geste** qui a
> changé de main : `serveur_forgejo` revendique désormais la clé au moment où il crée le
> groupe. `client_pki` garde la sienne et la repose à chaque passage, parce que `step`
> réécrit la clé à chaque renouvellement.
le site reconstruit depuis zero : 7/7, 0 echec, et seize corrections SITE-Chezlepro n avait jamais ete rase. La limite qu on repetait partout — l infrastructure d accueil n a jamais ete reconstruite depuis zero — se lisait comme de la prudence. C etait seize defauts que rien d autre n aurait pu reveler. Un locataire naît dans un monde deja peuple : le site lui fournit paquets, noms, genome, heure et depot. Un site n a personne au-dessus, sauf sa frontiere. Onze des seize murs viennent de la. DEUX CAPACITES QUI N EXISTAIENT PAS. make site-raser — rien ne detruisait les machines du site, donc la limite etait un trou d outillage. make forge-amorcer — la forge naît vide et le runner y clone ; l amorcage part du poste, seul endroit qui detienne alors le genome. TROIS GARDES QUI VERIFIAIENT LA FORME. La plus couteuse des familles : elles donnent l apparence d une verification. Le resolveur comparait des adresses au lieu de mesurer si la resolution aboutit, et protegeait ainsi l etat casse. L administration etait reconnue a son port. Un flux a deux paires n obtenait qu une branche. UN ECART DE SECURITE. Le PostgreSQL du site servait le certificat auto-signe de Debian, sans reseaux autorises ni hostssl — invisible tant qu aucun client n exigeait la verification. Le defaut n a pas casse la construction : la construction a revele le defaut. UN ACCES ACCIDENTEL. Celui de l exploitant tenait au chevauchement d adressage que le renumerotage a supprime. Separer les index n a pas cause le probleme, il a retire le hasard qui le masquait. La sequence du premier jour est ecrite : runbooks §9, avec les seize murs et ce que chacun enseigne. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-12 19:08:31 -04:00
### Les quinze murs, et ce que chacun enseigne
| # | Le mur | Ce qu'il enseigne |
|---|---|---|
| 1 | Aucun moyen de raser le site | `make site-raser` — la limite était un trou d'outillage, pas une fatalité |
| 2 | La forge naît vide, le runner y clone | `make forge-amorcer` — un amorçage vient de l'extérieur de ce qu'il amorce |
| 3 | `dns_amorcage` pointe sur le DNS du site | le mécanisme existait, la **surcharge** n'avait jamais été posée |
| 4 | La garde du résolveur teste l'adresse écrite | **une adresse écrite ne prouve pas qu'elle répond** |
| 5 | Aucune cible « déployer tout le site » | la voûte n'était jointe nulle part à la séquence complète |
| 6 | `client_pki` bloque sur un groupe absent | blocage **circulaire** : l'échec empêchait d'atteindre ce qui créait le groupe |
| 7 | PostgreSQL du site sans TLS de l'AC | un écart de **sécurité**, révélé par le premier client exigeant `verify-full` |
| 8 | `pg_hba` n'autorisait personne | le site ne déclarait aucun réseau client |
| 9 | `/etc/setops` absent sur le dépôt | un rôle supposait qu'une couche ultérieure était déjà passée |
| 10 | Forgejo attend 300 s une clé illisible | une attente devrait abandonner quand la cause est déjà au journal |
| 11 | La clé SSH de l'exploitant inconnue de la forge | une forge neuve ne connaît personne |
| 12 | L'accès de l'exploitant était **accidentel** | il tenait au chevauchement d'adressage que le renumérotage a supprimé |
| 13 | Le devis reconnaît l'administration à son port | `"22" in ports` plutôt que `"admin" in pairs` |
| 14 | Un flux à deux paires n'obtient qu'une branche | la chaîne de `elif` rangeait `[flotte, admin]` dans un seul cas |
| 15 | Dépôts créés privés, runner anonyme | `could not read Username` — un message qui pointe ailleurs que sa cause |
| 16 | Le wiki n'existe pas sur une forge neuve | Forgejo ne crée `<dépôt>.wiki.git` qu'à la **première page**, posée à la main dans l'interface |
trois reconstructions : trouver, verifier, prouver — 37 min 24 au tour 3 Tour 1 8 passages ~2 h 30 16 defauts Tour 2 3 passages 53 min 2 defauts Tour 3 2 passages 37 min 0 LE TOUR 2 EST CELUI QUI COMPTE LE PLUS. J avais annonce deux passages ; il en fallait trois, parce que les deux blocages connus sont EN SERIE : on ne peut pas amorcer une forge qui ne tourne pas, et elle ne tourne qu apres la convergence de la cle. Un runbook ecrit d apres un recit de depannage contenait une erreur qu aucune relecture n aurait montree — il fallait le SUIVRE pour la voir. DEUX MURS DE PLUS, invisibles au tour 1. site-creer rend la main avant que les machines repondent (3 min 20 mesurees). Et les cles d hote changent a chaque reconstruction : accept-new couvre la premiere rencontre, jamais un changement. LE CYCLE DE LA CLE EST DENOUE. Aucun ordre de couches n y pouvait rien — les certificats doivent venir tot. C est la propriete du geste qui a change de main : serveur_forgejo revendique la cle au moment ou il cree le groupe. client_pki garde la sienne et la repose a chaque passage, parce que step reecrit la cle a chaque renouvellement. Gain : un passage entier et 300 secondes d attente perdue. forge-amorcer purge desormais l entree perimee de l hote que GIT va contacter, lu dans git remote get-url — pas celle de l API, qui peut etre un tunnel. Et il rend les quatre premieres lignes de stderr : n afficher que la derniere m a coute un aller-retour, git terminant toujours par un message generique. Le runbook porte les six etapes du tour 3 avec leurs durees reelles et les dix-huit murs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-12 20:55:59 -04:00
| 17 | `site-creer` rend la main avant que les machines répondent | mesuré à **3 min 20** — un enchaînement automatique échouerait sur `UNREACHABLE` |
| 18 | Les clés d'hôte changent à chaque reconstruction | `accept-new` couvre la première rencontre, **jamais un changement** : `forge-amorcer` purge l'entrée périmée de l'hôte que `git` va contacter |
le site reconstruit depuis zero : 7/7, 0 echec, et seize corrections SITE-Chezlepro n avait jamais ete rase. La limite qu on repetait partout — l infrastructure d accueil n a jamais ete reconstruite depuis zero — se lisait comme de la prudence. C etait seize defauts que rien d autre n aurait pu reveler. Un locataire naît dans un monde deja peuple : le site lui fournit paquets, noms, genome, heure et depot. Un site n a personne au-dessus, sauf sa frontiere. Onze des seize murs viennent de la. DEUX CAPACITES QUI N EXISTAIENT PAS. make site-raser — rien ne detruisait les machines du site, donc la limite etait un trou d outillage. make forge-amorcer — la forge naît vide et le runner y clone ; l amorcage part du poste, seul endroit qui detienne alors le genome. TROIS GARDES QUI VERIFIAIENT LA FORME. La plus couteuse des familles : elles donnent l apparence d une verification. Le resolveur comparait des adresses au lieu de mesurer si la resolution aboutit, et protegeait ainsi l etat casse. L administration etait reconnue a son port. Un flux a deux paires n obtenait qu une branche. UN ECART DE SECURITE. Le PostgreSQL du site servait le certificat auto-signe de Debian, sans reseaux autorises ni hostssl — invisible tant qu aucun client n exigeait la verification. Le defaut n a pas casse la construction : la construction a revele le defaut. UN ACCES ACCIDENTEL. Celui de l exploitant tenait au chevauchement d adressage que le renumerotage a supprime. Separer les index n a pas cause le probleme, il a retire le hasard qui le masquait. La sequence du premier jour est ecrite : runbooks §9, avec les seize murs et ce que chacun enseigne. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-12 19:08:31 -04:00
### Le motif
trois reconstructions : trouver, verifier, prouver — 37 min 24 au tour 3 Tour 1 8 passages ~2 h 30 16 defauts Tour 2 3 passages 53 min 2 defauts Tour 3 2 passages 37 min 0 LE TOUR 2 EST CELUI QUI COMPTE LE PLUS. J avais annonce deux passages ; il en fallait trois, parce que les deux blocages connus sont EN SERIE : on ne peut pas amorcer une forge qui ne tourne pas, et elle ne tourne qu apres la convergence de la cle. Un runbook ecrit d apres un recit de depannage contenait une erreur qu aucune relecture n aurait montree — il fallait le SUIVRE pour la voir. DEUX MURS DE PLUS, invisibles au tour 1. site-creer rend la main avant que les machines repondent (3 min 20 mesurees). Et les cles d hote changent a chaque reconstruction : accept-new couvre la premiere rencontre, jamais un changement. LE CYCLE DE LA CLE EST DENOUE. Aucun ordre de couches n y pouvait rien — les certificats doivent venir tot. C est la propriete du geste qui a change de main : serveur_forgejo revendique la cle au moment ou il cree le groupe. client_pki garde la sienne et la repose a chaque passage, parce que step reecrit la cle a chaque renouvellement. Gain : un passage entier et 300 secondes d attente perdue. forge-amorcer purge desormais l entree perimee de l hote que GIT va contacter, lu dans git remote get-url — pas celle de l API, qui peut etre un tunnel. Et il rend les quatre premieres lignes de stderr : n afficher que la derniere m a coute un aller-retour, git terminant toujours par un message generique. Le runbook porte les six etapes du tour 3 avec leurs durees reelles et les dix-huit murs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-12 20:55:59 -04:00
Douze des dix-huit sont **du code juste en régime établi**, faux le premier jour : un résolveur
le site reconstruit depuis zero : 7/7, 0 echec, et seize corrections SITE-Chezlepro n avait jamais ete rase. La limite qu on repetait partout — l infrastructure d accueil n a jamais ete reconstruite depuis zero — se lisait comme de la prudence. C etait seize defauts que rien d autre n aurait pu reveler. Un locataire naît dans un monde deja peuple : le site lui fournit paquets, noms, genome, heure et depot. Un site n a personne au-dessus, sauf sa frontiere. Onze des seize murs viennent de la. DEUX CAPACITES QUI N EXISTAIENT PAS. make site-raser — rien ne detruisait les machines du site, donc la limite etait un trou d outillage. make forge-amorcer — la forge naît vide et le runner y clone ; l amorcage part du poste, seul endroit qui detienne alors le genome. TROIS GARDES QUI VERIFIAIENT LA FORME. La plus couteuse des familles : elles donnent l apparence d une verification. Le resolveur comparait des adresses au lieu de mesurer si la resolution aboutit, et protegeait ainsi l etat casse. L administration etait reconnue a son port. Un flux a deux paires n obtenait qu une branche. UN ECART DE SECURITE. Le PostgreSQL du site servait le certificat auto-signe de Debian, sans reseaux autorises ni hostssl — invisible tant qu aucun client n exigeait la verification. Le defaut n a pas casse la construction : la construction a revele le defaut. UN ACCES ACCIDENTEL. Celui de l exploitant tenait au chevauchement d adressage que le renumerotage a supprime. Separer les index n a pas cause le probleme, il a retire le hasard qui le masquait. La sequence du premier jour est ecrite : runbooks §9, avec les seize murs et ce que chacun enseigne. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-12 19:08:31 -04:00
qui se pointe sur lui-même, une clé dont le consommateur n'existe pas encore, un répertoire
créé par une couche ultérieure, une forge vide qu'on croit remplie.
Trois sont des **gardes qui vérifiaient la forme au lieu du résultat**. C'est la famille la
plus coûteuse : elles donnent l'apparence d'une vérification.
Un seul touchait la sécurité — et il était invisible tant qu'aucun client n'exigeait la
vérification. **Le défaut n'a pas cassé la construction : la construction a révélé le
défaut.**
> **Pour le prochain site.** Poser `dns_amorcage` dès le départ, prévoir deux passages,
> amorcer la forge entre les deux, déclarer `nftables_admin_ssh` — sans quoi l'exploitant ne
> peut pas atteindre ce qu'il vient de construire — et créer la première page du wiki dans
> l'interface avant `make wiki-publier`.