Documentation / Qualité et gouvernance
Contrat de qualité
Les règles de qualité vivent dans un fichier versionné du dépôt, pas dans le prompt, et s’appliquent de la même façon aux personnes et aux agents.
Le contrat de qualité est le fichier .ai/contract.json de votre projet. Il définit le niveau de rigueur exigé par l’équipe : seuils de mesure, couverture, complexité, taille des changements, chemins protégés et dérogations.
Il est appliqué par le gate du moteur, les hooks Git, la CI et les agents. Le résultat ne dépend pas de qui écrit le code : une personne, Yuli, Claude Code, Codex, Kiro ou Antigravity.
Si le fichier n’existe pas ou n’est pas valide, Yuli utilise les valeurs par défaut (criticité Métier). Chaque champ est facultatif : un contrat partiel fonctionne donc aussi.
Où le modifier
Ouvrez le Centre de gouvernance (rail de droite → Plus d'outils, ou la palette de commandes avec Ouvrir le centre de gouvernance) et allez dans l’onglet Contrat.
Lorsque vous enregistrez avec Enregistrer et signer, Yuli consigne la modification avec votre git config user.name. Toutes les modifications sont visibles dans Historique du contrat.
Criticité
La criticité sélectionne un profil complet de seuils. Il existe quatre niveaux :
| Valeur dans le fichier | Libellé dans Yuli | Quand l’utiliser |
|---|---|---|
low |
Faible | Prototypes, outils internes, expérimentations. |
business |
Métier | Applications métier. C’est la valeur par défaut. |
regulated |
Réglementée | Systèmes soumis à audit ou à réglementation. |
safety |
Sécurité critique | Logiciels où une défaillance a des conséquences graves. |
Profils
| Seuil | Faible | Métier | Réglementée | Sécurité critique |
|---|---|---|---|---|
| Score d’acceptation | 80 | 90 | 92 | 95 |
| Tours de mesure | 2 | 3 | 4 | 5 |
| Couverture minimale | 50 % | 70 % | 80 % | 90 % |
| Complexité cognitive max. | 20 | 15 | 15 | 10 |
| Complexité cyclomatique max. | 15 | 10 | 10 | 8 |
| Mutation minimale | 0 % | 0 % | 60 % | 75 % |
| Fichiers par changement | 60 | 40 | 25 | 15 |
| Lignes par changement | 2000 | 1000 | 600 | 400 |
| Revue indépendante | Non | Non | Oui | Oui |
| Bloquer la triche sur les tests | Non | Oui | Oui | Oui |
| Application stricte | Non | Non | Oui | Oui |
Vous pouvez remplacer un seuil précis dans gates. Seul ce champ change ; le reste continue de provenir du profil. Bloquer la triche sur les tests et Application stricte dépendent uniquement de la criticité et ne peuvent pas être remplacés.
Le score d’acceptation et les tours du contrat remplacent les paramètres locaux de la phase de Mesure.
Structure du fichier
{
"schemaVersion": 1,
"criticality": "business",
"gates": { "minCoverage": 75, "maxCyclomatic": null },
"changeLimits": { "maxFiles": 40, "maxLines": 1000 },
"protectedPaths": ["db/migrations/**"],
"waivers": []
}
| Champ | Ce qu’il définit |
|---|---|
criticality |
low, business, regulated ou safety. |
gates |
acceptanceScore, maxMeasureRounds, minCoverage, maxCognitive, maxCyclomatic, requireIndependentReview, minMutationScore. null reprend la valeur du profil. |
changeLimits |
maxFiles et maxLines par changement. |
protectedPaths |
Globs supplémentaires, qui s’ajoutent à ceux protégés par défaut. |
waivers |
Dérogations avec date d’expiration. |
architecture |
Couches (layers avec name, paths, mayDependOn) et forbidCycles. |
slos |
Objectifs de service : latencyP95Ms, availability ou errorRate. |
licensePolicy |
Licences autorisées (allow) et interdites (deny), par identifiant SPDX ou par famille, comme strong-copyleft. |
reviewer |
Relecteur indépendant : requireOtherFamily, provider, model. |
dataClassification |
Motifs de données avec leur niveau : public, internal, confidential ou restricted. |
finops |
Budget mensuel par service et son responsable. |
Limites de changement
La taille d’un changement se mesure avec git diff --numstat. Les fichiers de verrouillage (package-lock.json, yarn.lock, Cargo.lock, go.sum et similaires) comptent comme fichiers, mais pas leurs lignes.
Dépasser la limite bloque en application stricte (Réglementée et Sécurité critique). Dans les autres profils, c’est un avertissement.
Chemins protégés
Un agent ne peut pas modifier ces fichiers, même si on le lui demande :
.ai/contract.json,.ai/quality.jsonet.ai/state/**.claude/settings.jsonet.claude/settings.local.json.githooks/**.github/workflows/**,.gitlab-ci.ymletJenkinsfileCODEOWNERSet.github/CODEOWNERS
La comparaison ignore la casse. Ajoutez vos propres chemins dans protectedPaths. Une modification du contrat enregistrée depuis Yuli est consignée dans l’audit et compte comme approuvée.
Dérogations (waivers)
Une dérogation permet d’ignorer une règle de façon temporaire et justifiée.
| Champ | Contenu |
|---|---|
id |
Identifiant de la dérogation. |
rule |
Règle concernée : secrets, protectedPaths, testIntegrity, un type de triche précis ou *. |
path |
Glob auquel elle s’applique. Vide signifie n’importe quel chemin. |
reason |
Motif. |
approvedBy |
Qui l’a approuvée. |
expires |
Date d’expiration, AAAA-MM-JJ. |
ticket |
Référence facultative. |
Une dérogation est valable jusqu’au jour indiqué dans expires inclus. Une date absente ou mal saisie compte comme expirée. À l’expiration, la règle s’applique de nouveau et le gate le signale.
Dans l’interface, chaque dérogation affiche son état : En vigueur, Expire bientôt, Expirée ou Date invalide.
testIntegrity neutralise d’un coup toutes les détections de triche dans les tests. Utilisez-la avec un chemin restreint et une date proche.
Audit
Chaque enregistrement ajoute une ligne à .ai/state/contract-audit.jsonl avec la date, l’auteur, le hash SHA-256 et un résumé (par exemple « criticality business→regulated; waivers +1 »).
L’auteur est toujours une personne : le nom indiqué ou votre git config user.name. « Yuli » et « Yuli Code » sont refusés comme auteurs.
Étape suivante
- Mesure contre N−1 : comment s’appliquent le score d’acceptation et les tours.
- Gate et Centre de gouvernance : comment le contrat est appliqué à chaque commit.