Set-OPS-Public/docs/audit
Daniel Allaire 7e190e0a57 Trois preuves qui regardent au-dela d'une seule instance + champ liens/websocket au GUI
Le harnais ne verifiait qu'UNE instance et le seul modele socle. Tout ce qui vit
a cote du moteur echappait au controle. Trois preuves ferment ces angles morts :

- P17 (scripts/modeles.py) : TOUS les modeles valident, pas seulement socle.
  SETOPS_MODELES=../Set-OPS-Modeles inclut les modeles assembles prives. A trouve
  6 modeles invalides sur 7 (corriges dans Set-OPS-Modeles).
- P18 (scripts/voute.py) : le gabarit vault.yml.example couvre EXACTEMENT les secrets
  que le plan exige (bases + roles actifs + group_vars). Ne dechiffre jamais la vraie
  voute : compare des noms.
- P19 (scripts/couverture_gui.py) : tout champ present dans un plan reel est editable
  par le GUI. A trouve applications.websocket (comble). Nomenclature toleree (trou connu).

GUI :
- champ « Liens (bindings) » dans l'inspecteur d'application : role -> cible en listes
  deroulantes, les roles proposes = ceux que le role porteur accepte (meta/liens.yml).
  Comble un manque : les bindings ne se declaraient qu'en editant le YAML a la main.
- champ « WebSocket » (Collabora).
- CHAMPS_ECRITS_PAR_GUI : declaration de ce que le GUI sait ecrire, verifiee par P19.

Garde-fou de fond : valider_applications refuse une application posee sur un hote non
declare (l'hote fantome exact qu'integral portait). Cable partout + POST du GUI.

liens_acceptes()/catalogue_liens() dans inventory_rules : source unique partagee par le
validateur, le GUI et instancier.py (dont la copie locale est retiree).

Valide : make verifier rc=0, CONFORME 19/19, ansible-lint 0 echec, 7 modeles valident,
DIFF VIDE, node --check du GUI OK. Piece justificative : docs/audit/preuve-2026-07-22.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 21:32:42 -04:00
..
affirmations.md Protocole d'épreuve de l'opérateur indépendant (AFF-002) 2026-07-21 09:46:21 -04:00
preuve-2026-07-20.md Preuve complète (16/16) + détail P16 lisible 2026-07-20 20:47:36 -04:00
preuve-2026-07-22.md Trois preuves qui regardent au-dela d'une seule instance + champ liens/websocket au GUI 2026-07-22 21:32:42 -04:00
protocole-operateur-independant.md Protocole d'épreuve de l'opérateur indépendant (AFF-002) 2026-07-21 09:46:21 -04:00
README.md Trois preuves qui regardent au-dela d'une seule instance + champ liens/websocket au GUI 2026-07-22 21:32:42 -04:00

Audit de conformité — mode d'emploi

Ce dossier contient le dispositif qui garde Set-OPS honnête : il ne doit jamais affirmer plus que ce qu'il prouve.

Les pièces

Fichier Rôle
affirmations.md Le registre : chaque affirmation publique du dépôt (README, AGENTS, QUICKSTART, docs, wiki, aide make, GUI) tracée vers une commande de preuve et un statut (/🟡//), plus le journal des traitements (ce qui a été corrigé, quand, comment).
scripts/prouver.py Le harnais : un orchestrateur mince qui rejoue les preuves automatisables du registre en appelant l'outillage existant (les mêmes scripts que make verifier). Il ne réimplémente aucune validation.
preuve-AAAA-MM-JJ.md La pièce justificative : le rapport horodaté produit par make prouver. Rejouable et présentable (audit, certification, revue).
protocole-operateur-independant.md L'épreuve humaine : le protocole qui met AFF-002 (« exploitable sans IA ») à l'épreuve d'un sysadmin qui n'est pas l'auteur. Aucune commande locale ne peut prouver cette affirmation ; produit un rapport operateur-independant-AAAA-MM-JJ.md.

Produire une preuve

make prouver

Cela exécute chaque preuve et écrit docs/audit/preuve-<date>.md. La commande sort en erreur (rc≠0) si une preuve automatisable échoue — utilisable en garde-fou (CI locale, pré-commit). Une preuve SAUTÉE () n'est pas un échec.

Prérequis Vault

La preuve P15 (inventaire Ansible complet, ansible-inventory --list) déchiffre le group_vars de l'instance. Sans ANSIBLE_VAULT_PASSWORD_FILE, elle est automatiquement sautée () avec la mention du prérequis — le reste du harnais reste vert, car les validateurs Python lisent le plan et l'inventaire directement, sans secret. Pour l'inclure :

export ANSIBLE_VAULT_PASSWORD_FILE=~/.config/setops-vault-pass
make prouver

Ce que couvre make prouver

# Preuve Ce qu'elle établit
P01 Lint (ansible-lint) 0 violation, profil production.
P02 Tests unitaires inventory_host — cas nominal + refus.
P03 Diff-vide du plan l'inventaire est généré depuis le plan (diff vide).
P04 Groupes ↔ playbooks chaque groupe opérationnel a son playbook homonyme.
P05 Dépendances de groupes graphe cohérent, aucune entrée orpheline.
P06 Validateurs de registres serveurs / applications / bases / domaines valides.
P07 GUI node --check du JS du GUI.
P08 Orchestration couches + graphe : aucun cycle, aucune arête en arrière.
P09 Flux réseau schéma + matrice d'audit cohérents.
P10 Handlers ↔ notify tout notify pointe vers un handler du même rôle.
P11 Syntaxe --syntax-check de tous les playbooks (via make syntaxe).
P12 Runbooks cités les fichiers docs/ référencés existent.
P13 Invariants structurels LICENSE, socle en forme dossier, pas de couches parallèles, SSH clé-only, nftables désactivé par défaut.
P14 Chemins d'inventaire aucun instance/inventories/lab/group_vars codé en dur.
P15 Modèle public socle ses registres (domaines/serveurs/applications/bases) valident.
P16 Inventaire Ansible (voûte) ansible-inventory --list — sauté sans mot de passe Vault.
P17 Tous les modèles d'instance chaque modèle découvert valide (pas seulement socle). SETOPS_MODELES=../Set-OPS-Modeles inclut les modèles assemblés privés.
P18 Gabarit de voûte complet vault.yml.example couvre exactement les secrets que le plan exige (rôles actifs + bases + group_vars).
P19 GUI couvre le plan tout champ présent dans un plan réel est éditable par le GUI (nomenclature tolérée : trou connu).

P17, P18, P19 ferment les angles morts du harnais : il ne vérifiait qu'une instance et le seul modèle socle. P17 aurait attrapé l'hôte fantôme d'integral ; P18, les neuf secrets absents du gabarit Chezlepro ; P19, les champs liens / websocket que le GUI ne savait pas écrire. Chacune a une CLI dédiée (scripts/modeles.py, voute.py, couverture_gui.py) utilisable seule.

Le rapport relie chaque preuve aux affirmations qu'elle couvre (colonne « Affirmations »), et liste à part les déclarations d'intention ( invérifiables localement : AFF-036, 091, 096, 007) — assumées comme intentions, jamais présentées comme prouvées.

Ajouter une preuve

  1. Ajouter (ou corriger) l'affirmation dans affirmations.md avec sa commande de preuve.
  2. Ajouter une entrée à la liste PREUVES de scripts/prouver.py : soit une ou plusieurs commandes (cmds, toutes doivent renvoyer 0), soit une fonction native func renvoyant (ok, détail) pour un invariant simple. Renseigner refs avec les ID d'affirmations.
  3. Ne pas réimplémenter de logique de validation : appeler l'outillage existant (scripts/*.py, ansible-lint, cibles make). Le harnais orchestre, il ne valide pas.

Rapport avec make verifier

make verifier inclut désormais les preuves : il enchaîne ses vérifications au fil de l'eau (lint, tests, cohérence, syntaxe — arrêt au premier échec) puis termine par python3 scripts/prouver.py --verifier — les preuves du registre sans écrire de rapport (pour ne pas écraser la pièce justificative committée). Ainsi, make verifier échoue si une preuve échoue.

make prouver (sans --verifier) reste le mode pièce justificative : il exécute tout, horodate et écrit docs/audit/preuve-<date>.md. Les deux réutilisent le même outillage. (Quelques vérifications se recouvrent entre les deux étapes — coût assumé : la sortie détaillée de verifier est conservée, et prouver ajoute les preuves manquantes.)