From 041e36ca7c4226e37b39bb7f98bd26347ad90e13 Mon Sep 17 00:00:00 2001 From: Daniel Allaire Date: Sun, 2 Aug 2026 17:45:56 -0400 Subject: [PATCH] =?UTF-8?q?docs=20:=20le=20retour=20arri=C3=A8re=20de=20la?= =?UTF-8?q?=20migration,=20et=20deux=20renvois=20faux?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit La recette affirmait la réversibilité sans décrire le retour. Or il change de nature à la bascule, et le geste évident — repointer le DNS — devient faux à cet instant : les utilisateurs ont écrit chez l'entrant, et ces données n'existent nulle part ailleurs. Les perdre serait silencieux. Trois régimes écrits : avant le gel (sans conséquence), pendant le gel (dégeler), après la bascule (migration inverse, même outillage). Rendu explicite : le sortant reste gelé après la bascule, jusqu'à confirmation. Le dégeler « au cas où » créerait deux copies vivantes et plus aucune vérité ; en contrepartie il n'a pas divergé, donc le delta d'un retour reste à sens unique. Deux points de non-retour distingués : la bascule fait perdre le retour gratuit, la purge fait tout perdre. D'où l'exigence ajoutée : les critères de confirmation se fixent par écrit AVANT la première bascule. Corrigés : le rattrapage est à l'étape 5 (non 4) ; le chemin de vérification hors DNS public est un prérequis de l'étape 3 elle-même. Preuves : 24 OK, 0 échec. Co-Authored-By: Claude Opus 5 --- CHANGELOG.md | 28 +++++++++++++++++ docs/migration-tenant.md | 68 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 91 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c2be6dd..4ae47fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,33 @@ # CHANGELOG — Set-OPS +## 2026-08-02 (suite 9) — le retour arrière de la migration + +La recette affirmait la réversibilité sans jamais décrire le retour. Or elle **change de +nature à la bascule**, et le geste évident — repointer le DNS — devient faux à cet instant. + +Trois régimes, désormais écrits : + +- **avant le gel** : sans conséquence, le sortant n'a jamais cessé de servir. C'est ce que la + règle d'ordre achète — tout ce qui peut échouer sans coût échoue là ; +- **pendant le gel** : dégeler, l'interruption se limite à la durée du gel ; +- **après la bascule** : ce n'est plus un retour mais une **migration inverse**. Les + utilisateurs ont écrit chez l'entrant — courriels, fichiers, commits — et ces données + n'existent nulle part ailleurs. Repointer le DNS les perdrait, et silencieusement. + +Point rendu explicite : **le sortant reste gelé après la bascule**, jusqu'à confirmation. Le +dégeler « au cas où » créerait deux copies vivantes du même tenant et plus aucune vérité. En +contrepartie il n'a pas divergé, donc le delta d'un retour reste à sens unique. + +Deux points de non-retour à ne pas confondre : la **bascule** fait perdre le retour *gratuit* +(il reste la migration inverse) ; la **purge** fait tout perdre. + +D'où une exigence ajoutée aux points à trancher : les **critères de confirmation** de l'étape +7 se fixent par écrit **avant** la première bascule. Décider après coup ce qui compte comme +« ça marche » revient à se donner raison. + +Corrigés au passage : deux renvois d'étape faux (le rattrapage est à l'étape 5, non 4 ; le +chemin de vérification hors DNS public est un prérequis de l'étape 3 elle-même). + ## 2026-08-02 (suite 8) — recette de migration d'un tenant entre hébergeurs `docs/migration-tenant.md` : la séquence, les états et les gardes. Écrite avant tout code, diff --git a/docs/migration-tenant.md b/docs/migration-tenant.md index d021597..ef2ea02 100644 --- a/docs/migration-tenant.md +++ b/docs/migration-tenant.md @@ -60,7 +60,7 @@ inaccessible tant que l'état `préparé` n'est pas prouvé. | **mandaté** | le tenant a signé ; l'entrant peut commencer | l'entrant a construit | | **préparé** | l'entrant est déployé, restauré (données tièdes) et **prouvé** — mais **pas public** | *garde : preuves vertes chez l'entrant* | | **gelé** | le sortant est en lecture seule ; capture du delta | delta restauré chez l'entrant | -| **basculé** | le DNS public pointe l'entrant, qui sert | l'entrant confirme le service | +| **basculé** | le DNS public pointe l'entrant, qui sert ; **le sortant reste gelé** | l'entrant confirme le service | | **libéré** | le sortant a **révoqué** ses accès ; horloge de rétention lancée | fin de rétention | | **purgé** | le sortant a détruit sa copie | — | @@ -92,7 +92,7 @@ entièrement dessus (`serveur_backup` / `client_backup`). transit présent, zones du plan couvertes (`make underlay`, preuve **P23**). 3. **Créer et déployer** la flotte du tenant chez l'entrant. 4. **Restaurer** depuis un instantané restic *tiède* — les données auront quelques jours ; - c'est voulu, le rattrapage viendra à l'étape 4. + c'est voulu, le rattrapage viendra à l'étape 5. Pendant tout ce temps, le sortant sert normalement. Personne ne voit rien. @@ -105,7 +105,8 @@ C'est le point délicat de toute la procédure : le tenant tourne alors **aux de mais un seul doit servir. Si l'entrant répondait publiquement, le courrier arriverait des deux côtés et l'identité se dédoublerait. Il faut donc un chemin de vérification qui ne dépende pas du DNS public — résolution locale, `/etc/hosts` du poste de vérification, ou vues DNS -séparées. **Ce chemin doit exister avant l'étape 4.** +séparées. **Ce chemin est un prérequis de cette étape** : sans lui, pas de vérification, donc +pas de garde, donc pas de gel. ### Étape 4 — geler (chez le sortant) @@ -123,6 +124,10 @@ passé à l'étape 2. Le DNS public pointe l'adresse publique de l'entrant. Le TTL abaissé à l'étape 1 fait son office. L'interruption se termine à la propagation. +**Le sortant reste gelé.** Le dégeler maintenant créerait deux copies vivantes du même tenant : +un courriel livré chez l'un, un fichier déposé chez l'autre, et plus aucune vérité. Il ne +dégèle qu'en cas de retour arrière (§6), jamais « au cas où ». + ### Étape 7 — confirmer (chez l'entrant) Le service répond publiquement, les preuves passent, le tenant valide. **C'est ce qui autorise @@ -141,7 +146,58 @@ rattrape ça après coup. Puis rétention — durée convenue — avant purge. -## 6. Ce que la migration ne déplace pas +## 6. Le retour arrière + +La réversibilité n'est pas uniforme : elle change de nature à la bascule. Trois régimes, trois +réponses différentes — et il faut les avoir décidées avant, pas à trois heures du matin. + +### Avant le gel — sans conséquence + +Les étapes 2 et 3 échouent chez l'entrant. Le sortant n'a jamais cessé de servir et ignore +tout de l'affaire. On corrige ou on jette la construction, on recommence. Aucun utilisateur +n'a rien vu. + +C'est précisément ce que la règle du §3 achète : **tout ce qui peut échouer sans coût échoue +avant le gel.** + +### Pendant le gel, avant la bascule — dégeler, et c'est tout + +Le rattrapage du delta échoue, ou une vérification de dernière minute déraille. L'entrant ne +sert pas encore : rien n'y a été écrit qui compte. + +On dégèle le sortant. L'interruption aura duré le temps du gel — quelques minutes. La +construction chez l'entrant reste debout pour un nouvel essai. + +### Après la bascule — ce n'est plus un retour, c'est une migration inverse + +Dès que l'entrant sert, les utilisateurs y écrivent : courriels reçus, fichiers déposés, +commits poussés. **Ces données n'existent nulle part ailleurs.** Repointer simplement le DNS +vers le sortant les perdrait — et silencieusement, ce qui est pire. + +Le retour arrière devient donc une migration dans l'autre sens, avec la même mécanique : +geler l'entrant, capturer le delta, le restaurer chez le sortant, repointer le DNS, dégeler le +sortant. C'est faisable — c'est le même outillage — mais ça se prépare, ça ne s'improvise pas. + +Bonne nouvelle : le sortant est **encore gelé** (étape 6), donc il n'a pas divergé de son côté. +Le delta est à sens unique, et la fusion n'a pas lieu d'être. + +### Ce qui en découle + +**Les critères de confirmation se définissent avant l'étape 6, pas pendant l'étape 7.** La +bascule est le moment où le coût d'un échec change d'ordre de grandeur ; décider *ensuite* ce +qui compte comme « ça marche » revient à se donner raison après coup. + +**Deux points de non-retour**, à ne pas confondre : + +| Point | Ce qu'on perd | Ce qu'il reste | +|---|---|---| +| **la bascule** (étape 6) | le retour gratuit | le retour par migration inverse | +| **la purge** (fin de rétention) | la copie du sortant | rien — c'est le vrai point de non-retour | + +Entre `libéré` et `purgé`, revenir reste possible mais coûte un second re-clétage : le sortant +a révoqué ses accès, il faudrait les rétablir. + +## 7. Ce que la migration ne déplace pas - **La fabric** : l'underlay appartient à l'hébergeur. Le tenant en change, il n'en emporte pas. @@ -149,11 +205,13 @@ Puis rétention — durée convenue — avant purge. `make devis-opnsense` est déjà multi-tenant. - **L'index** : c'est une coordonnée locale à une fédération, pas une propriété du tenant. -## 7. Ce qui reste à trancher +## 8. Ce qui reste à trancher - **Le format du mandat** et l'emplacement de la clé publique du tenant dans son plan. - **Le chemin de vérification hors DNS public** (étape 3) — le plus structurant. - **La durée de rétention** avant purge, et qui l'atteste. +- **Les critères de confirmation** de l'étape 7, à fixer par écrit avant la première bascule + (§6) — c'est ce qui décide si un retour arrière s'impose. - **L'outillage** : un `devis-migration` dériverait l'index retenu, l'adressage résultant et la compatibilité de fabric, et refuserait sur un point bloquant — dans l'idiome du dépôt : dériver un plan, le prouver, laisser l'humain l'appliquer. À écrire **après** avoir joué la