Validation et génération de schéma
Deux choses ont leur place ici : vérifier une configuration sans rien démarrer, et émettre le JSON Schema qui décrit toutes les configurations. Les deux sont des commandes, et les deux fonctionnent sur toutes les distributions — le binaire, Docker, Homebrew.
sovrium validate <fichier>
La barrière avant déploiement.
sovrium validate app.yamlAffiche Valid configuration: <nom> et sort en 0, ou les erreurs et sort en 1. Tout échec vaut 1 : contrôler un pipeline tient donc en une ligne.
sovrium validate app.yaml || exit 1Une validation, trois commandes. validate, start et build lisent votre configuration via le même processus : les mêmes raccourcis d'écriture sont acceptés, et les mêmes règles inter-champs sont appliquées. Une configuration que sovrium validate accepte est une configuration que sovrium start démarre. Comportement complet — codes de sortie, format des erreurs, attribution des $ref — sur Valider une configuration.
--json — le même verdict, pour un programme
sovrium validate app.yaml --json rend le verdict sous forme d'un unique document JSON plutôt qu'en prose. Il s'adresse aux lecteurs qu'un terminal ne sert pas : un éditeur qui souligne la ligne fautive, une étape d'intégration continue, un superviseur, ou l'IA qui vient d'écrire la configuration et doit savoir si sa modification a été prise.
sovrium validate app.yaml --jsonDeux garanties rendent la sortie sûre à analyser :
- La sortie standard ne porte que le document JSON. Tout ce qui relève de la conversation reste sur la sortie d'erreur — l'avis
Using app.yaml (auto-discovered), et la ligneError:d'un fichier tout simplement illisible. Rien ne vient jamais s'intercaler dans le document. - Le code de sortie est inchangé.
0pour une configuration valide,1pour une configuration invalide.--jsonchange la forme du rapport, jamais le verdict : un script qui enveloppe déjàsovrium validatecontinue de fonctionner quand vous ajoutez l'option.
Une configuration valide, porteuse d'une clé supplantée qui mérite d'être signalée sans faire échouer quoi que ce soit :
{
"valid": true,
"files": ["/srv/factures/app.yaml"],
"findings": [],
"notices": [
"Superseded: design.typeScale.families.sans.weights — declared and validated, but no renderer reads any of them. …"
]
}Une configuration invalide — un composant text portant tag, alors que la propriété s'écrit element, dans une configuration répartie sur plusieurs fichiers $ref :
{
"valid": false,
"files": ["/srv/factures/app.yaml", "/srv/factures/config/pages.yaml"],
"findings": [
{
"path": "pages[0].components[0]",
"message": "Unknown property 'tag' on component type 'text'",
"accepted": [
"type",
"children",
"props",
"content",
"interactions",
"responsive",
"visibility",
"i18n",
"session",
"element",
"required"
],
"sourceFile": "pages.yaml",
"severity": "error"
}
],
"notices": []
}Le document
| Champ | Signification |
|---|---|
valid |
Le verdict — celui-là même que porte le code de sortie. |
files |
Tous les fichiers couverts par le verdict : la racine, plus chaque partiel $ref ou module importé qu'elle a entraîné. C'est ainsi qu'un surveillant apprend quels fichiers suivre sans résoudre le graphe lui-même. |
findings |
Une entrée par refus ; liste vide quand la configuration est valide. |
notices |
Les messages non bloquants — clés de design supplantées, et champs dont l'identifiant est laissé implicite. Un avis ne rend jamais valid faux et ne change jamais le code de sortie : une barrière de déploiement ne peut donc pas échouer sur une configuration qui fonctionne. Voir Avis. |
Un constat
| Champ | Signification |
|---|---|
path |
Chemin pointé et indexé depuis la racine de la configuration, par exemple pages[0].components[0]. Vide pour un refus qui porte sur la configuration entière plutôt que sur une position précise. |
message |
Ce qui ne va pas, en une ligne, en nommant la valeur fautive. |
accepted |
Ce qu'il est permis d'écrire à la place. Lu dans le schéma plutôt que dans une liste tenue à la main, et jamais tronqué — pour un type de composant inconnu, c'est la totalité des types légaux. Absent quand le refus n'a aucune liste d'alternatives à proposer. |
sourceFile |
Le partiel $ref où vit l'erreur, présent uniquement pour une configuration répartie. Là, path désigne une position dans le document résolu, qui n'existe dans aucun fichier ; ce champ nomme le fichier à ouvrir. |
severity |
"error" sur chaque constat. Tout refus rapporté par validate est bloquant ; le champ existe pour qu'un lecteur n'ait jamais à le déduire du code de sortie de l'exécution entière. |
Deux points à intégrer. Une configuration tout simplement illisible — fichier absent, extension non prise en charge — est refusée avant qu'un verdict existe : la commande affiche une ligne Error: sur la sortie d'erreur et sort en 1, sans aucun document JSON. Et le décodeur s'arrête au premier refus structurel : une configuration qui comporte plusieurs propriétés non reconnues les signale une exécution à la fois.
La même forme de constat est publiée par le fichier d'état d'une instance en cours et poussée vers le navigateur quand une sauvegarde --watch est refusée — un seul vocabulaire, que vous ayez posé la question ou qu'on vous ait donné la réponse.
Avis
Un avis signale ce qui mérite d'être dit sans mériter un échec. La configuration est valide et part en production : valid reste true et le code de sortie reste 0, si bien qu'aucune barrière de déploiement ne bute dessus. En mode texte, les avis s'affichent sur la sortie d'erreur avant le verdict, ce qui garde la sortie standard analysable ; sous --json, ils arrivent dans le tableau notices.
field-id-implicit
L'identifiant d'un champ est facultatif. Omettez-le et le décodeur le déduit de la position du champ dans la liste — l'identité existe donc que vous l'ayez écrite ou non, et vous ne la voyez pas.
$ sovrium validate app.yaml
Notice:
field-id-implicit: table "contacts" — "full_name", "email" declare no id, so the id is the field's position in the list. Inserting a field above one of them shifts every id after it, and the migration diff reads that as a rename. Give each field an explicit id — keep the ones it has today, and give new fields the next unused number.
Valid configuration: crmLe moteur de migration compare les tables par identifiant : insérer un champ ailleurs qu'à la fin décale donc tous les identifiants qui le suivent. Trois champs sans identifiant se décodent en 1, 2, 3 ; ajoutez-en un en tête et ils se décodent en 2, 3, 4 tandis que le nouveau venu prend 1 — chaque champ porte désormais l'identifiant qui appartenait à son voisin, et la comparaison y lit une cascade de renommages entre des champs que personne n'a renommés.
Personne n'écrit cela à la main. Une IA à qui l'on demande d'« ajouter un champ avant status » l'écrit à chaque fois : c'est pourquoi l'avis existe aujourd'hui, et non à l'époque où les identifiants sont apparus.
Le remède consiste à écrire les identifiants :
tables:
- name: contacts
fields:
- id: 1
name: full_name
type: single-line-text
- id: 2
name: email
type: emailConservez à chaque champ l'identifiant qu'il possède aujourd'hui — sa position actuelle, en comptant à partir de 1 — et donnez à tout nouveau champ le premier numéro inutilisé, où que vous le placiez dans la liste. L'identifiant porte l'identité ; c'est toujours la position dans le tableau qui donne l'ordre, et les deux ont le droit de diverger. C'est tout l'intérêt : un champ inséré en tête avec le premier identifiant libre change l'ordre et ne renomme rien.
Un avis par table, et non par champ : une table écrite avant que les identifiants ne soient explicites les omet tous, et quarante lignes identiques apprennent à leur lecteur à ignorer les avis. La table est nommée parce qu'« un champ quelque part n'a pas d'identifiant » n'est pas actionnable dans une configuration répartie sur une douzaine de fichiers $ref, et un champ sans name est désigné par la position qui est son identifiant. Le jeton field-id-implicit figure dans le message pour qu'il soit repérable avec un grep.
Valider depuis une configuration
Pour vérifier une configuration depuis une application en cours d'exécution — un webhook qui reçoit une configuration soumise, un audit planifié d'une configuration stockée — utilisez l'action d'automatisation sovrium:validateConfig. Elle exécute le décodeur qu'exécute sovrium validate, sans effet de bord et sans démarrage.
automations:
- name: check-submitted-config
trigger:
type: webhook
method: POST
actions:
- name: check
type: sovrium
operator: validateConfig
props:
config: '{{trigger.data.config}}'
format: autoL'étape expose {{steps.check.valid}} et {{steps.check.errors}}. config accepte l'objet de configuration ou une chaîne sérialisée ; format ne concerne que la chaîne — json (par défaut), yaml, ou auto pour essayer JSON puis YAML.
Deux comportements méritent d'être connus avant de bâtir dessus :
- Une configuration invalide est une étape réussie, rapportée comme
{ valid: false, errors }. La validation est un verdict, pas une panne : l'exécution continue et l'étape suivante décide quoi en faire. - Le candidat est lu tel quel. Un
{{...}}ou un$env.Xprésent à l'intérieur de la configuration soumise n'est pas résolu — il est validé comme le texte littéral qu'il est. C'est ce qui rend le verdict fiable : ce qui est vérifié est exactement ce que vous avez transmis, pas une copie réécrite.
sovrium schema
Affiche le JSON Schema (Draft 2020-12) de la configuration d'application — le même document que servent les URLs du schéma hébergé.
sovrium schema
sovrium schema --output app.schema.jsonLa commande ne prend aucun argument au-delà du chemin de sortie et ne lit rien de l'environnement : le schéma est dérivé d'AppSchema lui-même, sa sortie ne dépend donc que de la version de Sovrium. On peut ainsi le régénérer en CI et comparer les différences — un changement dans le fichier est un changement du schéma, jamais de la machine.
Un usage courant consiste à figer le schéma à côté de la configuration, pour que les éditeurs valident face à la version exacte que vous déployez :
# À exécuter après chaque montée de version
sovrium schema --output app.schema.json# app.yaml
# yaml-language-server: $schema=./app.schema.json
name: my-appsovrium design-system
Exportez le système de design de l'application — le bloc design et tout ce dont il hérite — sous forme de brief destiné à un agent, ou de document de jetons standard.
# Le brief pour agent, sur la sortie standard
sovrium design-system app.yaml
# Versionné à côté de la configuration, référencé depuis vos consignes d'agent
sovrium design-system app.yaml --output DESIGN.md
# Le document de jetons, pour l'outillage
sovrium design-system app.yaml --format json --output tokens.jsonLe markdown est le format par défaut, parce que le lecteur par défaut est un modèle. --format json produit un document W3C Design Tokens (DTCG) 2025.10, la couche propre à Sovrium — principes, voix, rôles de couleur, guidage des composants — étant transportée dans $extensions.
Comme sovrium schema, la commande s'exécute hors ligne : sans serveur, sans base de données, sans session. À la différence de celle-ci, sa sortie dépend de votre configuration : elle a donc sa place dans un hook de pré-commit ou une étape d'intégration continue qui régénère le brief versionné quand le design change.
Deux choses qu'elle refuse plutôt que de les contourner :
- Un
--formatinconnu. Un repli silencieux sur le markdown permettrait à une étape d'intégration continue qui demande autre chose de se terminer avec le code0après avoir écrit le mauvais fichier. - Une configuration qui échoue à la validation. Exporter depuis une configuration non validée produit un système de design décrivant une application incapable de démarrer — remis à un agent, c'est un brief pour construire contre quelque chose que personne n'exécute.
Le même contenu est disponible à l'exécution via GET /api/admin/design-system.md et GET /api/admin/design-system.json, tous deux réservés aux administrateurs. Voir Système de design.
Pages associées
- Aperçu du CLI — l'ensemble des commandes.
- Valider une configuration — le vérificateur du CLI en détail.
- Commandes de cycle de vie — le fichier d'état publié par une instance en cours, dans le même vocabulaire de constats.
- Schéma JSON — les URLs du schéma hébergé.
- Configuration de l'éditeur — y brancher VS Code ou JetBrains.
- Système de design — le bloc
designet le contenu de l'export.
Dernière mise à jour 24 septembre 2026
Cette documentation a été rédigée avec de l'IA : des erreurs ou du contenu obsolète sont donc possibles. Sovrium est en bêta. Les contributions et corrections sont les bienvenues.