Développement piloté par contraintes

Établit le niveau de qualité d'un projet sous forme de contrat écrit et empêche les agents de le réduire silencieusement. Interviewe l'utilisateur sur les dimensions importantes, fournit des seuils par défaut, enregistre tout dans CONSTRAINTS.md et surveille les affaiblissements du bar.

Qu'est-ce que Développement piloté par contraintes ?

Cette compétence transforme les exigences de qualité d'un projet en un contrat écrit et vérifiable mécaniquement qui survit à la session de l'agent. Elle guide l'utilisateur à travers un entretien en quatre questions pour déterminer les dimensions critiques (couverture de test, sécurité, performance, accessibilité, architecture), propose des seuils par défaut lorsque l'utilisateur n'a pas de chiffre en tête, et produit automatiquement un fichier `CONSTRAINTS.md` à la racine du dépôt. Le système surveille ensuite les changements pour détecter tout affaiblissement du niveau de qualité : nouvelles suppressions `@ts-ignore` ou `eslint-disable`, tests ignorés ou supprimés, assertions retirées, stubs non implémentés ou seuils réduits. Elle est compatible avec tous les environnements d'agents (Claude Code, Cursor, Codex, GitHub Copilot), nécessite un utilisateur interactif pour l'entretien initial, et applique un plancher minimal de qualité même en mode autonome.

Compatible avec✓Claude Code✓Codex CLI~Cursor
npx skills add https://github.com/addyosmani/agent-skills/tree/main/skills/constraint-driven-development

Installed? Explore more Développement et programmation skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Que fait Développement piloté par contraintes ?

Présentation

Les autres compétences de ce pack décrivent ce qui est bien. code-review-and-quality vous donne cinq axes. test-driven-development vous donne un cycle. security-and-hardening vous donne une liste de menaces. Tout cela vit dans une prose que l'agent lit et peut ou non suivre, et rien ne survit à la fin de la session.

Cette compétence produit quelque chose de différent : un enregistrement écrit du niveau de qualité de ce projet, avec des chiffres, qui survit à la conversation et peut être vérifié mécaniquement.

La raison est importante. Quand vous écriviez le code, le lire vous disait s'il était bon. Un agent écrit plus en un après-midi que vous n'en lirez cette semaine, donc le jugement passe de votre tête à des vérifications qui tournent en boucle. Ces vérifications doivent exister, elles doivent avoir des chiffres que vous avez réellement choisis, et elles doivent se déclencher suffisamment près du travail pour que l'agent corrige sa propre sortie.

Le développement piloté par spécifications dit quoi construire. Le développement piloté par tests prouve que ça marche. Le développement piloté par contraintes définit ce que « assez bon pour être livré » signifie, avant que quiconque ne discute dans une pull request.

Quand utiliser

Appliquez cette compétence lorsque :

  • Vous démarrez un projet ou une fonctionnalité importante et aucun niveau de qualité n'est écrit
  • L'utilisateur demande à « définir des contraintes », « ajouter des portes de qualité », « définir nos standards » ou « empêcher l'agent de livrer de la camelote »
  • Un agent produit un volume que personne ne lit ligne par ligne
  • L'intégration continue a des vérifications, mais personne ne sait lesquelles bloquent une fusion et lesquelles sont décoratives
  • Les chiffres de couverture, performance ou accessibilité sont débattus par pull request au lieu d'être décidés une fois pour toutes
  • Vous êtes sur le point d'exécuter /build auto ou toute boucle autonome, et la seule chose entre elle et la branche principale est une suite de tests que l'agent a également écrite

À NE PAS utiliser lorsque :

  • Le projet a déjà un CONSTRAINTS.md et l'utilisateur ne le modifie pas — lisez-le et suivez-le à la place
  • Scripts uniques, expérimentations, prototypes jetables
  • L'utilisateur veut une revue de code maintenant (code-review-and-quality) ou une pipeline CI construite (ci-cd-and-automation)
  • Code pré-Product-Market-Fit avec une durée de vie estimée à deux semaines — le plancher en vaut encore la peine, le reste non

Chargement des contraintes

L'entretien nécessite un utilisateur en direct. Ne l'exécutez pas dans des contextes non interactifs (CI, /loop, exécutions autonomes). Si les contraintes sont manquantes et que vous êtes dans l'un de ces contextes, appliquez le plancher ci-dessous, notez que vous l'avez fait, et signalez le reste à un humain.

Le processus

Étape 1 : Détectez avant de demander

Ne demandez jamais ce que vous pouvez lire. Avant la première question, recueillez :

QuoiOù chercher
Langage et stackpackage.json, pyproject.toml, go.mod, Cargo.toml
Exécuteur de testsdépendances de développement, script test, fichiers de test existants
Linters existantseslint.config.*, biome.json, .ruff.toml
Couverture actuellesortie coverage/, ou exécutez la suite une fois
CI.github/workflows/, .gitlab-ci.yml
Infrastructure agent.claude/, .codex/, AGENTS.md

Signalez ce que vous avez trouvé en deux lignes, puis demandez seulement ce qui reste.

Étape 2 : Quatre questions, chacune avec une valeur par défaut

Suivez la discipline une question à la fois de interview-me, avec un changement : chaque question ici a une valeur par défaut, donc « Je ne sais pas » est une réponse complète qui produit toujours une configuration fonctionnelle.

Q1 : Au-delà du plancher, lesquelles de celles-ci voulez-vous appliquer ?
    (a) Couverture de test sur le nouveau code
    (b) Scan de sécurité
    (c) Budgets de performance
    (d) Accessibilité
    (e) Frontières d'architecture
ESTIMATION : (a) et (b) — vous avez déjà un exécuteur de tests et vous traitez des entrées utilisateur.
DÉFAUT si incertain : (a) et (b).
Dites ce que chaque choix coûte : (c) et (d) nécessitent une URL en cours d'exécution, (e) nécessite un fichier de règles écrit.
Q2 : Lorsqu'une vérification échoue pendant que l'agent est en pleine tâche, doit-elle bloquer ou avertir ?
ESTIMATION : Bloquer. Vous exécutez des agents sans surveillance et un avertissement que personne ne lit est un avertissement.
DÉFAUT si incertain : Bloquer sur le plancher, avertir sur tout le reste pour les deux premières semaines.
Q3 : Avez-vous des chiffres cibles en tête, ou dois-je mesurer où vous en êtes aujourd'hui et maintenir cette ligne ?
ESTIMATION : Mesurer. La plupart des équipes n'ont pas de chiffre, et un chiffre inventé est ignoré.
DÉFAUT si incertain : Mesurer et maintenir. Voir « Cliquets » ci-dessous.
Q4 : Quelle est la vérification la plus lente que vous tolérerez avant que l'agent ne rende le travail ?
ESTIMATION : Environ 90 secondes. Plus long et vous arrêterez de l'exécuter.
DÉFAUT si incertain : 90 secondes à la fin de la tâche, illimité dans CI.

Arrêtez-vous à quatre. Un questionnaire de douze questions produit une configuration que personne ne comprend et un utilisateur qui regrette d'avoir commencé.

Étape 3 : Écrire CONSTRAINTS.md

Un fichier à la racine du dépôt. Tout agent sur toute infrastructure peut le lire, et une modification apparaît dans la revue là où elle doit être.

# Contraintes

Dernière révision : 2026-08-08 par @addy

## Plancher (toujours appliqué, sans configuration requise)

- Pas de nouveaux commentaires de suppression : `@ts-ignore`, `eslint-disable`, `# noqa`, `# type: ignore`
- Pas de stubs non implémentés : `throw new Error("Not implemented")`, `catch {}` vide
- Pas de tests ignorés ou supprimés sans raison dans le message de commit
- Pas de secrets dans le code source
- Ce fichier ne doit pas être affaibli pour faire passer une modification

## Appliqué avec des chiffres

| Dimension | Règle | Vérifié par | S'exécute à |
|-----------|-------|-------------|-------------|
| Types | Zéro erreur de type | `tsc --noEmit` | chaque édition |
| Lint | Zéro erreur de notre config | `biome check` | chaque édition |
| Secrets | Pas de secrets dans le source | `gitleaks detect --redact` | chaque édition |
| Couverture | Lignes modifiées ≥ 80 % couvertes | `vitest run --coverage` + git diff | fin de tâche, CI |
| Sécurité : code | Aucun résultat élevé | `semgrep scan --config p/default` | CI |
| Sécurité : dépendances | Rien à haut ou au-dessus | `osv-scanner scan source -r .` | CI |
| Accessibilité | Zéro critique ou sérieux | `axe $PREVIEW_URL --tags wcag2a,wcag2aa,wcag21aa` | déploiement de preview |
| Performance | LCP ≤ 2500ms, CLS ≤ 0.1 | `lighthouse $PREVIEW_URL --output=json` | déploiement de preview |

Chaque ligne nomme la commande qui produit le verdict. Une dimension avec un
chiffre et aucune commande dans cette colonne est une aspiration, pas une contrainte.

## Mesuré, pas encore appliqué

| Métrique | Aujourd'hui | Direction |
|----------|-------------|-----------|
| Couverture du projet | 62.4 % | ne doit pas baisser |
| Taille du bundle (main) | 184 kB | ne doit pas augmenter |

## Exceptions

| ID | Règle | Chemin | Raison | Propriétaire | Expire |
|----|-------|--------|--------|--------------|--------|
| W1 | `no-explicit-any` | `src/legacy/**` | Réécriture suivie dans ENG-441 | @addy | 2026-11-01 |

Ajoutez ensuite une ligne à AGENTS.md et CLAUDE.md : Lisez CONSTRAINTS.md avant d'écrire du code. Ne l'affaiblissez pas pour faire passer une modification.

Étape 4 : Installer ce dont chaque dimension a besoin

Choisir une dimension signifie installer quelque chose. Ne laissez pas l'utilisateur avec un chiffre et aucun mécanisme, et n'inventez pas votre propre vérificateur quand un outil de facto existe — ces outils sont listés parce que leurs formats de règles et seuils sont ce que tout le reste de l'écosystème cible, donc la configuration existante de l'équipe continue de fonctionner.

DimensionOutilInstallationExécutionPorte sur
Types (TS)tscdéjà présenttsc --noEmittoute erreur
Types (Python)mypypip install mypymypy .toute erreur
Lintvotre config existantedéjà présenteslint . / biome check / ruff checktoute erreur
Couverture (JS)votre exécuteur de testsdéjà présentvitest run --coverage (ou jest --coverage)couverture des lignes modifiées
Couverture (Python)pytest-covpip install pytest-covpytest --cov --cov-report=lcovidem
Sécurité : codeSemgreppipx install semgrepsemgrep scan --config p/default --config p/owasp-top-tentout résultat élevé
Sécurité : secretsgitleaksbrew install gitleaksgitleaks detect --redact --no-bannertout résultat
Sécurité : dépendancesosv-scannerbrew install osv-scannerosv-scanner scan source -r .haut ou supérieur
Performance : pageLighthousenpm i -D lighthouselighthouse $URL --output=json --quietLCP, CLS, score de performance
Performance : bundlesize-limitnpm i -D size-limitsize-limit --jsonbudget par entrée
Accessibilitéaxe-corenpm i -D @axe-core/cliaxe $URL --tags wcag2a,wcag2aa,wcag21aazéro critique ou sérieux
Architecturedependency-cruisernpm i -D dependency-cruiserdepcruise --validate srctoute violation
Qualité des assertionsStrykernpm i -D @stryker-mutator/corestryker run --mutate <fichiers modifiés>score de mutation

Cinq choses qui vous mordront si vous les sautez :

  1. --redact sur gitleaks n'est pas optionnel. Sans lui, le secret correspondant atterrit dans le journal de l'agent, ce qui fait qu'une clé divulguée se retrouve dans un log, un résumé ou un message de commit. Signalez la règle et l'emplacement, jamais la valeur.
  2. Lighthouse et axe ont besoin d'une URL. Ils ne fonctionnent que contre une application en cours d'exécution, donc ils appartiennent à l'étape d'exécution contre un déploiement de preview ou un serveur local que vous démarrez d'abord. Si le projet n'a pas d'URL à atteindre — un CLI, une bibliothèque, une application de bureau — dites-le et abandonnez la dimension plutôt que d'inventer une vérification qui ne peut pas s'exécuter.
  3. Limitez les vérifications coûteuses au diff. stryker run --mutate sur l'ensemble du dépôt prend des heures et sera désactivé ; sur les fichiers touchés par un changement, cela prend moins d'une minute. Idem pour Semgrep, qui prend une liste de chemins.
  4. La couverture n'a pas besoin d'une deuxième exécution de test. Lisez le lcov que votre suite écrit déjà et croisez-le avec git diff. Exécuter la suite deux fois pour obtenir un chiffre est le moyen le plus rapide de faire détester cette approche.
  5. Les règles du registre Semgrep sont gratuites à exécuter ; vérifiez la licence avant de les redistribuer. opengrep est un fork compatible avec le même format de règles et une sortie JSON si cela compte pour votre équipe juridique.

Ajoutez chacune au script propre du projet pour qu'il soit reproductible sans agent :

{
  "scripts": {
    "check:fast": "tsc --noEmit && eslint . && gitleaks detect --redact --no-banner",
    "check:task": "npm run check:fast && vitest run --coverage",
    "check:full": "npm run check:task && semgrep scan --config p/default && osv-scanner scan source -r ."
  }
}

Ce mappage est plus important que les outils. check:fast est ce qui s'exécute après une édition, check:task quand l'agent pense avoir terminé, check:full dans CI.

Les commandes vivent maintenant à deux endroits — la colonne Vérifié par dans CONSTRAINTS.md et ces scripts. CONSTRAINTS.md est la source canonique : elle porte la raison à côté de chaque commande et apparaît dans la revue. Les scripts sont des wrappers de commodité qui doivent la refléter, pas une seconde source de vérité ; s'ils divergent, le fichier gagne.

Étape 5 : Câbler au cycle de vie

La plus grosse erreur est de tout exécuter partout. Une vérification qui bloque l'agent est désactivée, et une porte désactivée est pire qu'aucune porte, car le niveau de qualité semble toujours exister.

PhaseCommandeCe qui s'exécuteBudget
BUILD/buildTypes, lint, secrets, le planchermoins de 5s, fichier modifié seulement
VERIFY/testTests associés, couverture sur les lignes modifiéesmoins de 90s
REVIEW/reviewTout, plus les gardes ci-dessousminutes
SHIP/shipVérifications de direction, pas de régressionsCI

Deux règles qui rendent cela tolérable :

  1. Limitez au diff. Vérifiez les lignes que ce changement a touchées, pas l'ensemble du dépôt. La couverture des lignes modifiées est un chiffre que l'agent peut faire bouger ; la couverture du projet est un chiffre qu'il hérite.
  2. Le coût décide de l'emplacement. Tout ce qui dépasse quelques secondes sort de la boucle d'édition. Les tests de mutation sur un dépôt entier prennent des heures ; sur les fichiers touchés par un changement, cela prend moins d'une minute, ce qui fait la différence entre une vérification que les gens exécutent et une qu'ils ne font pas.

Étape 6 : Protéger le niveau de qualité lui-même

Quelqu'un fera remarquer que si l'agent écrit le code et les vérifications, les vérifications ne prouvent rien. À moitié vrai, et ça vaut la peine de l'ingénieriser.

Les agents ne créent pas de failles astucieuses. Ils rencontrent un échec rouge et prennent le chemin le moins cher pour passer au vert. Surveillez ces cinq mouvements dans le diff, au moment de la revue :

  1. Le seuil a bougé. Un budget réduit, une sévérité baissée, une vérification retirée de l'étape rapide. Comparez CONSTRAINTS.md à son état au point de branchement.
  2. Un test est devenu plus facile. .skip ajouté, un fichier de test supprimé, des assertions retirées de tests qui sont restés.
  3. Un vérificateur a été réduit au silence. Nouveau @ts-ignore ou eslint-disable. Quatre suppressions méritent une attention particulière car elles désactivent une vérification sur laquelle vous comptez : istanbul ignore retire du code de la couverture au lieu de le tester, Stryker disable cache un mutant survivant, nosemgrep et gitleaks:allow font de même pour les résultats de sécurité.
  4. Le travail est inachevé. Un stub qui lève une exception, un catch vide qui transforme un échec en silence, un TODO à la place de l'implémentation.
  5. Une exception est apparue. Une nouvelle ligne dans le tableau des Exceptions dont personne n'a parlé.

Aucun de ces éléments n'a besoin d'outillage au-delà de git diff. Renforcer le niveau de qualité devrait être silencieux ; l'affaiblir devrait être bruyant.

Contrairement aux dimensions numérotées, le plancher n'a pas d'outil de facto propre, donc un agent chargé de l'appliquer a tendance à écrire un vérificateur à partir de zéro, et deux agents en écrivent deux différents. Une implémentation de référence de ces cinq vérifications est livrée avec cette compétence dans references/floor-guard.md (limitée au diff, code de sortie 0/1/2, modèles adaptables par écosystème). Adaptez-la plutôt que de la réinventer, pour la même raison que chaque dimension nomme un outil de facto : pour que le mécanisme soit le même d'une exécution à l'autre et d'un stack à l'autre.

Toutes les vérifications ne sont pas également circulaires. Classez-les selon une question : l'agent peut-il les faire passer en écrivant du code qui ne fonctionne pas ?

  • Externe — axe-core encode WCAG, osv-scanner lit une base de données de vulnérabilités, Lighthouse mesure un vrai navigateur. L'agent ne peut pas discuter avec ceux-ci.
  • Projet — vos règles de lint, vos limites de couche. Un humain possède le fichier.
  • Suite — vos propres tests. Le plus utile, et le seul vraiment circulaire.

Un bar

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

addyosmani/agent-skills

Prepares production launches. Use when preparing to deploy to production, or when asking what needs to be in place before shipping. Use when you need a pre-launch checklist, when setting up monitoring, when planning a staged rollout, or when you need a rollback strategy.

addyosmani/agent-skills

Builds production-quality, accessible, responsive user-facing UIs. Use when building or modifying interfaces and pages, creating components, implementing layouts, meeting WCAG accessibility requirements, managing state, or when the output needs to look and feel production-quality rather than AI-generated.

addyosmani/agent-skills

Guides stable API and interface design. Use when designing APIs, module boundaries, or any public interface. Use when creating REST or GraphQL endpoints, defining type contracts between modules, or establishing boundaries between frontend and backend.

addyosmani/browser-testing-with-devtools

Tests in real browsers via Chrome DevTools MCP. Use when building or debugging anything that runs in a browser. Use when you need to inspect the DOM, capture console errors, analyze network requests, profile performance, or verify visual output with real runtime data. Requires the chrome-devtools MCP server to be configured.

addyosmani/ci-cd-and-automation

Automates CI/CD pipeline setup. Use when setting up or modifying build and deployment pipelines. Use when you need to automate quality gates, configure test runners in CI, or establish deployment strategies.

addyosmani/code-review-and-quality

Conducts multi-axis code review. Use before merging any change. Use when reviewing code written by yourself, another agent, or a human. Use when you need to assess code quality across multiple dimensions before it enters the main branch.

addyosmani/code-simplification

Simplifies code for clarity. Use when refactoring code for clarity without changing behavior. Use when code works but is harder to read, maintain, or extend than it should be. Use when reviewing code that has accumulated unnecessary complexity.

addyosmani/debugging-and-error-recovery

Guides systematic root-cause debugging. Use when tests fail, builds break, behavior doesn't match expectations, or you encounter any unexpected error. Use when you need a systematic approach to finding and fixing the root cause rather than guessing.

addyosmani/deprecation-and-migration

Manages deprecation and migration. Use when removing old systems, APIs, or features. Use when migrating users from one implementation to another. Use when deciding whether to maintain or sunset existing code.

addyosmani/documentation-and-adrs

Records decisions and documentation. Use when making architectural decisions, changing public APIs, shipping features, or when you need to record context that future engineers and agents will need to understand the codebase.

addyosmani/doubt-driven-development

Subjects every non-trivial decision to a fresh-context adversarial review before it stands. Use when correctness matters more than speed, when working in unfamiliar code, when stakes are high (production, security-sensitive logic, irreversible operations), or any time a confident output would be cheaper to verify now than to debug later.

addyosmani/git-workflow-and-versioning

Structures git workflow practices. Use when making any code change. Use when committing, branching, resolving conflicts, or when you need to organize work across multiple parallel streams.

addyosmani/idea-refine

Refines raw ideas into sharp, actionable concepts through structured divergent and convergent thinking. Use when an idea is still vague, when you need to stress-test assumptions before committing to a plan, or when you want to expand options before converging on one. Triggers on "ideate", "refine this idea", or "stress-test my plan".

addyosmani/incremental-implementation

Delivers changes incrementally. Use when implementing any feature or change that touches more than one file. Use when you're about to write a large amount of code at once, or when a task feels too big to land in one step.

addyosmani/interview-me

Extracts what the user actually wants instead of what they think they should want. Achieves this through one-question-at-a-time interview until ~95% confidence about the underlying intent. Use when an ask is underspecified ("build me X" without "for whom" or "why now"), when the user explicitly invokes ("interview me", "grill me", "are we sure?", "stress-test my thinking"), or when you catch yourself silently filling in ambiguous requirements before any plan, spec, or code exists.

addyosmani/observability-and-instrumentation

Instruments code so production behavior is visible and diagnosable. Use when adding logging, metrics, tracing, or alerting. Use when shipping any feature that runs in production and you need evidence it works. Use when production issues are reported but you can't tell what happened from the available data.

addyosmani/performance-optimization

Optimizes application performance. Use when performance requirements exist, when you suspect performance regressions, or when Core Web Vitals or load times need improvement. Use when profiling reveals bottlenecks that need fixing.

addyosmani/planning-and-task-breakdown

Breaks work into ordered tasks. Use when you have a spec or clear requirements and need to break work into implementable tasks. Use when a task feels too large to start, when you need to estimate scope, or when parallel work is possible.

addyosmani/security-and-hardening

Hardens code against vulnerabilities. Use when handling user input, authentication, data storage, or external integrations. Use when building any feature that accepts untrusted data, manages user sessions, or interacts with third-party services.

addyosmani/source-driven-development

Grounds every implementation decision in official documentation. Use when you want authoritative, source-cited code free from outdated patterns. Use when building with any framework or library where correctness matters.

Skills associés