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.json et .ai/state/**
  • .claude/settings.json et .claude/settings.local.json
  • .githooks/**
  • .github/workflows/**, .gitlab-ci.yml et Jenkinsfile
  • CODEOWNERS et .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