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>
37 KiB
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(inventaireprincipal/) - 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 duMakefile, 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.yml → domaine_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 flux → docs/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 (generer→appliquer) |
❌ | 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.yml → make 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.
-
AFF-021 / AFF-020 — QUICKSTART renvoie à un modèle inexistant.
cp -r exemples/modeles/presence-web ../mon-instanceéchoue : seulsocleest 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 ». -
AFF-006 —
make verifieréchoue sur un dépôt propre.ansible-lintrapporte 33 échecs (surtoutname[play]sur lesite.ymlgé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). -
AFF-050 — Contradiction SSH doc vs code (sécurité).
CLAUDE.mdprescritPasswordAuthentication yespendant la construction ; le code etAGENTS.mdimposentno+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. -
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 publicsoclen'a pas d'inventairelab/(seulementproduction/). L'opérateur crée sa voûte au mauvais endroit → déchiffrement introuvable au déploiement. -
AFF-026 —
make inventaire-verifierexige le Vault sans le dire. La validation « à tout moment » appelleansible-inventory --listqui échoue (no vault secrets found) sansANSIBLE_VAULT_PASSWORD_FILE. Prérequis non rappelé au point d'usage → échec surprenant pour qui n'a pas exporté sa clé. -
AFF-002 — Promesse « exploitable sans IA » entamée par 1–5. 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 verifiercassé). C'est le méta-risque : la doc ne mène pas seule au succès. -
AFF-080 / AFF-081 / AFF-082 — Commandes
makepérimées dans la doc.make help(→aide) etmake syntax-template(→syntaxe-modele, cité 2×) n'existent pas. L'opérateur tape une commande qui renvoie une erreurmake. -
AFF-061 — SOLUTION.md décrit un flux SSH périmé.
--ask-pass --ask-become-passsuppose 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. -
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. -
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 publickeydès la construction (aligné surAGENTS.md, cf. AFF-037). Aucun correctif de code ; la doctrine SSH a été retirée deCLAUDE.md. - AFF-052 (🟡 → résolu) — Duplication CLAUDE.md ↔ AGENTS.md.
CLAUDE.mdré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 publicsocle(cp -r exemples/modeles/socle …) ; les modèles assemblés renvoyés au dépôt privéSet-OPS-modeles, cohérent avecexemples/modeles/README.md. - AFF-023 (❌ → résolu, A + correctif d'exemple) — Chemin de voûte corrigé
lab/→production/dansQUICKSTART.md,exemples/vault.exemple.ymletdocs/config-proxmox.md. Piège corrigé : le modèlesoclelivrait ses intrants enproduction/group_vars/all.yml(forme fichier) ; ajouterall/vault.yml(forme dossier) masque silencieusement le fichierall.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éeprincipal. Validé :ansible-inventory --hostcharge biendomaine_internedepuis la nouvelle disposition. - AFF-080/081/082 (❌ → résolu, A) — Commandes
makepérimées corrigées :make help→make(docs/config-proxmox.md) ;make syntax-template→make 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 queinventaire-verifier/verifierchargent l'inventaire complet et exigentANSIBLE_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-dossiersplaybooks/— seulsgroupes/,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 parmake 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 verifiercasse) → 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-098 — diffé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.ymlajouté à la liste des sources de secrets Proxmox (chargé via le filtreis search('vault'), autoritaire car en dernier).Makefile(cloner-vm) : la détection de voûte chiffrée cherche d'abordgroup_vars/all/vault.ymlpuisproxmox.vault.yml(déclenche--ask-vault-pass). Messages de tâche/rescousse/assert rendus génériques. Validé :--syntax-checkOK,ansible-lint0 échec sur le playbook, et test fonctionnel (mini-instance en clair) — le token est bien chargé depuisall/vault.ymlet l'hôte depuisproxmox.yml(assert vert).proxmox.vault.ymlreste 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.md→production/+ voûte unifiée. Plus aucune référenceinventories/lab/group_varsdans les fichiers suivis (horstmp/gitignoré et la section migration deconfig-proxmox.md, intentionnelle).
Phase 3 — Lot C « make verifier vert » — 2026-07-20
- AFF-006 (❌ → résolu, B) —
ansible-lintpasse de 33 échecs à 0 (profil montémin→production), doncmake lintrc=0. Trois causes traitées :- 30×
name[play]sur lesite.ymlgénéré →scripts/orchestrer.py(rendre_site) émet désormais- name: Couche <c> — groupe <g>avant chaqueimport_playbook;site.ymlrégénéré (make site). Logique d'orchestration inchangée (orchestrer verifierOK, 30 groupes, syntax-check OK). - 2×
risky-shell-pipe(playbooks/valider.yml) →set -o pipefail;+executable: /bin/bashsur les deux tâches shell à pipe. - 1×
name[template](playbooks/proxmox/supprimer_vm_debian.yml) → Jinja déplacé en fin dename(… (VMID {{ … }})). - Validé :
make lintrc=0 ;make verifierfranchit lint + test (4) +site-verifierflux-verifier+syntaxe(35 playbooks) — toutes vertes. Seuleinventaire-verifierexige la voûte de l'opérateur (ANSIBLE_VAULT_PASSWORD_FILE), prérequis documenté (AFF-026).
- 30×
- 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
makecitées existent ; jetons périmés (presence-webhors contexte,syntax-template,make help,--ask-pass, voûtelab/) soldés (les occurrences restantes ne sont que dansCHANGELOG.md/docs/audit, historiques). - AFF-099 (❌ → résolu, B) —
exemples/modeles/socle/plan/domaines.yml:interne→auto-heberge. Le modèle public valide désormais. - AFF-100 (❌ → résolu, B) —
instancier.pyetinventory_gui.py: le repli sanshosts.ymlvise maintenant le répertoire d'inventaire existant (→production/pour le socle) avant de retomber surprincipal. Instances existantes (avechosts.yml) inchangées. - Cohérence GUI/doc —
docs/intrants-communs.md:group_vars/all.yml→group_vars/all/10-intrants.yml(le GUI écrit déjà en forme dossier).QUICKSTART.mdétape 8 : exempleserveur_postgresql→serveur_powerdns(groupe présent dans le socle). - Preuve bout-en-bout (hors-ligne) : parcours QUICKSTART rejoué sur une copie du socle —
instancier generer→comparer→appliquer --forceécritproduction/hosts.yml, diff vide ensuite (idempotence), et les 4 validateurs verts (serveursréconcilié). Non-régression vérifiée sur l'instance réelleprincipal(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.py → docs/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,--checkréel, les très nombreux « prouvé sur VM réelles » duCHANGELOG.md) est marquée ⚪ ou 🟡 — non rejouable localement par conception. LeCHANGELOG.mdn'étant pas une surface publique listée, ses affirmations « prouvé » ne sont pas enregistrées ici ; à noter queAGENTS.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 lisenthosts.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.