diff --git a/CHANGELOG.md b/CHANGELOG.md index 03a2a38..d51ab25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,73 @@ # CHANGELOG — Set-OPS +## 2026-08-21 — L'intuition disait « blockchain » ; la réponse était déjà dans git + +L'exploitant, en regardant la lignée s'ouvrir : *« j'ai une intuition : blockchain. »* +L'intuition visait le bon problème — une mémoire partagée, vérifiable, sans centre — mais +la réponse était à portée de main, et une vérification l'a montré : + +``` +1f47e9b N 6148877 N 254268d N (N = aucune signature) +aucune étiquette +``` + +**Git est déjà une chaîne de hachage.** Chaque commit porte l'empreinte de son parent : +modifier une ligne d'il y a trois mois casse toutes les empreintes suivantes. C'est un +arbre de Merkle — la même structure qu'une blockchain, sans le reste. Ce qui manquait +n'était pas la chaîne, mais **l'auteur** : `user.name` est déclaratif, et toute la soirée +du 20 des commits ont porté « Daniel Allaire » sans qu'aucune preuve ne les lie à une clé. + +### Trois manques, trois réponses mûres + +| Manque | Posé aujourd'hui | +|---|---| +| **qui** a écrit | signature par clé SSH ; première étiquette signée `v2026.08.21`, vérifiée | +| **quelles clés** ont le droit | `.git-allowed-signers`, **versionné** : qui clone vérifie sans rien demander à la forge | +| **de quoi** on descend | `parente.yml` par écosystème, et la preuve **P40** | + +### Ce que la fractale fait gratuitement + +Une signature prouve l'auteur, pas que l'histoire n'a pas été **remplacée** — celui qui +tient la forge peut réécrire et re-signer. Le seul remède est la multiplicité : si chaque +enfant porte une copie du code dont il descend, réécrire suppose de convaincre **tous les +descendants**. + +C'est très exactement ce qu'une blockchain achète au prix d'une machinerie considérable, et +que la lignée produit **comme effet secondaire de sa forme**. Une chaîne publique +ajouterait une dépendance à un réseau extérieur ; une chaîne privée, une base de données +distribuée exigeant plusieurs opérateurs — l'inverse de *« un humain doit pouvoir la faire +tourner »*. + +### Le génome + +`make genome` nomme les **quatre dépôts** sans lesquels un écosystème ne renaît pas : +moteur, instance, hébergeur, modèles. Ils sont **dérivés**, pas déclarés — les modèles se +reconnaissent à leur forme (des plans en sous-dossiers, aucun à la racine). + +Deux critères appris d'un faux positif : sans le second, le détecteur désignait le lab, qui +porte un lien `OPS-Technolibre -> ../OPS-Technolibre` que le motif traversait. **Un lien +vers un frère n'est pas un contenu.** + +Patient 0 sait désormais d'où il vient : moteur `742bcbf`, étiquette `v2026.08.21`. + +### Enseigné, pas seulement posé + +Nouvelle unité : [Filiation, signatures & témoins](wiki/Filiation-signatures-et-témoins.md) +— pourquoi git suffit, ce qu'une signature prouve et ce qu'elle ne prouve pas, pourquoi les +témoins comptent plus que la longueur des clés, et quand un **journal de transparence** +serait la vraie réponse (le jour où l'Alliance certifiera des écosystèmes). + +Onze termes ajoutés au glossaire — génome, parenté, empreinte, Merkle, étiquette, +signature, témoin, journal de transparence, horodatage… — et **P39 les exige désormais** : +le vocabulaire de ce soir ne pourra pas rester non expliqué. + +`make verifier` : **40 OK, 0 échec, 0 sauté**. + +> **La bonne question n'était pas « quelle technologie ».** C'était : *contre qui se +> protège-t-on, et qui, déjà, pourrait témoigner ?* Les témoins existaient — ce sont les +> enfants. Il ne manquait qu'un nom sur les clés et un registre de filiation. + + ## 2026-08-21 — Le glossaire définissait Set-OPS et laissait dehors tout le métier Demande de l'exploitant, après une soirée passée à croiser *strophe FRR*, *VRF*, *VNet* et diff --git a/docs/audit/plan-de-recette.md b/docs/audit/plan-de-recette.md index abcc691..9b9ecb9 100644 --- a/docs/audit/plan-de-recette.md +++ b/docs/audit/plan-de-recette.md @@ -10,7 +10,7 @@ Ce plan est le **pendant manuel** de `make prouver` : là où le harnais prouve le côté humain **est** la preuve de l'affirmation « exploitable sans IA » (cf. `protocole-operateur-independant.md`). -**85 gestes** sur **21 unités** · **19** en « casse-répare » +**89 gestes** sur **22 unités** · **19** en « casse-répare » · **5** doublés d'un garde-fou machine (colonne *Preuve auto*). > **Honnêteté de couverture.** La colonne *Preuve auto* n'est remplie que lorsqu'une @@ -72,6 +72,17 @@ le côté humain **est** la preuve de l'affirmation « exploitable sans IA » (c *Source : [DNS & résolution de noms](DNS-et-résolution) · § À toi de jouer.* +## Filiation, signatures et témoins + +| # | Ce qu'on éprouve | Le geste (avec l'attendu) | Type | Preuve auto | +|---|---|---|---|---| +| 1 | — | make genome — quatre dépôts ? Lequel n'a pas de *remote* ? Celui-là n'existe qu'ici. | 👁 observe | — | +| 2 | — | git verify-tag v2026.08.21 — que se passe-t-il si tu retires ta ligne de .git-allowed-signers ? (remets-la ensuite) | 👁 observe | — | +| 3 | — | make genome-inscrire, puis ouvre parente.yml. Dans un an, qu'est-ce que ce fichier te dira que ta mémoire ne dira plus ? | 👁 observe | — | +| 4 | — | Demande-toi où sont les témoins aujourd'hui. Combien de copies vivantes du moteur existent, sur combien de machines distinctes ? C'est la vraie mesure de la résistance de la lignée — pas la longueur des clés. Voir aussi : Multi-instance… | 👁 observe | — | + +*Source : [Filiation, signatures et témoins](Filiation-signatures-et-témoins) · § À toi de jouer.* + ## Identité & SSO | # | Ce qu'on éprouve | Le geste (avec l'attendu) | Type | Preuve auto | diff --git a/scripts/prouver.py b/scripts/prouver.py index 135d739..16625ec 100644 --- a/scripts/prouver.py +++ b/scripts/prouver.py @@ -734,9 +734,42 @@ JARGON_A_ENSEIGNER = [ "SMTP", "IMAP", "LMTP", "DKIM", "MTA", # etat et methode "restic", "devis", "preuve", "harnais", "GUI", "index", "plan", "tenant", + # filiation — le vocabulaire arrive le 2026-08-21 avec les signatures + "genome", "parente", "commit", "empreinte", "Merkle", "etiquette", "signature", + "allowed-signers", "temoin", "journal de transparence", "horodatage", ] +def preuve_parente_inscrite() -> tuple[bool, str]: + """L'ecosysteme sait de QUOI il descend, et cette filiation tient encore. + + POURQUOI (2026-08-21). Un ecosysteme se reproduit depuis quatre depots, pas depuis ses + machines. Fabrique aujourd'hui depuis la forge de son parent, il ne saura plus dans un + an de quel moteur il descend ni a quel etat — et cinq enfants sans registre font cinq + moteurs differents que plus personne ne sait rapprocher. C'est la mutation sans + memoire : le seul vrai risque d'une lignee. + + CE QU'ELLE TESTE (via `scripts/genome.py verifier`) : la parente est inscrite ; chaque + depot qu'elle nomme se retrouve ; chaque commit inscrit EXISTE encore dans son depot + (une histoire reecrite se voit ici) ; et chacun porte un remote — un depot qui n'existe + qu'ici n'est pas une lignee, c'est un point unique de defaillance. + + SAUTEE quand l'instance n'est pas un depot git : c'est le cas du modele public monte + par la CI. Un gabarit jetable n'a pas d'ascendance a declarer, et exiger un + `parente.yml` d'une copie temporaire ferait echouer la CI pour une question qui n'a pas + de sens dans son contexte. + + CE QU'ELLE NE TESTE PAS : que le depot distant contienne encore ce commit. Cela exige + de joindre la forge ; ici on ne verifie que ce qui est lisible hors ligne. + """ + if not (INSTANCE / ".git").exists(): + return True, "Instance sans depot git (modele jetable) : aucune ascendance a declarer." + r = subprocess.run([sys.executable, "scripts/genome.py", "verifier"], + cwd=RACINE, capture_output=True, text=True, timeout=120) + sortie = (r.stdout + r.stderr).strip().splitlines() + return r.returncode == 0, (sortie[-1] if sortie else "") + + def preuve_glossaire_enseigne() -> tuple[bool, str]: """Tout mot que le depot emploie devant l'exploitant est explique au glossaire. @@ -1069,6 +1102,8 @@ PREUVES: list[dict] = [ "func": preuve_catalogue_a_jour}, {"id": "P39", "titre": "Glossaire : tout mot employe est enseigne", "refs": [], "func": preuve_glossaire_enseigne}, + {"id": "P40", "titre": "Parente : l'ecosysteme sait de quoi il descend", "refs": [], + "func": preuve_parente_inscrite}, {"id": "P33", "titre": "Aucune collision de port entre roles co-localises", "refs": [], "cmds": [[sys.executable, "scripts/verifier_ports.py"]]}, ] diff --git a/wiki/Filiation-signatures-et-témoins.md b/wiki/Filiation-signatures-et-témoins.md new file mode 100644 index 0000000..f2c9619 --- /dev/null +++ b/wiki/Filiation-signatures-et-témoins.md @@ -0,0 +1,139 @@ +# Filiation, signatures et témoins + +> **Unité d'apprentissage.** Moule : ① concept → ② Set-OPS → ③ transférable → ④ à toi de jouer. + +Un écosystème Set-OPS peut en **engendrer** un autre. Dès qu'il y a une descendance, trois +questions apparaissent, et aucune n'est technique au départ : + +- **de qui** cet écosystème descend-il ? +- **qui** a le droit de modifier ce dont il descend ? +- comment le savoir **sans faire confiance** à celui qui héberge le code ? + +--- + +## ① Le concept + +### Git est déjà une chaîne de hachage + +C'est la chose la plus utile à comprendre, et la moins connue. Chaque commit contient +l'**empreinte** de son parent. Changer une ligne d'il y a trois mois change l'empreinte de +ce commit — donc celle du suivant, et de tous les autres jusqu'à aujourd'hui. + +``` +A ←── B ←── C ←── D modifier B casse C et D +``` + +C'est un **arbre de Merkle** : la même structure de données qu'une blockchain. L'intégrité +est déjà là, gratuitement, depuis 2005. + +### Ce que la chaîne ne dit pas + +**Qui a écrit.** `user.name` est purement déclaratif : n'importe qui peut signer « Daniel +Allaire » et pousser. Rien ne lie ce nom à une personne. + +C'est ce que corrigent les **signatures**. Avec une clé — la même clé SSH que pour se +connecter — on scelle une étiquette ou un commit. Qui possède la **clé publique** peut +vérifier ; qui ne possède pas la **clé privée** ne peut pas contrefaire. + +Reste alors une question : *quelles clés ont le droit de signer ?* La réponse doit vivre +**avec le code**, pas chez l'hébergeur — sinon on remplace la confiance en une personne par +la confiance en une plateforme. + +### Les témoins, ou pourquoi la fractale est le registre + +Une signature prouve l'auteur, pas que l'histoire n'a pas été **remplacée**. Celui qui tient +la forge peut réécrire et re-signer. + +Contre ça, un seul remède : la **multiplicité**. Si chaque écosystème enfant porte une copie +du code dont il descend, réécrire l'histoire suppose de convaincre **tous les descendants**. +C'est exactement ce qu'une blockchain achète au prix d'une machinerie considérable — et +qu'une lignée produit comme **effet secondaire de sa forme**. + +> **Pourquoi pas une blockchain, alors ?** Elle résout un problème précis : *qui écrit +> ensuite, quand personne ne fait confiance à personne et qu'il y a de l'argent en jeu.* +> Ici : les membres sont connus, il n'y a pas d'argent dans la boucle, et une ancre de +> confiance existe déjà. Une chaîne publique ajouterait une dépendance à un réseau +> extérieur ; une chaîne privée, une base de données distribuée exigeant plusieurs +> opérateurs — l'inverse de « un humain doit pouvoir la faire tourner ». + +--- + +## ② Dans Set-OPS + +### Les quatre dépôts du génome + +Un écosystème ne se reproduit pas depuis ses machines. Il se reproduit depuis **quatre +dépôts** — et `make genome` les nomme : + +| Rôle | Ce qu'il porte | +|---|---| +| **moteur** | Set-OPS : les rôles, les preuves, le Makefile | +| **instance** | le plan du tenant, sa voûte chiffrée | +| **hébergeur** | l'`underlay.yml` du site : sa fabric physique | +| **modèles** | les offres dont les instances sont tirées | + +Perdre les VM coûte du temps. Perdre ces quatre-là coûte l'écosystème. + +### Le registre des signataires + +`.git-allowed-signers`, **versionné dans le dépôt** : + +``` +allaire.dan@chezlepro.ca ssh-ed25519 AAAAC3NzaC1lZDI1... +``` + +Qui clone peut vérifier sans rien demander à la forge. Retirer une ligne **révoque** le +signataire pour la suite ; ce qui est déjà signé reste vérifiable — on ne réécrit pas le +passé, on cesse d'accepter l'avenir. + +### La parenté, inscrite + +`make genome-inscrire` écrit `parente.yml` dans l'instance : de quel moteur elle descend, +à quel **commit**, sous quelle **étiquette signée**. + +```yaml +moteur: + remote: ssh://…/Set-OPS-Public.git + commit: 742bcbf4b0e1322bfa5e0dee14c94bcad6898c53 + etiquette: v2026.08.21 +``` + +Sans ce fichier, un écosystème fabriqué aujourd'hui ne sait plus, dans un an, d'où il +vient. Cinq enfants sans registre font cinq moteurs différents que plus personne ne sait +rapprocher. **C'est la mutation sans mémoire, et c'est le seul vrai risque d'une lignée.** + +La preuve **P40** vérifie que la parenté est inscrite, que chaque dépôt nommé se retrouve, +que chaque commit inscrit **existe encore** — une histoire réécrite se voit là — et que +chacun porte un *remote* : un dépôt qui n'existe qu'ici n'est pas une lignée, c'est un +point unique de défaillance. + +--- + +## ③ Transférable + +Rien ici n'appartient à Set-OPS : + +- **signature par clé SSH** : git 2.34+, partout, sans infrastructure ; +- **`allowed_signers`** : le mécanisme natif d'OpenSSH ; +- **journal de transparence** (Certificate Transparency, Sigstore) : la réponse mûre quand + plusieurs organisations doivent constater les mêmes faits sans se faire confiance ; +- **horodatage RFC 3161** : prouver qu'un document existait à une date. + +Le jour où l'Alliance certifiera des écosystèmes, c'est un **journal de transparence** +qu'il faudra — un registre append-only, auditable par un tiers — et non une blockchain. + +--- + +## ④ À toi de jouer + +1. `make genome` — quatre dépôts ? Lequel n'a pas de *remote* ? Celui-là n'existe qu'ici. +2. `git verify-tag v2026.08.21` — que se passe-t-il si tu retires ta ligne de + `.git-allowed-signers` ? (remets-la ensuite) +3. `make genome-inscrire`, puis ouvre `parente.yml`. Dans un an, qu'est-ce que ce fichier + te dira que ta mémoire ne dira plus ? +4. Demande-toi où sont les **témoins** aujourd'hui. Combien de copies vivantes du moteur + existent, sur combien de machines distinctes ? C'est la vraie mesure de la résistance de + la lignée — pas la longueur des clés. + +**Voir aussi** : [Multi-instance & fédération](Multi-instance-et-fédération), +[La preuve](La-preuve), [Sauvegardes](Sauvegardes). diff --git a/wiki/Glossaire.md b/wiki/Glossaire.md index 1f3278d..5ebed9c 100644 --- a/wiki/Glossaire.md +++ b/wiki/Glossaire.md @@ -306,3 +306,42 @@ quoi** il a porté. [Le GUI](Le-GUI-console-d-exploitation). **CI** — La vérification automatique à chaque poussée (`make ci` la rejoue à l'identique). + +--- + +## La filiation + +→ Unité complète : [Filiation, signatures & témoins](Filiation-signatures-et-témoins) + +**Génome** — Les **quatre dépôts** sans lesquels un écosystème ne peut pas être refabriqué : +le *moteur*, l'*instance*, le dépôt de l'hébergeur, les *modèles*. `make genome` les nomme. + +**Parenté** — Le fichier `parente.yml` d'une instance : de quel moteur elle descend, à quel +*commit*, sous quelle *étiquette signée*. Sans lui, un écosystème ne sait plus d'où il vient. + +**Commit** — Un instantané du dépôt, qui porte l'**empreinte** du précédent. Modifier le +passé change toutes les empreintes suivantes : c'est ce qui rend une histoire vérifiable. + +**Empreinte (hachage)** — Une courte signature calculée d'un contenu. Deux contenus +différents n'ont pas la même — c'est ce qui permet de détecter une modification. + +**Arbre de Merkle** — La structure où chaque élément porte l'empreinte du précédent. Git en +est un ; une blockchain aussi. L'intégrité vient de là, pas d'une chaîne de blocs. + +**Étiquette (tag)** — Un nom posé sur un état précis du dépôt (`v2026.08.21`). Signée, elle +devient un point de repère **vérifiable** : « c'est de cet état-là que je descends ». + +**Signature** — Le scellé posé avec une clé privée. Qui a la clé **publique** peut vérifier ; +qui n'a pas la privée ne peut pas contrefaire. Sans elle, un nom d'auteur est déclaratif. + +**`.git-allowed-signers`** — Le registre, **versionné**, des clés autorisées à signer cette +lignée. Retirer une ligne révoque pour la suite ; le passé signé reste vérifiable. + +**Témoin** — Une copie vivante et indépendante du *génome*. Réécrire l'histoire suppose de +convaincre tous les témoins : c'est la lignée elle-même qui protège la lignée. + +**Journal de transparence** — Un registre append-only, auditable par un tiers (Certificate +Transparency, Sigstore). La réponse mûre quand plusieurs organisations doivent constater les +mêmes faits sans se faire confiance — et l'alternative sobre à une blockchain. + +**Horodatage (RFC 3161)** — Prouver qu'un document **existait** à une date, par un tiers. diff --git a/wiki/_Sidebar.md b/wiki/_Sidebar.md index ebb4a62..64a376d 100644 --- a/wiki/_Sidebar.md +++ b/wiki/_Sidebar.md @@ -37,6 +37,7 @@ *Flotte & preuve* - [Multi-instance & fédération](Multi-instance-et-fédération) - [La preuve](La-preuve) +- [Filiation, signatures & témoins](Filiation-signatures-et-témoins) - [Vérifier le déployé](Vérifier-le-déployé) **Opérations**