Les trois dates de « décisions renversées » avaient été estimées. L'historique les corrige : ACL et routage sur commutateur remontent au 2026-07-07 (`make devis-reseau`), pas au 29 juillet ; l'underlay gitignoré au 2026-07-24, pas au 31. Un registre qui invente une date perd la confiance qu'on lui accorde sur le reste. Chaque renversement cite maintenant le commit qui l'a opéré — vérifiable en une commande. Ajouté : qui décide. Toutes ces décisions sont celles de l'opérateur du dépôt, plusieurs prises sur recommandation ; l'assistance propose et argumente, elle ne tranche pas. La distinction compte pour la suite : une décision se renverse par celui qui l'a prise, et savoir qu'elle a été choisie plutôt qu'héritée change ce qu'on s'autorise à en faire. Non corrigé : le renvoi de D-07. `frontiere-opnsense.md` §1 porte bien un titre explicite « Décision (2026-08-02) : pas d'ACL sur cette fabric » — ma réserve était infondée. Preuves : 24 OK, 0 échec. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
8.1 KiB
Registre des décisions d'architecture
À quoi sert ce document. Les décisions sont écrites là où elles s'appliquent —
frontiere-opnsense.md,sdn-evpn.md,migration-tenant.md,underlay.yml.example— et leur histoire vit dans leCHANGELOG. Ce registre ne les répète pas : il dit quelles décisions existent, pourquoi, et où lire le détail. Sans lui, « pourquoi le/29et pas le/30? » demande de relire vingt entrées de journal.
Ce n'est pas la doctrine de conduite (AGENTS.md §Principes), ni le registre des
affirmations prouvables (docs/audit/affirmations.md). Une décision peut n'être gardée par
aucune preuve : elle reste une décision.
Qui décide. Toutes ces décisions sont celles de l'opérateur du dépôt. Plusieurs ont été prises sur recommandation — l'assistance propose et argumente, elle ne tranche pas. La distinction compte pour la suite : une décision se renverse par celui qui l'a prise, et savoir qu'elle a été choisie plutôt que héritée change ce qu'on s'autorise à en faire.
Les dates de la §5 sont celles de l'historique git, pas du moment de la conversation : ce sont les seules vérifiables.
1. Le réseau
| # | Décision | Pourquoi | Détail | Garde |
|---|---|---|---|---|
| D-01 | OPNsense est une frontière nord/sud, pas la passerelle des zones | le routage inter-zone reste au débit ligne ; la bordure ne voit pas l'est-ouest | frontiere-opnsense.md §1 |
— |
| D-02 | Le lien de transit vit dans l'underlay, pas dans un tenant | la frontière route vers tous les tenants par le même saut : il ne peut dériver d'aucun index |
frontiere-opnsense.md §6 |
P23 |
| D-03 | Le /29 de transit : frontières en bas (.1,.2), SVI en haut (.6), .3 réservée |
deux pare-feux cohabitent pendant une transition ; .3 attend une IP virtuelle CARP |
frontiere-opnsense.md §6 |
P23 |
| D-04 | Un point de routage porte le même dernier octet sur tous ses sous-réseaux | on retient une adresse, pas treize | frontiere-opnsense.md §4 |
P23 |
| D-05 | Un seul commutateur route ; les autres restent en L2 pur | sans MLAG, dupliquer les SVI créerait autant de conflits d'adresses que de zones | underlay.yml.example |
P23 |
| D-06 | Les réseaux déclarent leur fabric ; un devis ne parle que de la sienne | le stockage jumbo vit sur ses propres commutateurs — un devis est une configuration, pas un inventaire | sdn-evpn.md §4 |
P23 |
| D-07 | Pas d'ACL sur cette fabric (acl_inter_tenant: false) |
le matériel ne sait pas lier une ACL à un SVI ; des règles jamais liées auraient l'air d'isoler | frontiere-opnsense.md §1 |
— |
| D-08 | Le routage tenant passe au SDN EVPN — une zone par tenant | une zone EVPN est un VRF : l'isolation devient structurelle, pas réglementaire | sdn-evpn.md |
P23 (MTU) |
| D-09 | Le filtrage inter-zone d'un tenant se fait au même niveau (EVPN) | là où le routage a lieu | sdn-evpn.md §3 |
— |
| D-10 | L'inter-tenant passe obligatoirement par la frontière | il sort du VRF, donc traverse une bordure en block par défaut : il ne peut plus être oublié |
sdn-evpn.md §3 |
— |
| D-11 | La sortie générale est déclarée dans le registre des flux | block out est un vrai default-deny ; un besoin oublié ne se manifeste pas par un refus clair |
frontiere-opnsense.md §8 |
P09 |
| D-12 | Nommage : bifrost aux frontières, sleipnir à la fabric |
Bifröst est le pont vers l'extérieur ; Sleipnir traverse les mondes sans en sortir | frontiere-opnsense.md §6 |
— |
2. Qui possède quoi
| # | Décision | Pourquoi | Détail | Garde |
|---|---|---|---|---|
| D-13 | Un hébergeur sert plusieurs tenants et a son tenant par défaut | Chezlepro est les deux à la fois, ce qui masquait la distinction | frontiere-opnsense.md §2 |
— |
| D-14 | underlay.yml appartient à l'hébergeur, monté par symlink |
ce sont ses commutateurs, ses câbles ; le moteur est générique, un tenant n'en possède pas | sdn-evpn.md, underlay.yml.example |
— |
| D-15 | Ce symlink ne suit pas make instance-utiliser |
basculer le tenant actif ne change pas la fabric | frontiere-opnsense.md §2 |
— |
| D-16 | Les intrants de la frontière se lisent chez l'hébergeur | un hébergeur n'a qu'une frontière pour tous ses tenants | frontiere-opnsense.md §2 |
— |
| D-17 | L'hébergeur n'est pas déclaré : le symlink le désigne | une seconde déclaration ouvrirait deux valeurs contradictoires | frontiere-opnsense.md §2 |
— |
| D-18 | Chaque tenant a un responsable désigné | sans lui, « qui peut décider de déménager cette organisation ? » se pose au pire moment | migration-tenant.md §3 |
— |
3. Les secrets
| # | Décision | Pourquoi | Détail | Garde |
|---|---|---|---|---|
| D-19 | Une seule voûte par instance (group_vars/all/vault.yml) |
un mot de passe, un endroit | config-proxmox.md |
P18 |
| D-20 | La liste des secrets se recense, elle ne s'écrit pas | trois copies manuelles ont existé, toutes ont divergé | intrants-communs.md §H |
P18 |
| D-21 | L'empreinte du root CA n'est pas un secret : elle se dérive à chaud | un from-zero régénère l'AC ; figée en voûte, elle serait périmée |
roles/client_pki/README.md |
— |
| D-22 | Migrer un tenant, c'est révoquer, pas transmettre | sinon l'ancien hébergeur garde à vie l'accès aux secrets d'un client parti | migration-tenant.md §6 |
— |
4. La méthode
| # | Décision | Pourquoi | Détail | Garde |
|---|---|---|---|---|
| D-23 | Les cibles hors flotte reçoivent un devis, pas un rôle | commutateurs, frontière et SDN sont des objets de cluster ; un rôle boucle sur des hôtes | sdn-evpn.md §7 |
— |
| D-24 | Un devis n'écrit rien : il se relit, puis s'applique | proportionné au risque — une config ratée partitionne tout un cluster | frontiere-opnsense.md §7 |
— |
| D-25 | Le dépôt n'affirme pas que ses devis s'appliquent, il affirme qu'ils dérivent | leur syntaxe dépend d'un matériel que le dépôt ne possède pas | audit/affirmations.md §10 |
— |
| D-26 | Un modèle peut porter un underlay ; tous les hébergeurs n'ont pas le même matériel | générique public, étoffés en privé | exemples/modeles/socle/README.md |
P17 |
| D-27 | Migration : le receveur est prouvé prêt avant tout gel | l'interruption se réduit au delta et à la propagation DNS | migration-tenant.md §4 |
— |
| D-28 | Le mandat de migration est signé par le tenant, pas convenu entre hébergeurs | il n'y a pas de registre central pour arbitrer ; une organisation n'est pas la propriété de son hébergeur | migration-tenant.md §2 |
— |
5. Décisions renversées
Les garder évite de refaire le chemin, et explique pourquoi le code porte encore des branches qui semblent inutiles.
| Décision | Tenue du … au … | Renversée par | Pourquoi | Ce qu'il en reste |
|---|---|---|---|---|
| L'isolation inter-tenant est portée par des ACL de commutateur | 2026-07-07 → 08-03 | 059d76a |
le matériel ne sait pas lier une ACL à une interface de routage | acl_inter_tenant: true reste le défaut : une autre fabric peut en être capable |
| Le routage inter-zone est porté par les commutateurs L3 | 2026-07-07 → 08-03 | e5ce2b9 |
sans ACL, l'isolation devenait déclarative ; EVPN la rend structurelle | routage_tenants: switch reste le défaut et reste généré |
L'underlay.yml vit à la racine du moteur, gitignoré |
2026-07-24 → 08-02 | 0eae97c |
consommé par deux générateurs, validé par une preuve, versionné nulle part | SETOPS_UNDERLAY permet toujours de le pointer ailleurs |
Ce que ces renversements ont en commun. Aucun ne vient d'un changement d'avis : les trois viennent d'un fait découvert après la décision — une commande absente de l'aide du matériel, une capacité manquante, une dizaine de modifications irrécupérables. C'est l'argument le plus fort pour éprouver avant de figer.