diff --git a/REATTESTATION.fr.md b/REATTESTATION.fr.md new file mode 100644 index 0000000..5bf8e9d --- /dev/null +++ b/REATTESTATION.fr.md @@ -0,0 +1,104 @@ +# Réattester les labs de ce catalogue + +> Page écrite le 2026-10-19, avec des valeurs **mesurées sur le disque** et non +> recopiées. Les chiffres vieillissent : le `validation-labs.json` reste la +> source de vérité pour les verdicts. + +## Pourquoi cette page existe + +Le 2026-10-19, une campagne de réattestation a inscrit **douze faux ROUGE** dans +un catalogue avant d'être arrêtée, et s'est bloquée vingt-trois minutes dans un +autre. Aucune des deux causes ne tenait aux labs : un `.venv` dont les shebangs +désignaient l'ancien nom du dépôt après son renommage, et un outil en ligne de +commande qui attendait un réseau que le bac à sable ne lui donnait pas. + +Dans les deux cas, le validateur **avait l'air de mesurer les labs alors qu'il +mesurait sa propre panne**, et il l'écrivait dans le relevé. Un faux ROUGE coûte +plus cher qu'une absence de verdict : il envoie chercher un défaut dans un lab +qui n'en a pas. + +## Ce que ce catalogue exige + +- **dsoxlab 0.5.4 ou plus** dans le `PATH`. C'est la version du moteur qui sera inscrite dans le relevé, et le relevé la déclare pour TOUS les labs : voir la section sur le rejeu partiel. +- Les outils épinglés par `mise.toml`, donc la commande se lance par `mise exec --`. Sans lui, un outil absent ou d'une autre version fait échouer des labs sans rapport avec leur sujet. +- **`.vault-pass` à la racine** : 1 fichier(s) de solution de ce catalogue sont chiffrés par ansible-vault, et le cycle les pose déchiffrés. Le secret n'est jamais commité. Ici : présent. +- Aucun secret : ce catalogue déclare `solutions: plaintext` dans son `meta.yml`, avec sa raison. Ses solutions servent de fixtures au lab suivant, donc elles doivent rester lisibles. + +## La commande + +```bash +mise exec -- uv run scripts/valider-labs.py +``` + +Un seul lab, pour éprouver le harnais avant d'engager les 1 : + +```bash +mise exec -- uv run scripts/valider-labs.py --lab +``` + +**Commencer par un seul lab n'est pas une précaution de principe.** C'est ce qui +distingue un défaut d'environnement d'un défaut de lab : si le lab unitaire +passe, le harnais est sain ; s'il échoue comme les autres, c'est le harnais +qu'il faut réparer. + +## L'état actuel + +Relevé actuel : 1 VALIDE. Moteur déclaré : **aucune version de moteur enregistrée**. Dates des verdicts : 2026-10-19. Durée cumulée du dernier cycle mesuré : **0 minutes** pour 1 labs, hors provisionnement et destruction d'infrastructure. + +## Les quatre pièges qui produisent un faux verdict + +**1. Un `.venv` au shebang mort.** Si le dépôt a été renommé, les scripts de +`.venv/bin/` pointent encore l'ancien chemin et ne s'exécutent plus. Le +symptôme est un échec identique sur chaque lab, souvent sur le déchiffrement de +la solution. Vérification et correctif : + +```bash +head -1 .venv/bin/ansible-vault # le chemin doit exister +uv venv --clear && uv sync # le recréer +``` + +**2. `uv run --no-sync` sur un venv vide.** Le drapeau suppose un environnement +déjà peuplé. Sur un clone neuf, il rend un `ModuleNotFoundError` avant d'avoir +regardé un seul lab. Lancer sans `--no-sync` la première fois. + +**3. Un outil qui attend un réseau que le bac à sable ne donne pas.** Mesuré +sur un `octl --version` resté bloqué vingt-trois minutes : seule la commande de +premier niveau est exemptée, un sous-processus ne l'est pas. Si une campagne +n'avance plus, regarder ses processus enfants avant de soupçonner un lab : + +```bash +ps -eo pid,etimes,cmd | grep -E 'python.*valider[-]labs' +ps --ppid -o pid,etimes,cmd +``` + +**4. Un rejeu partiel rend l'en-tête du relevé faux.** La version du moteur est +enregistrée **une fois pour tout le fichier**, alors que les verdicts sont +individuels. Rejouer un seul lab réécrit donc cet en-tête, et le relevé affirme +que tous ses labs ont été attestés avec la version courante. Soit on rejoue tout, +soit on restaure le relevé : + +```bash +git checkout -- validation-labs.json +``` + +## Ce que le relevé ne dit pas + +Il ne dit pas **avec quelle version du moteur chaque lab** a été attesté, mais +seulement celle de la dernière campagne. C'est un manque connu, et il se voit +dès qu'une campagne est partielle. + +**Ici, le relevé ne porte même pas de version de moteur** : il n'a aucune clé racine, là où six catalogues de la collection enregistrent `genere_le`, `dsoxlab` et la version de chaque outil employé. Tant que c'est le cas, rien ne permet de dire si ses verdicts valent pour le moteur courant. + +## Pourquoi les verdicts de ce catalogue sont périmés + +Aucun commit de la campagne du 2026-10-17 n'a touché les tests de ce catalogue. Ses verdicts ne sont périmés que par ce qui l'a modifié depuis, et un changement de descripteur ou de documentation ne justifie pas à lui seul un rejeu. + +## Le format du relevé décide de ce que le site peut en dire + +Le relevé de ce catalogue est au format **plat**, et le site **n'y lit aucune version de moteur**, et affiche donc une attestation sans dire avec quoi elle a été obtenue. + +Le générateur du site ne lit `genere_le` et `dsoxlab` **que si la clé `labs` +est un dictionnaire** : un relevé dont les clés de premier niveau sont +directement les identifiants de labs part dans une autre branche, qui rend une +date et un outil vides. Corriger le champ sans corriger le format ne servirait +donc à rien, et c'est pour ça que les deux sont dits ensemble ici. diff --git a/REATTESTATION.md b/REATTESTATION.md new file mode 100644 index 0000000..694ed03 --- /dev/null +++ b/REATTESTATION.md @@ -0,0 +1,102 @@ +# Re-attesting this catalogue's labs + +> Written on 2026-10-19, with values **measured on disk** rather than copied. +> Numbers age: `validation-labs.json` remains the source of truth for verdicts. + +## Why this page exists + +On 2026-10-19, a re-attestation campaign recorded **twelve false REDs** in one +catalogue before being stopped, and hung for twenty-three minutes in another. +Neither cause had anything to do with the labs: a `.venv` whose shebangs still +named the repository's former path after a rename, and a command-line tool +waiting on network access the sandbox does not grant. + +In both cases the validator **looked like it was measuring the labs when it was +measuring its own breakdown**, and it wrote that into the record. A false RED +costs more than a missing verdict: it sends people hunting for a defect in a lab +that has none. + +## What this catalogue requires + +- **dsoxlab 0.5.4 or newer** on the `PATH`. That is the engine version the record will carry, and the record states it for ALL labs: see the section on partial replays. +- The tools pinned by `mise.toml`, so run the command through `mise exec --`. Without it, a missing or differently versioned tool fails labs for reasons unrelated to their subject. +- **`.vault-pass` at the root**: 1 solution file(s) in this catalogue are ansible-vault encrypted, and the cycle lays them decrypted. The secret is never committed. Here: present. +- No secret: this catalogue declares `solutions: plaintext` in its `meta.yml`, with its reason. Its solutions act as fixtures for the next lab, so they must stay readable. + +## The command + +```bash +mise exec -- uv run scripts/valider-labs.py +``` + +A single lab, to exercise the harness before committing to all 1: + +```bash +mise exec -- uv run scripts/valider-labs.py --lab +``` + +**Starting with one lab is not a matter of principle.** It is what separates an +environment defect from a lab defect: if the single lab passes, the harness is +sound; if it fails like the others, the harness is what needs fixing. + +## Current state + +Current record: 1 VALIDE. Declared engine: **no engine version recorded**. Verdict dates: 2026-10-19. Cumulative duration of the last measured cycle: **0 minutes** for 1 labs, excluding infrastructure provisioning and teardown. + +## The four traps that produce a false verdict + +**1. A `.venv` with dead shebangs.** If the repository was renamed, the scripts +in `.venv/bin/` still point at the old path and no longer execute. The symptom +is an identical failure on every lab, often on decrypting the solution. Check +and fix: + +```bash +head -1 .venv/bin/ansible-vault # the path must exist +uv venv --clear && uv sync # recreate it +``` + +**2. `uv run --no-sync` on an empty venv.** The flag assumes an already +populated environment. On a fresh clone it raises `ModuleNotFoundError` before +looking at a single lab. Run without `--no-sync` the first time. + +**3. A tool waiting on network access the sandbox does not grant.** Measured on +an `octl --version` that hung for twenty-three minutes: only the top-level +command is exempt, a subprocess is not. If a campaign stops progressing, look at +its child processes before suspecting a lab: + +```bash +ps -eo pid,etimes,cmd | grep -E 'python.*valider[-]labs' +ps --ppid -o pid,etimes,cmd +``` + +**4. A partial replay makes the record's header false.** The engine version is +recorded **once for the whole file**, while verdicts are per lab. Replaying a +single lab therefore rewrites that header, and the record then claims all its +labs were attested with the current version. Either replay everything, or +restore the record: + +```bash +git checkout -- validation-labs.json +``` + +## What the record does not say + +It does not say **which engine version attested each lab**, only the one from +the last campaign. This is a known gap, and it shows as soon as a campaign is +partial. + +**Here the record carries no engine version at all**: it has no root key, where six catalogues in the collection record `genere_le`, `dsoxlab` and each tool's version. Until that changes, nothing tells whether its verdicts hold for the current engine. + +## Why this catalogue's verdicts are stale + +No commit from the 2026-10-17 campaign touched this catalogue's tests. Its verdicts are stale only through what changed since, and a descriptor or documentation change does not by itself justify a replay. + +## The record's shape decides what the site can say about it + +This catalogue's record uses the **plat** shape, and the site **reads no engine version from it**, and therefore shows an attestation without saying what produced it. + +The site's generator reads `genere_le` and `dsoxlab` **only when the `labs` +key is a dictionary**: a record whose top-level keys are lab identifiers falls +into another branch, which returns an empty date and tool. Fixing the field +without fixing the shape would therefore change nothing, which is why both are +stated together here. diff --git a/validation-labs.json b/validation-labs.json index 7425f85..e8eb1a9 100644 --- a/validation-labs.json +++ b/validation-labs.json @@ -4,7 +4,10 @@ "apres": { "echecs": [], "passed": 5, + "recorded": true, "score": 100, + "skipped": 0, + "status": "passed", "total": 5 }, "avant": { @@ -16,14 +19,17 @@ "test_un_test_casse_fait_echouer_le_pipeline" ], "passed": 0, + "recorded": true, "score": 0, + "skipped": 0, + "status": "failed", "total": 5 }, - "date": "2026-10-03", - "duree_s": 15, + "date": "2026-10-19", + "duree_s": 13, "ecarts": [], "etapes": [ - "état photographié, 26 conteneur(s) Docker présents", + "état photographié, 6 conteneur(s) Docker présents", "avant le travail : 0/5", "après la solution : 5/5", "après clean et run : 0/5", @@ -41,7 +47,10 @@ "test_un_test_casse_fait_echouer_le_pipeline" ], "passed": 0, + "recorded": true, "score": 0, + "skipped": 0, + "status": "failed", "total": 5 }, "verdict": "VALIDE"