Set-OPS-Public/docs/audit/affirmations.md
Daniel Allaire ea2d490e20 Protocole d'épreuve de l'opérateur indépendant (AFF-002)
AFF-002 (« Set-OPS s'exploite sans aucune IA ») était  par inspection : ses
écarts bloquants soldés et le parcours relu, mais jamais exécutée par un
opérateur qui n'est pas l'auteur. Aucune commande locale ne peut la prouver.

Ajoute le protocole de l'épreuve humaine : départ à froid depuis le modèle
public `socle`, sur la grappe Proxmox de l'opérateur. Règle du silence
(N0 journalise / N1 déblocage après 30 min, consigné comme défaut / N2 arrêt
sécurité), interdits (aucune IA, aucun dépôt privé, aucune lecture de
docs/audit/ qui divulguerait les pièges connus), critères R1→R6 fixés
d'avance, périmètre matériel, gabarit de rapport.

Le registre peut perdre : la redescente d'AFF-002 en 🟡 ou  selon le verdict
est explicitement prévue.

Le protocole ne nomme personne — il est réutilisable, et l'identité de
l'opérateur vit dans son rapport, sous réserve de consentement.

Validé : prouver.py --verifier → CONFORME 16/16. Aucun code touché.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 09:46:21 -04:00

37 KiB
Raw Blame History

Registre des affirmations — Set-OPS

Phase 1 de la mise en conformité prouvable. Ce document est un audit, sans aucun correctif de code ni de documentation. Chaque affirmation publique vérifiable du dépôt est tracée vers une commande de preuve reproductible, ou marquée comme invérifiable.

Règle d'arbitrage (rappel) : le dépôt ne doit jamais affirmer plus que ce qu'il prouve. Les traitements (corriger la doc / corriger le code / chantier séparé) relèvent de la Phase 3 — ils ne sont pas appliqués ici.

  • Date de l'audit : 2026-07-20
  • Instance montée pendant l'audit : instance -> ../OPS-Technolibre (inventaire principal/)
  • Outillage : ansible-core 2.18.1, ansible-lint 25.1.3, Python 3.13.3, node présent.
  • Périmètre : surfaces publiques uniquement — README.md, AGENTS.md, CLAUDE.md, QUICKSTART.md, SOLUTION.md, docs/, wiki/, aide du Makefile, libellés du GUI. Aucune VM / Proxmox / réseau touché (mission hors production).

Légende du statut : prouvée · 🟡 partielle · fausse · invérifiable localement.


1. README.md

ID Affirmation (source) Type Commande de preuve Statut Écart constaté
AFF-001 « Set-OPS est un moteur Ansible générique … à partir d'un plan déclaratif » (README:3) fonctionnelle python3 scripts/instancier.py generer && python3 scripts/instancier.py comparer « DIFF VIDE : le plan reproduit exactement l'inventaire ». Générateur opérationnel.
AFF-002 « Set-OPS s'exploite entièrement à la main — la doc, make et le GUI suffisent, sans aucune IA » (README:9 ; AGENTS principe 10) doctrinale Suivre QUICKSTART.md de bout en bout ; make verifier 🟡 Le principe tient au niveau outillage, mais deux trous cassent le parcours sans IA : make verifier échoue (AFF-006) et QUICKSTART étape 2 renvoie à un modèle absent (AFF-020/021). Un opérateur seul bute.
AFF-003 Registres = source unique de vérité : serveurs.yml, applications.yml, bases-donnees.yml, domaines.yml, nomenclature.yml (README:15) structurelle make inventaire-verifier (serveurs/applications/bases/domaines) Les 4 validateurs renvoient « Registre valide ». Fichiers présents dans instance/plan/.
AFF-004 « instance/inventories/production/hosts.yml est généré depuis le plan — ne pas l'éditer à la main » (README:34) procédurale python3 scripts/instancier.py comparer (diff-vide) Diff vide confirmé. (Nuance de chemin : l'instance courante utilise principal/ — voir AFF-023.)
AFF-005 « Afficher l'aide : make » (README:86) procédurale make (défaut = cible aide) .DEFAULT_GOAL := aide ; l'aide s'affiche.
AFF-006 « Valider le dépôt : make verifier » (README:91) fonctionnelle make verifier make lint (1re dépendance de verifier) échoue rc=2 : ansible-lint rapporte « Failed: 33 failure(s) » (name[play] sur le site.yml généré, risky-shell-pipe dans site.yml/valider.yml, name[template]). make verifier ne passe donc pas sur un dépôt propre.
AFF-007 « Inspecter … make hote-afficher HOTE=web-frontal-01 » (README:98) procédurale make hote-afficher HOTE=web-frontal-01 🟡 La cible existe et fonctionne, mais l'hôte d'exemple web-frontal-01 n'existe pas dans l'instance courante → l'exemple littéral échoue (exemple générique, pas garanti par instance).
AFF-008 « Chaque groupe opérationnel doit avoir son playbook homonyme dans playbooks/groupes/ » (README:120 ; AGENTS:316) structurelle python3 scripts/inventory_host.py --inventaire instance/inventories/principal/hosts.yml verifier-playbooks --dossier-playbooks playbooks/groupes rc=0. Les 30 groupes opérationnels ont leur playbook. Seuls hotes_actifs, hotes_planifies, modeles_vm (groupes méta/état) n'en ont pas — exclus par conception.
AFF-009 « Les dépendances causales entre groupes sont dans docs/dependances-groupes.yml » (README:128 ; AGENTS:413) structurelle python3 scripts/inventory_host.py … verifier-dependances … rc=0. Aucune entrée ne référence un rôle/groupe inexistant.
AFF-010 « Le runbook du DNS interne initial est dans docs/dns-interne.md » (README:130) structurelle test -f docs/dns-interne.md Fichier présent.
AFF-011 « La nomenclature … est dans docs/nomenclature-vm.md » (README:132) structurelle test -f docs/nomenclature-vm.md Fichier présent.
AFF-012 « Le catalogue des services … docs/catalogue-services.md » (README:126) structurelle test -f docs/catalogue-services.md Fichier présent.
AFF-013 « make creer-vm HOTE=… VMID/IP/VLAN/passerelle lus dans le plan » (README:138) fonctionnelle python3 scripts/inventory_host.py … parametres-proxmox --hote <h> 🟡 La dérivation existe (sous-commande parametres-proxmox), mais l'exécution réelle touche Proxmox → non testable localement (hors production). Mécanique de dérivation seule vérifiable.
AFF-014 « Les déploiements de groupes ciblent automatiquement les hôtes actifs seulement » (README:171) fonctionnelle lecture Makefile:261 : --limit '$(GROUPE):&$(GROUPE_HOTES_ACTIFS)' Intersection groupe ∩ hotes_actifs codée dans la cible appliquer.
AFF-015 « Set-OPS est un logiciel libre … AGPLv3 … texte intégral dans LICENSE » (README:177-186) structurelle test -f LICENSE LICENSE présent.

2. QUICKSTART.md

ID Affirmation (source) Type Commande de preuve Statut Écart constaté
AFF-020 « Les modèles sont dans exemples/modeles/ … Choisis : socle, presence-web, forge, identite, observabilite, integral » (QUICKSTART:25-26) structurelle ls exemples/modeles/ Le dossier public ne contient que socle (+ README.md). Les 5 autres modèles sont dans un dépôt privé Set-OPS-modeles (correctement expliqué dans exemples/modeles/README.md, mais pas dans QUICKSTART).
AFF-021 « cp -r exemples/modeles/presence-web ../mon-instance » (QUICKSTART:29) procédurale exécuter la commande La commande échoue : exemples/modeles/presence-web n'existe pas. C'est la commande centrale de l'étape 2 ; un opérateur suivant QUICKSTART à la lettre est bloqué immédiatement. Seule valeur valide : socle.
AFF-022 « instance/inventories/production/group_vars/all.ymldomaine_interne » (QUICKSTART:36) structurelle test -f exemples/modeles/socle/inventories/production/group_vars/all.yml Le modèle socle fournit bien ce fichier sous production/.
AFF-023 « Tous tes secrets … instance/inventories/lab/group_vars/all/vault.yml » (QUICKSTART:48-49) procédurale ls exemples/modeles/socle/inventories/ Le modèle socle n'a pas d'inventaire lab/ (uniquement production/). Le chemin de voûte annoncé n'existe pas dans le modèle public ; incohérent avec AFF-022 (production/).
AFF-024 « make instancier (diff) puis make instancier-appliquer FORCE=1 — 1re génération » (QUICKSTART:68-70) fonctionnelle make instancier ; cible instancier-appliquer (Makefile:582) Cibles présentes ; FORCE mappé sur --force. Diff-vide prouve le mécanisme (AFF-001).
AFF-025 Étape 5 : make preparer-modele / verifier-modele / nettoyer-modele CONFIRMER=true (QUICKSTART:59-62) procédurale cibles Makefile:632-643 🟡 Cibles présentes et gardes vérifiées ; l'exécution réelle exige une VM Debian 13 + Proxmox → hors production, non testable ici.
AFF-026 « Valider à tout moment : make inventaire-verifier / make verifier » (QUICKSTART:98-101) fonctionnelle make inventaire-verifier ; make verifier 🟡 make verifier échoue (AFF-006). make inventaire-verifier appelle ansible-inventory --list qui exige le mot de passe Vault (ERROR! Attempting to decrypt but no vault secrets found sans ANSIBLE_VAULT_PASSWORD_FILE) — prérequis non rappelé à cet endroit.

3. AGENTS.md

ID Affirmation (source) Type Commande de preuve Statut Écart constaté
AFF-030 « RÈGLE D'OR : …/production/hosts.yml est un artefact GÉNÉRÉ » (AGENTS:43) procédurale python3 scripts/instancier.py comparer Diff vide : l'inventaire est reproductible depuis le plan.
AFF-031 « make instancier-appliquer refuse si le diff n'est pas vide (FORCE=1 sinon) » (AGENTS:47) fonctionnelle lecture scripts/instancier.py appliquer + Makefile:582-583 appliquer accepte --force (mappé FORCE) ; garde diff cohérente avec le comparateur.
AFF-032 « VMID / IP / VLAN / passerelle sont dérivés de la fonction via la nomenclature » (AGENTS:49) fonctionnelle python3 scripts/serveurs.py verifier (réconcilie dérivation ↔ inventaire) « Registre des serveurs valide et réconcilié avec l'inventaire. » Dérivation confirmée.
AFF-033 « garde-fous : … node --check du JS du GUI (scripts/verifier_gui.py, dans make inventaire-verifier) » (AGENTS:50) fonctionnelle python3 scripts/verifier_gui.py « JS du GUI : syntaxe valide (node --check). »
AFF-034 « Chaque rôle qui utilise notify doit contenir son handler dans le rôle » (AGENTS:182) structurelle script de recoupement notify↔handlers sur tous les rôles « OK : tout notify pointe vers un handler existant dans le même rôle. »
AFF-035 « Tout notify doit pointer vers un handler existant » (AGENTS:193) structurelle idem AFF-034 Aucun notify orphelin.
AFF-036 « Playbooks … testables avec --check autant que possible » (AGENTS:214, 427) fonctionnelle ansible-playbook … --check sur cibles vivantes Non testable hors flotte réelle (mission hors production). Recensement des rôles non-check reporté (nécessite des hôtes).
AFF-037 État SSH attendu : PasswordAuthentication no, AuthenticationMethods publickey (AGENTS:538-542) fonctionnelle lecture roles/ssh_baseline/defaults + templates/10-setops.conf.j2 Défauts = no/no/yes ; le template code AuthenticationMethods publickey. Le code suit AGENTS.md. (Contredit CLAUDE.md — voir AFF-050.)
AFF-038 « Ne pas maintenir en parallèle playbooks/socle/ ou playbooks/durcissement/ » (AGENTS:278) structurelle ls playbooks/ Ces dossiers n'existent pas ; socle/durcissement = groupes serveur_debian/serveur_durci.
AFF-039 « Les playbooks peuvent être classés par domaine : groupes/ maintenance/ monitoring/ networking/ proxmox/ modeles_vm/ web/ database/ identity/ backup/ applications/ » (AGENTS:257-270) structurelle find playbooks -maxdepth 1 -type d 🟡 Seuls groupes/, maintenance/, modeles_vm/, proxmox/ existent. Formulé au conditionnel (« peuvent ») → aspirationnel, pas une fausse affirmation, mais liste plus large que la réalité.
AFF-040 Section « Comportement attendu de Codex » (AGENTS:650) doctrinale lecture 🟡 La section ne nomme que Codex alors qu'elle vaut pour tout agent (Claude inclus). Correctif de titrage prévu en Phase 2 (item 3).

4. CLAUDE.md

ID Affirmation (source) Type Commande de preuve Statut Écart constaté
AFF-050 « Pendant la construction du template : PasswordAuthentication yes » (CLAUDE.md § SSH) fonctionnelle roles/ssh_baseline/defaults/main.yml Le code déploie PasswordAuthentication no dès la construction (ssh_baseline_password_authentication: "no", template AuthenticationMethods publickey). CLAUDE.md contredit et le code et AGENTS.md (qui fait autorité). Cause racine : duplication de doctrine. Cible Phase 2 (item 1).
AFF-051 « Claude Code doit lire et respecter AGENTS.md avant toute modification ; en cas de contradiction, suivre AGENTS.md » (CLAUDE.md § Instruction principale) doctrinale Cohérent avec AGENTS.md ; pas de commande de preuve (déclaration de gouvernance).
AFF-052 CLAUDE.md redéclare la doctrine de template, SSH, pare-feu, cloud-init, handlers, actions destructives (dupliquée d'AGENTS.md) structurelle diff conceptuel CLAUDE.md ↔ AGENTS.md 🟡 Large duplication → source des dérives (AFF-050). Réduction à un pointeur mince prévue Phase 2 (item 2).

5. SOLUTION.md

ID Affirmation (source) Type Commande de preuve Statut Écart constaté
AFF-060 « On garde une seule structure : inventories/ playbooks/ roles/ docs/ » (SOLUTION:11-18) structurelle ls racine 🟡 Réel : aussi scripts/, filter_plugins/, exemples/, wiki/, instance/. Description obsolète (antérieure au plan/GUI).
AFF-061 Commande template : ansible-playbook … debian13_proxmox_preparer.yml --ask-pass --ask-become-pass (SOLUTION:24-25) procédurale comparaison avec la doctrine SSH clé-only 🟡 --ask-pass (mot de passe SSH) contredit l'accès par clé dès le départ d'AGENTS.md (AFF-037). SOLUTION.md décrit un flux périmé (mot de passe SSH) ; le flux réel = clé via cloud-init.
AFF-062 « Le pare-feu nftables est installé et préparé, mais pas activé par défaut dans le template » (SOLUTION:60 ; AGENTS:559 ; CLAUDE.md) fonctionnelle grep enabled roles/nftables_baseline/defaults/main.yml nftables_baseline_enabled: false. preparer-modele inclut le rôle et affiche « nftables est installé mais désactivé par défaut ».

6. Aide du Makefile (make)

ID Affirmation (source) Type Commande de preuve Statut Écart constaté
AFF-070 « make site-verifier valide la cohérence couches/graphe » (Makefile aide:133) fonctionnelle python3 scripts/orchestrer.py verifier « Orchestration cohérente : 30 groupes classés, aucun cycle, aucune arête en arrière. »
AFF-071 « make fluxdocs/registre-flux.md + instance/flux-genere/*.nft » (Makefile aide:146) fonctionnelle python3 scripts/resoudre_flux.py verifier ; en-tête de docs/registre-flux.md « Flux cohérents : 29 rôles, 63 flux ». Le registre porte l'en-tête « GÉNÉRÉ par scripts/resoudre_flux.py ».
AFF-072 « make deployer-tout — déploiement orchestré de la flotte ; garde CONFIRMER » (Makefile aide:138) fonctionnelle lecture Makefile:352-357 🟡 Garde CONFIRMER=true vérifiée (refuse sinon, rc=2). Déploiement réel hors production → non exécuté.
AFF-073 « make wiki-publier … refuse sans WIKI_REMOTE » (Makefile aide:151) fonctionnelle lecture Makefile:320-326 Garde présente : refus + message d'usage si WIKI_REMOTE vide.
AFF-074 « make devis-reseau — dérivé des nomenclatures » (Makefile:309) fonctionnelle python3 scripts/devis_reseau.py 🟡 Dérive des instances fédérées ../*/plan/nomenclature.yml (schéma ip-miroir) ; sortie dépend du voisinage de dépôts → vérifiable seulement dans un contexte fédéré.
AFF-075 Cibles dépréciées make hote-planifier / hote-ajouter / hote-groupes renvoient vers le plan (README:118 ; Makefile:237) procédurale make hote-planifier Stub présent : message « Cible dépréciée … » + exit 2.

7. docs/ — runbooks et cohérence des commandes

ID Affirmation (source) Type Commande de preuve Statut Écart constaté
AFF-080 « make help — liste des cibles » (docs/config-proxmox.md:114) procédurale grep -E '^help:' Makefile Aucune cible help. La cible réelle est aide (défaut). Commande citée inexistante.
AFF-081 « make syntax-template » (docs/modeles_vm/debian13-proxmox.md:77) procédurale grep syntax-template Makefile Aucune cible syntax-template. Réel : syntaxe-modele. Nom périmé.
AFF-082 « make syntax-template » (docs/MISE-A-JOUR-CODEX-CLAUDE.md:146) procédurale idem Même nom périmé, second emplacement.
AFF-083 Tous les docs cités par README/QUICKSTART/AGENTS existent (plan-et-generation, positionnement, bindings-conception, flux-conception, couches-deploiement.yml, registre-flux.md, carte-set-ops, runbooks-exploitation, vm-lifecycle, procedure-template-…, dns-interne, nomenclature-vm, config-proxmox, catalogue-services, dimensionnement-ressources, exemples/vault.exemple.yml, exemples/instance.exemple.yml) structurelle test -f sur chaque chemin 17/17 présents.
AFF-084 « docs/dependances-groupes.yml — chaque groupe existant y figure, aucune entrée ne référence un rôle supprimé » (AGENTS:345,413) structurelle verifier-dependances (AFF-009) Validé ; graphe sans cycle, tri topologique réussi (via orchestrer verifier).
AFF-097 Chemins d'inventaire lab/ codés en dur pour la config/voûte Proxmox et le template, alors que make config/cloner-vm résolvent lab > principal > production (modèle socle = production/) procédurale grep -rn 'inventories/lab/group_vars' docs playbooks ; scripts/config_proxmox.py:31 🟡 Découvert en Phase 3 (lot A). Reste lab/ codé en dur dans docs/vm-lifecycle.md:171, docs/procedure-template-debian13-proxmox.md:741,747, docs/modeles_vm/debian13-proxmox.md:89, playbooks/proxmox/README.md:31,43,49,50, playbooks/proxmox/cloner_vm_debian.yml:45 (message). Non bloquant (l'outillage résout), mais trompeur pour le socle. Différé au lot « voûte Proxmox » (couplé à AFF-098).
AFF-099 Le modèle public socle livre un plan/domaines.yml invalide : exemple.internal en autorite: interne, rejeté par le validateur (auto-heberge/delegue/primaire-cache attendus) fonctionnelle SETOPS_INSTANCE=exemples/modeles/socle python3 scripts/domaines.py verifier Découvert Phase 5. Un opérateur suivant QUICKSTART bute à la validation (étape 9 / make inventaire-verifier). interne = valeur périmée (déjà corrigée ailleurs en auto-heberge, cf. CHANGELOG 2026-07-07).
AFF-100 instancier.py/inventory_gui.py résolvent principal > production mais retombent sur principal quand aucun hosts.yml n'existe encore ; le socle est en production/ → 1ʳᵉ génération dans principal/, à côté des group_vars restés en production/ (split-brain) fonctionnelle parcours QUICKSTART hors-ligne sur une copie du socle (genererappliquer) Découvert Phase 5. config_proxmox.py détecte le répertoire existant (→ production/) ; instancier/GUI non → incohérence. QUICKSTART étapes 6-9 cassées pour le socle.
AFF-098 Contradiction fonctionnelle voûte Proxmox : make config écrit le token dans la voûte unifiée all/vault.yml (et config-proxmox.md dit de supprimer proxmox.vault.yml), mais le clonage cloner_vm_debian.yml (lancé -i localhost,) ne charge le secret que depuis proxmox.vault.yml/proxmox.local.yml ou les variables d'env — jamais all/vault.yml fonctionnelle lecture playbooks/proxmox/cloner_vm_debian.yml:11-12,51-64 vs scripts/config_proxmox.py:35 Découvert en Phase 3 (lot B). Un opérateur qui suit la voûte unifiée met le token dans all/vault.ymlmake creer-vm échoue l'assert (proxmox_api_token_secret vide), sauf variables d'env ou proxmox.vault.yml conservé. Traitement B (code) : faire lire all/vault.yml par le clonage, ou faire écrire proxmox.vault.yml par make config. À arbitrer dans le lot « voûte Proxmox ».

8. wiki/

ID Affirmation (source) Type Commande de preuve Statut Écart constaté
AFF-090 Le wiki pédagogique fournit des unités d'apprentissage par service (wiki/*.md) publiables dans Forgejo structurelle ls wiki/*.md 16 pages de contenu (+ README.md + _Sidebar.md) ; 17 publiées par wiki-publier (README exclu).
AFF-091 Contenu conceptuel du wiki (OIDC, PKI, DNS, sauvegardes, idempotence, RBAC…) doctrinale Contenu pédagogique = affirmations conceptuelles, non rattachées à une preuve exécutable du dépôt. Hors périmètre de preuve automatisable.

9. GUI (libellés)

ID Affirmation (source) Type Commande de preuve Statut Écart constaté
AFF-095 « La vue Inventaire est en lecture seule ; vues éditables Serveurs, Applications, Domaines ; vues lecture seule Réseau, Flux, Couches » (README:41 ; AGENTS:48 ; CHANGELOG) fonctionnelle démarrage headless de scripts/inventory_gui.py + inspection des routes/onglets 🟡 Les routes backend et l'import des validateurs sont présents dans scripts/inventory_gui.py ; le rendu des onglets et le caractère « lecture seule » ne sont pas vérifiés sans lancer le serveur + un navigateur (non fait — pas de commande de preuve headless au registre).
AFF-096 « GUI 100 % française » (CHANGELOG 2026-07-03) structurelle inspection des chaînes du GUI Vérifiable seulement par revue exhaustive des libellés rendus ; non automatisé ici.

Décompte

Recompte exact par ID (numérotation à trous AFF-001 → AFF-096, 54 affirmations).

Statut Nombre
prouvée 30
🟡 partielle 13
fausse 8
invérifiable localement 3
Total 54

Détail :

  • (30) : AFF-001, 003, 004, 005, 008, 009, 010, 011, 012, 014, 015, 022, 024, 030, 031, 032, 033, 034, 035, 037, 038, 051, 062, 070, 071, 073, 075, 083, 084, 090.
  • 🟡 (13) : AFF-002, 007, 013, 025, 026, 039, 040, 052, 060, 061, 072, 074, 095.
  • (8) : AFF-006, 020, 021, 023, 050, 080, 081, 082.
  • (3) : AFF-036, 091, 096.

La Phase 4 (make prouver) rattachera chaque à sa section de preuve et figera le compte.


Les dix écarts les plus graves

Classés par risque pour un opérateur qui suit la doc à la lettre, sans IA.

  1. AFF-021 / AFF-020 — QUICKSTART renvoie à un modèle inexistant. cp -r exemples/modeles/presence-web ../mon-instance échoue : seul socle est public. L'opérateur est bloqué dès l'étape 2 du guide de démarrage. Risque maximal : c'est la toute première action concrète du parcours « zéro → écosystème ».

  2. AFF-006 — make verifier échoue sur un dépôt propre. ansible-lint rapporte 33 échecs (surtout name[play] sur le site.yml généré par l'outil lui-même, + risky-shell-pipe). La commande de validation vantée par README et QUICKSTART ne passe pas → l'opérateur croit son dépôt cassé, ou apprend à ignorer l'échec (perte de confiance dans le harnais).

  3. AFF-050 — Contradiction SSH doc vs code (sécurité). CLAUDE.md prescrit PasswordAuthentication yes pendant la construction ; le code et AGENTS.md imposent no + AuthenticationMethods publickey. Un opérateur qui suit CLAUDE.md attend un accès mot de passe qui n'existe pas — et la doctrine de sécurité affichée est contradictoire.

  4. AFF-023 — Chemin de voûte faux dans QUICKSTART. L'étape 4 place les secrets dans inventories/lab/group_vars/all/vault.yml, mais le modèle public socle n'a pas d'inventaire lab/ (seulement production/). L'opérateur crée sa voûte au mauvais endroit → déchiffrement introuvable au déploiement.

  5. AFF-026 — make inventaire-verifier exige le Vault sans le dire. La validation « à tout moment » appelle ansible-inventory --list qui échoue (no vault secrets found) sans ANSIBLE_VAULT_PASSWORD_FILE. Prérequis non rappelé au point d'usage → échec surprenant pour qui n'a pas exporté sa clé.

  6. AFF-002 — Promesse « exploitable sans IA » entamée par 15. Le principe fondateur (AGENTS principe 10) est partiellement démenti par les faits : le parcours documenté comporte au moins deux ruptures dures (modèle absent, make verifier cassé). C'est le méta-risque : la doc ne mène pas seule au succès.

  7. AFF-080 / AFF-081 / AFF-082 — Commandes make périmées dans la doc. make help (→ aide) et make syntax-template (→ syntaxe-modele, cité 2×) n'existent pas. L'opérateur tape une commande qui renvoie une erreur make.

  8. AFF-061 — SOLUTION.md décrit un flux SSH périmé. --ask-pass --ask-become-pass suppose un accès par mot de passe contraire au modèle clé-only réel. Suivre SOLUTION.md pour construire le template mène à un flux qui ne correspond plus au code.

  9. AFF-060 — SOLUTION.md décrit une arborescence obsolète. « Une seule structure : inventories/playbooks/roles/docs/ » ignore scripts/, instance/, filter_plugins/, wiki/, exemples/ — désoriente un nouveau lecteur sur l'endroit où vivent le plan et le GUI.

  10. AFF-052 / AFF-040 — Doctrine dupliquée et titrage « Codex ». La duplication CLAUDE.md ↔ AGENTS.md est la cause racine de la contradiction n°3 ; la section « Comportement attendu de Codex » sous-entend à tort qu'elle ne vise pas Claude. Risque de gouvernance : deux sources d'autorité qui divergent avec le temps.


Journal des traitements

Le tableau ci-dessus est le snapshot d'audit Phase 1 (2026-07-20) et n'est pas réécrit. Les traitements appliqués ensuite sont consignés ici, datés et traçables.

Phase 2 — 2026-07-20 (3 incohérences internes pré-cadrées)

  • AFF-050 ( → résolu) — Doctrine SSH contradictoire. Vérifié que le code applique déjà PasswordAuthentication no + AuthenticationMethods publickey dès la construction (aligné sur AGENTS.md, cf. AFF-037). Aucun correctif de code ; la doctrine SSH a été retirée de CLAUDE.md.
  • AFF-052 (🟡 → résolu) — Duplication CLAUDE.md ↔ AGENTS.md. CLAUDE.md réduit à un pointeur mince (autorité d'AGENTS.md + 5 règles absolues) ; cause racine d'AFF-050 supprimée.
  • AFF-040 (🟡 → résolu) — Section « Comportement attendu de Codex » renommée « …des agents IA » dans AGENTS.md, avec mention explicite qu'elle vaut pour tout agent.

Reste ouvert après Phase 2 : les 5 restants (AFF-006, 020, 021, 023, 080/081/082) et les 🟡 relèvent de la Phase 3 (arbitrage).

Phase 3 — Lot A « doc de démarrage » — 2026-07-20

  • AFF-020/021 ( → résolu, A)QUICKSTART.md étape 2 : ne propose plus que le modèle public socle (cp -r exemples/modeles/socle …) ; les modèles assemblés renvoyés au dépôt privé Set-OPS-modeles, cohérent avec exemples/modeles/README.md.
  • AFF-023 ( → résolu, A + correctif d'exemple) — Chemin de voûte corrigé lab/production/ dans QUICKSTART.md, exemples/vault.exemple.yml et docs/config-proxmox.md. Piège corrigé : le modèle socle livrait ses intrants en production/group_vars/all.yml (forme fichier) ; ajouter all/vault.yml (forme dossier) masque silencieusement le fichier all.yml (vérifié empiriquement : seul le dossier est chargé). Le modèle a été converti en forme dossier (all/10-intrants.yml), alignée sur l'instance prouvée principal. Validé : ansible-inventory --host charge bien domaine_interne depuis la nouvelle disposition.
  • AFF-080/081/082 ( → résolu, A) — Commandes make périmées corrigées : make helpmake (docs/config-proxmox.md) ; make syntax-templatemake syntaxe-modele (docs/modeles_vm/debian13-proxmox.md, docs/MISE-A-JOUR-CODEX-CLAUDE.md).
  • AFF-097 (🟡, découvert)lab/ codé en dur restant dans les docs template/clone (étapes 5+). Consigné ci-dessus ; non traité dans ce lot (lot séparé à prévoir).

Phase 3 — Lot B « doc (prose) » — 2026-07-20

  • AFF-026 (🟡 → résolu, A)QUICKSTART.md § « Valider à tout moment » : note ajoutée que inventaire-verifier/verifier chargent l'inventaire complet et exigent ANSIBLE_VAULT_PASSWORD_FILE (étape 4), sinon « no vault secrets found ».
  • AFF-039 (🟡 → résolu, A)AGENTS.md : note ajoutée sous la liste des sous-dossiers playbooks/ — seuls groupes/, maintenance/, modeles_vm/, proxmox/ sont peuplés ; les autres sont prospectifs.
  • AFF-060/061 (🟡 → résolu, A)SOLUTION.md : bannière « document historique » ajoutée (supplanté par README/QUICKSTART/make) ; arborescence complétée (scripts/, wiki/, instance/…) ; commande de construction --ask-pass (mot de passe) remplacée par make preparer-modele (accès par clé, aligné AGENTS.md).
  • AFF-002 (🟡) — « exploitable sans IA » : pas de reformulation (c'est un engagement fondateur légitime, pas une sur-affirmation). Son seul écart résiduel est AFF-006 (make verifier casse) → bascule une fois AFF-006 traité (lot C, B). Aucune édition.
  • AFF-007 (🟡)web-frontal-01 : assumé comme nom d'exemple/placeholder (usage cohérent dans tout le README) ; aucune édition.
  • AFF-097 / AFF-098différés au lot « voûte Proxmox » : AFF-098 (contradiction fonctionnelle all/vault.yml ↔ clonage, traitement B) est couplé à AFF-097 (mêmes fichiers) ; les traiter ensemble évite un double passage.

Phase 3 — Lot « voûte Proxmox » — 2026-07-20

  • AFF-098 ( → résolu, B, option a) — Le clonage lit désormais la voûte unifiée. playbooks/proxmox/cloner_vm_debian.yml : all/vault.yml ajouté à la liste des sources de secrets Proxmox (chargé via le filtre is search('vault'), autoritaire car en dernier). Makefile (cloner-vm) : la détection de voûte chiffrée cherche d'abord group_vars/all/vault.yml puis proxmox.vault.yml (déclenche --ask-vault-pass). Messages de tâche/rescousse/assert rendus génériques. Validé : --syntax-check OK, ansible-lint 0 échec sur le playbook, et test fonctionnel (mini-instance en clair) — le token est bien chargé depuis all/vault.yml et l'hôte depuis proxmox.yml (assert vert). proxmox.vault.yml reste accepté en compatibilité.
  • AFF-097 (🟡 → résolu, A)lab/ codé en dur retiré des docs Proxmox/template : playbooks/proxmox/README.md, docs/procedure-template-debian13-proxmox.md, docs/vm-lifecycle.md, docs/modeles_vm/debian13-proxmox.mdproduction/ + voûte unifiée. Plus aucune référence inventories/lab/group_vars dans les fichiers suivis (hors tmp/ gitignoré et la section migration de config-proxmox.md, intentionnelle).

Phase 3 — Lot C « make verifier vert » — 2026-07-20

  • AFF-006 ( → résolu, B)ansible-lint passe de 33 échecs à 0 (profil monté minproduction), donc make lint rc=0. Trois causes traitées :
    • 30× name[play] sur le site.yml généréscripts/orchestrer.py (rendre_site) émet désormais - name: Couche <c> — groupe <g> avant chaque import_playbook ; site.yml régénéré (make site). Logique d'orchestration inchangée (orchestrer verifier OK, 30 groupes, syntax-check OK).
    • 2× risky-shell-pipe (playbooks/valider.yml) → set -o pipefail; + executable: /bin/bash sur les deux tâches shell à pipe.
    • 1× name[template] (playbooks/proxmox/supprimer_vm_debian.yml) → Jinja déplacé en fin de name (… (VMID {{ … }})).
    • Validé : make lint rc=0 ; make verifier franchit lint + test (4) + site-verifier
      • flux-verifier + syntaxe (35 playbooks) — toutes vertes. Seule inventaire-verifier exige la voûte de l'opérateur (ANSIBLE_VAULT_PASSWORD_FILE), prérequis documenté (AFF-026).
  • AFF-002 (🟡) — « exploitable sans IA » : ses deux écarts résiduels sont soldés (parcours QUICKSTART, lot A ; make verifier/lint, ce lot). Bascule , sous le prérequis Vault désormais rappelé (AFF-026).

Phase 5 — Boucle documentaire — 2026-07-20

Relecture de cohérence bout-en-bout (README, QUICKSTART, docs, wiki) contre le code final, au regard du critère du principe 10 : un opérateur sans IA exécute chaque procédure sans commande morte, chemin faux ni étape manquante.

  • Sweep commandes/chemins : toutes les commandes make citées existent ; jetons périmés (presence-web hors contexte, syntax-template, make help, --ask-pass, voûte lab/) soldés (les occurrences restantes ne sont que dans CHANGELOG.md/docs/audit, historiques).
  • AFF-099 ( → résolu, B)exemples/modeles/socle/plan/domaines.yml : interneauto-heberge. Le modèle public valide désormais.
  • AFF-100 ( → résolu, B)instancier.py et inventory_gui.py : le repli sans hosts.yml vise maintenant le répertoire d'inventaire existant (→ production/ pour le socle) avant de retomber sur principal. Instances existantes (avec hosts.yml) inchangées.
  • Cohérence GUI/docdocs/intrants-communs.md : group_vars/all.ymlgroup_vars/all/10-intrants.yml (le GUI écrit déjà en forme dossier). QUICKSTART.md étape 8 : exemple serveur_postgresqlserveur_powerdns (groupe présent dans le socle).
  • Preuve bout-en-bout (hors-ligne) : parcours QUICKSTART rejoué sur une copie du socle — instancier generercomparerappliquer --force écrit production/hosts.yml, diff vide ensuite (idempotence), et les 4 validateurs verts (serveurs réconcilié). Non-régression vérifiée sur l'instance réelle principal (diff vide, cible inchangée).

Couverture par make prouver (Phase 4)

Chaque affirmation est soit rejouée par une preuve de make prouver (scripts/prouver.pydocs/audit/preuve-<date>.md), soit structurelle/doctrinale (vérifiée à l'audit, rien d'exécutable à rejouer en boucle).

Affirmation Preuve make prouver
AFF-001, 004, 030, 031, 032 P03 (diff-vide)
AFF-003 P06 (validateurs de registres)
AFF-008 P04 (groupes ↔ playbooks)
AFF-009, 084 P05 (dépendances)
AFF-010, 011, 012 P12 (existence des runbooks)
AFF-015, 022, 037, 038, 062 P13 (invariants structurels)
AFF-033 P07 (GUI node --check)
AFF-034, 035 P10 (handlers ↔ notify)
AFF-070 P08 (orchestration)
AFF-071 P09 (flux)
AFF-083 P11 (syntaxe) + P12
AFF-097 P14 (pas de lab/ codé en dur)
AFF-002, 006 P01 (lint) — + parcours démarrage corrigé
AFF-030 (inventaire complet) P15 (voûte requise ; sauté sinon)

Structurelles/doctrinales, hors harnais récurrent (vérifiées à l'audit) : AFF-005 (make=aide), AFF-014 (ciblage groupe:&hotes_actifs), AFF-024 (instancier-appliquer, couvert indirectement par P03), AFF-051 (autorité d'AGENTS.md), AFF-073/075 (gardes make wiki-publier/hote-planifier), AFF-090 (comptage wiki).

Déclarations d'intention ( — assumées, jamais présentées comme prouvées) : AFF-036 (--check réel), AFF-091 (contenu wiki), AFF-096 (GUI 100 % français), AFF-007 (placeholder web-frontal-01). Reprises dans la section dédiée de chaque preuve-<date>.md.

Limites de cet audit

  • AFF-002 est par inspection, pas par démonstration. Ses écarts bloquants ont été soldés (parcours QUICKSTART, make verifier) et le parcours relu de bout en bout, mais aucun opérateur indépendant ne l'a jamais exécuté. signifie ici « plus aucun défaut connu », pas « démontré ». C'est la seule affirmation du registre qu'aucune commande locale ne peut prouver : elle exige un humain qui n'est pas l'auteur. Épreuve prévue : protocole-operateur-independant.md — son rapport fera foi, y compris s'il fait redescendre AFF-002 en 🟡 ou .
  • Hors production : toute affirmation nécessitant une VM, Proxmox, le réseau ou la flotte vivante (make valider, make deployer*, make creer-vm, --check réel, les très nombreux « prouvé sur VM réelles » du CHANGELOG.md) est marquée ou 🟡non rejouable localement par conception. Le CHANGELOG.md n'étant pas une surface publique listée, ses affirmations « prouvé » ne sont pas enregistrées ici ; à noter que AGENTS.md (« pas encore exécuté contre des VM réelles », « ne jamais présenter un rôle non déployé comme en production ») encadre correctement cette réserve.
  • GUI : pas de preuve headless au registre (AFF-095/096 en 🟡/).
  • Vault : l'instance courante chiffre group_vars/all/vault.yml ; les commandes qui chargent l'inventaire complet via Ansible exigent le mot de passe Vault, non fourni pendant l'audit (les validateurs Python lisent hosts.yml/le plan directement et n'en ont pas besoin — d'où leur usage ici).
  • Numérotation à trous : les ID sautent (AFF-001…096) pour laisser de la place par surface ; ce n'est pas une omission.