---
name: validateur-config
description: Vérifie qu'un fichier de configuration JSON/TOML respecte un schéma déclaré (types, champs requis, valeurs autorisées) — stdlib pur, lecture seule, zéro appel réseau.
theme: outillage-developpement
langages_cibles: python
---
# validateur-config
## Objectif
Valider un fichier de configuration (`.toml` ou `.json`) contre un schéma
déclaré dans un fichier JSON séparé : types attendus, champs requis, plages
numériques (min/max), listes de valeurs autorisées, motifs regex pour les
chaînes, validation récursive de sections imbriquées. **Toujours en lecture
seule** — ce skill ne modifie jamais le fichier de configuration qu'il
valide, il ne fait que produire un rapport de violations.
## Pourquoi Python (et pas un autre langage) ?
- **`tomllib` est natif de la stdlib Python depuis la version 3.11** — c'est
l'argument central de ce choix : un parseur TOML conforme sans AUCUNE
dépendance tierce. En Rust, la seule voie pour parser du TOML est la crate
`toml` (dépendance externe) ou un parseur maison risqué et non conforme à
la spécification complète — ni l'une ni l'autre n'est compatible avec la
règle "zéro dépendance, souveraineté totale" de ce projet. Python est donc
concrètement le SEUL langage stdlib-pur disponible ici pour cette tâche
précise, pas un choix par défaut.
- Le module `json` de la stdlib couvre l'autre format cible sans effort
supplémentaire.
- La validation récursive de schéma (sections imbriquées) se prête bien aux
structures de données natives Python (`dict`/`list`) sans bibliothèque de
validation tierce (type `jsonschema`, explicitement évitée).
## Garanties de sécurité
- **Lecture seule stricte** — aucune écriture n'est jamais effectuée sur le
fichier de configuration validé, uniquement sur le rapport de sortie
(`--out`), un fichier distinct choisi par l'appelant.
- **Contenu de config = donnée inerte.** `tomllib.load`/`json.load`
construisent une structure de données sans jamais exécuter de code — un
champ de configuration contenant du texte qui ressemble à une instruction
n'est jamais interprété comme telle, seulement comparé à un schéma.
- **Schéma vérifié avant toute validation** (`charger_schema` →
`_valider_noeud_schema`, récursif) : type inconnu, champ `type` absent, ou
motif regex invalide dans le schéma lui-même lèvent une erreur nommée
(`ErreurSchemaInvalide`) — jamais supposé correct sans vérification.
- **Piège Python explicitement neutralisé** : `bool` est une sous-classe de
`int` en Python — sans précaution, une valeur `true`/`false` serait
acceptée à tort par un champ de type `entier`. `_type_python_correspond`
exclut explicitement ce cas (`isinstance(v, int) and not isinstance(v, bool)`),
vérifié par un test dédié.
- **Aucune donnée transmise à l'extérieur** — 100% local, 0 appel réseau.
## Gestion d'erreur exhaustive
`erreurs.py` distingue explicitement deux natures d'échec bien différentes :
une **violation de schéma** (champ manquant, type incorrect...) est le
résultat NORMAL et attendu de la validation — collectée dans une liste,
jamais une exception. Les exceptions couvrent uniquement les cas où la
validation elle-même ne peut pas avoir lieu : `ErreurCibleIntrouvable`,
`ErreurCibleNonAccessible`, `ErreurFormatFichierNonSupporte` (extension hors
`.toml`/`.json`), `ErreurParsingConfig` (fichier syntaxiquement invalide —
distinct d'une violation de schéma), `ErreurSchemaIntrouvable`,
`ErreurSchemaInvalide`, `ErreurEcritureRapport`. `main()` traite chaque
catégorie dans une branche `except` dédiée avec un code de sortie distinct,
plus un dernier recours nommé (`ErreurInterne`, code 99) — jamais un
`except Exception: pass` silencieux. La validation elle-même est exhaustive
au sens fonctionnel : TOUTES les violations d'un fichier sont collectées et
rapportées en un seul passage, jamais un arrêt à la première trouvée.
## Mode d'emploi
**Format du schéma** (fichier JSON séparé, exemple minimal) :
```json
{
"type": "objet",
"champs": {
"listen_port": {"type": "entier", "requis": true, "min": 1, "max": 65535},
"mode": {"type": "chaine", "requis": true, "valeurs_autorisees": ["prod", "dev"]}
}
}
```
Types reconnus : `chaine`, `entier`, `flottant`, `booleen`, `liste`, `objet`
(récursif via `champs`), `tout` (aucune vérification). Options par champ :
`requis`, `valeurs_autorisees`, `min`/`max` (numériques), `pattern` (regex,
chaînes), `elements_type` (type des éléments d'une liste). Option d'objet :
`interdire_champs_inconnus` (signale tout champ absent du schéma).
**Valider un fichier :**
```bash
python3 validateur_config.py /chemin/vers/config.toml --schema mon_schema.json
```
**Rapport JSON écrit sur disque :**
```bash
python3 validateur_config.py /chemin/vers/config.json --schema mon_schema.json \
--format json --out rapports/mon-rapport.json
```
**Résultat réel obtenu lors de la validation de ce skill** : schéma réel
écrit pour une section de configuration (`[web_server]`, 6 champs :
port d'écoute, URL, secret partagé optionnel, 3 intervalles/timeouts en
secondes) d'un fichier `default.toml` réel d'environ 1300 lignes appartenant
à un autre projet du même environnement, validé strictement en LECTURE SEULE
(aucune écriture, aucune modification) — **0 violation** (schéma cohérent
avec la configuration réelle). Détection positive vérifiée séparément en
dégradant volontairement une copie du schéma (borne `min` resserrée à tort +
champ requis inexistant ajouté) : **2 violations exhaustivement détectées**
en un seul passage, confirmant que le validateur ne se contente pas de
valider silencieusement n'importe quoi.
**Options communes :**
- `--format` : `md` (défaut, lisible) | `json` (structuré)
- `--out` : chemin de sortie (défaut : stdout)
**Prérequis :** Python **≥ 3.11** (contrairement aux 3 autres skills de ce
projet, `tomllib` n'existe pas avant cette version — seule contrainte
version stricte de la bibliothèque).
## Limites connues (honnêteté de l'outil, pas de sur-promesse)
- Schéma custom minimal, pas une implémentation de la spécification
JSON Schema standard (`$ref`, `oneOf`, `allOf`...) — délibéré, une
bibliothèque de validation JSON Schema tierce (`jsonschema`) violerait la
règle zéro dépendance ; ce schéma maison couvre les besoins réels
rencontrés (types, bornes, énumérations, imbrication) sans cette
complexité.
- Pas de support des tableaux de tables TOML (`[[section]]`) au niveau du
schéma — un champ de type `liste` est validé élément par élément avec un
seul `elements_type` scalaire, pas une validation de schéma objet complet
par élément de liste.
- `tomllib` (stdlib) est **strictement en lecture** — cohérent avec la
garantie "lecture seule" de ce skill, mais signifie qu'aucune fonctionnalité
d'écriture/réécriture de TOML n'est ni prévue ni possible avec ce module.