Parcourir la documentation

bmad-plus uat

Référence de bmad-plus uat (alias recette) : lint, build, serve, import, read, gate et order pour les recettes d’acceptation humaine, avec options, codes de sortie et exemples.

Sur cette page
  1. Synopsis
  2. Ce qu’elle lit et écrit
  3. Comment la porte décide
  4. Codes de sortie
  5. Exemples de sortie
  6. Erreurs et conduite à tenir
  7. Exemples

bmad-plus uat (alias bmad-plus recette) gère les recettes d’acceptation humaine. Une recette est une spécification JSON d’étapes qu’une personne joue à l’écran. La commande valide la spécification, construit une page HTML autonome pour le testeur, enregistre ses réponses dans une exécution JSON, liste les échecs et en tire un verdict de porte. Elle sert quand une livraison doit être vue en fonctionnement par une personne, et pas seulement par des tests. Sentinel la pilote à votre place ; vous en avez besoin pour scripter le processus, brancher une étape de CI ou vérifier ce que l’agent affirme.

Remarque Ce que la porte prouve, et ce qu’elle ne prouve pas

La porte établit qu’une exécution est terminée, à jour, entièrement répondue et triée. Elle n’établit jamais que le testeur a regardé au bon endroit : tout verdict est donc étiqueté « observé par un humain ». Une porte « passed » peut encore reposer sur des échecs : ils doivent seulement être classés, chacun avec une décision.

Synopsis

Dans le terminal de votre projet
npx bmad-plus uat <action> [target] [options]
npx bmad-plus recette <action> [target] [options]

action est l’une des sept actions ci-dessous. target est un identifiant de recette (la commande cherche <dir>/specs/<id>.json, puis toute spécification de ce dossier dont l'id correspond) ou le chemin d’un fichier .json. order n’a pas de cible.

Les sept actions
ActionCe qu’elle faitÉcrit
lintValide la spécification : schéma, clés inconnues, balisage, identifiants d’étapes et d’attendus, témoins, budget de 15 étapes / 30 minutes. Avec --src, vérifie que chaque libellé d’écran cité existe dans un fichier source.rien
buildLance d’abord le lint et refuse à la moindre erreur, puis écrit la page du testeur.<dir>/pages/uat-<id>.html
serveSert la page construite sur 127.0.0.1 et enregistre chaque réponse envoyée par la page. Tourne jusqu’à Ctrl+C.<dir>/results/<id>/<runId>.json
importEnregistre un JSON de résultats exporté depuis la page (fichier ou entrée standard).<dir>/results/<id>/<runId>.json
readListe chaque exécution et chaque attendu en échec ou bloqué avec son texte et la note du testeur.rien
gateCalcule le verdict : passed, failed, awaiting ou stale. --emit-check écrit en plus un vérificateur autonome.<dir>/checks/gate-<id>.cjs (seulement avec --emit-check)
orderCalcule l’ordre de jeu de toutes les recettes de <dir>/specs à partir de leur after et des témoins partagés.<dir>/ORDER.md
Options
OptionArgumentDéfautEffet
-d, --directory<path>dossier courantDossier du projet.
--dir<path>_bmad-output/uatDossier des recettes dans le projet : specs/, pages/, results/, triage/, checks/.
--src<path>aucunDossier source scanné pour les libellés d’écran (lint, build). Répétable.
--language<code>voir plus basLangue de la page : un code (fr), un nom (Français) ou une balise de locale.
--input<file>aucunimport seulement : fichier de résultats à enregistrer ; - lit l’entrée standard. Obligatoire pour import.
--port<number>4173serve seulement : port, lié à 127.0.0.1 uniquement.
--emit-checkaucundésactivégate seulement : écrit aussi le vérificateur Nexus checks/gate-<id>.cjs.
--jsonaucundésactivéSortie lisible par machine, avec schemaVersion: 1.

Langue de la page, par ordre de priorité : le champ language de la recette, puis --language, puis le communication_language lu dans _bmad/config.yaml, puis l’anglais. La page embarque toujours les dix langues de l’installateur (en, fr, es, de, pt-br, ru, zh, he, ja, it) et le testeur peut en changer sur la page.

Ce qu’elle lit et écrit

  • Lit : les spécifications de <dir>/specs (refusées au-delà de 4 Mio ou si le fichier est un lien symbolique), _bmad/config.yaml (build seulement, pour communication_language), les résultats de <dir>/results/<id>/ et le fichier de tri <dir>/triage/<id>.json.
  • Avec --src : ne lit que les fichiers source de ces extensions : ts, tsx, js, jsx, mjs, cjs, vue, svelte, html, htm, php, py, rb, java, kt, cs, go, json, yaml, yml, md. Elle ignore les liens symboliques, les dossiers commençant par un point, node_modules, .git, dist, build, coverage, .next, .nuxt, vendor, __pycache__, .venv, venv, target et out, saute les fichiers de plus de 512 Kio et s’arrête après 20000 fichiers.
  • Écrit : uniquement les fichiers nommés dans le tableau ci-dessus. Les valeurs ressemblant à des identifiants collées dans une note de testeur sont remplacées par [REDACTED] avant que l’exécution n’atteigne le disque (import et serve) ; l’exécution garde alors le nombre de remplacements dans redactions.
  • Réseau : aucun, sauf serve, qui n’écoute que sur 127.0.0.1. La page construite ne demande rien à une autre origine. Un testeur sur une autre machine utilise la page comme fichier ou comme artefact et renvoie le JSON pour import.
  • serve ne répond qu’aux noms d’hôte 127.0.0.1:<port> et localhost:<port> (tout autre en-tête Host reçoit HTTP 403), refuse un corps de requête de plus de 4 Mio et répond HTTP 409 quand une copie plus ancienne d’une exécution remplacerait une plus récente.

Comment la porte décide

La porte prend l’exécution terminée le plus récent de la recette. S’il n’y en a pas, le statut est awaiting. Si cette exécution répond à une autre révision de la spécification (son specSha256 diffère de la spécification actuelle), le statut est stale. Sinon le statut est failed tant qu’au moins une raison ci-dessous s’applique, et passed quand aucune ne s’applique.

  • Un attendu n’a jamais reçu de réponse (les étapes optionnelles sont ignorées).
  • Un attendu en échec ou bloqué n’a pas d’entrée dans <dir>/triage/<id>.json, ou sa classe est undecided, ou sa décision n’est pas l’une de fix, amend-spec, remeasure, accept-risk, ask-tester.
  • Une décision est accept-risk sans decidedBy.
  • Un attendu est bloqué et sa décision n’est pas accept-risk : rien n’a été observé, il faut le rejouer ou faire accepter le risque par une personne nommée.
  • Une étape writes: true est passée, mais le tri n’a pas d’entrée writeChecks avec verified: true et un texte evidence : une coche sur une étape qui écrit est une observation, c’est la preuve en lecture seule qui tranche.
Vocabulaire du tri
ClasseSensDécision usuelle
productL’écran diffère de ce que le code devait afficher.fix
recipeL’écran est juste, l’attendu le décrivait mal.amend-spec
dataLe témoin n’est plus dans l’état supposé.remeasure
undecidedAucune note, ou non attribuable : interroger le testeur. Garde la porte au rouge.ask-tester

Codes de sortie

Code de sortie par action
Action0123
lintaucune erreurau moins une erreur, ou tout échec--
buildpage écriteerreur de lint, gabarit ayant perdu une garantie, ou tout échec--
importexécution enregistréetout échec--
readexécutions lues, rien en échecun attendu en échec ou bloqué, ou tout échecpas encore d’exécution (awaiting)l’exécution le plus récent répond à une autre révision (stale)
gatepassedfailed (ou tout échec)awaitingstale
orderordre écritun cycle, aucune spécification dans le dossier, ou tout échec--

Un échec est toute erreur levée : action inconnue, cible manquante, spécification introuvable, fichier illisible, --input absent. Elle affiche uat: <message> sur la sortie d’erreur, ou {"schemaVersion":1,"status":"error","message":...} avec --json, et sort avec 1. Un script de livraison qui doit distinguer une porte en échec (1) d’une porte qui n’a pas pu s’exécuter utilise la porte de projet uat-release-gate.mjs, qui ajoute le code 4 pour le second cas.

Exemples de sortie

Le premier bloc a été rejoué avec la spécification d’exemple livrée dans la compétence bmad-plus-uat ; les blocs read et gate sont composés à partir des gabarits de messages de la commande, marqués comme simulés, et reprennent le jeu d’essai de tests/unit/uat-cli.test.js. Nombres de fichiers, tailles et empreintes dépendent de votre projet.

Valider puis construire une recette
npx bmad-plus uat lint example-1.0.0
example-1.0.0: 3 steps, 5 expectations, 8 on-screen labels
  no error
npx bmad-plus uat build example-1.0.0
/work/app/_bmad-output/uat/pages/uat-example-1.0.0.html — 3 steps, 83 KiB, spec a4a4850b284d
opens in English; the tester can switch to any of the 10 languages on the page
carries the 17 page guarantees: hidden-before-start, no-answer-before-run, verified-local-write, honest-save-status, save-on-every-change, restore-before-capabilities, newer-copy-wins, revision-guard, other-tab-notice, unreadable-draft-kept, progress-accessible, storage-explained, finished-is-not-accepted, unload-guard, utf8-and-escaped-diacritics, export-is-the-run, no-third-party-requests
npx bmad-plus uat lint example-1.0.0 --src src
example-1.0.0: 3 steps, 5 expectations, 8 on-screen labels
  error   step 0-setup: do: the label "Folders" is in no source file — copy it from the component, accents included or not
  error   step 1-nominal: where: the label "Technical" is in no source file — copy it from the component, accents included or not
Quatre autres erreurs du même genre suivent et la commande sort avec 1 : ici `src` est un dossier vide, donc aucun libellé de la spécification n’y est trouvé. `--src` doit pointer vers les dossiers qui contiennent réellement les libellés de vos écrans.

Sortie capturée lors d’une exécution réelle. Source: Rejoué avec le paquet 0.23.0 et la spécification d’exemple de la compétence bmad-plus-uat, dans un projet jetable ; le chemin du projet est remplacé par /work/app

Lire une exécution, puis demander la porteSimulé
npx bmad-plus uat read demo-1.0.0

■ Demo 1.0.0 — Sarah — 2026-09-16 08:00, finished
  1 passed · 1 failed · 0 blocked · 0 skipped · 0 to do   (_bmad-output/uat/results/demo-1.0.0/20260916-sarah-aaaa.json)
  ✗ 1-confirm/a (failed) — Confirm
      expectation: The line reads OPCO confirmed.
      seen instead: the line still reads OPCO to confirm
Code de sortie 1 : un échec existe.
npx bmad-plus uat gate demo-1.0.0
demo-1.0.0: failed (run 20260916-sarah-aaaa by Sarah)
  - 1-confirm/a is failed and not triaged
Code de sortie 1. Une fois l’échec classé dans triage/demo-1.0.0.json (classe product, décision fix), la même commande affiche « demo-1.0.0: passed ... » et sort avec 0.

Transcription illustrative, non capturée lors d’une exécution réelle. Source: tools/cli/commands/uat.js (modèles de read et gate) ; tests/unit/uat-cli.test.js (jeu d’essai demo-1.0.0, exécution 20260916-sarah-aaaa)

Erreurs et conduite à tenir

Messages affichés par uat
MessageCauseQue faire
uat: an id or a spec file is requiredAucune cible pour une action qui en exige une.Passez l’identifiant de la recette ou le chemin du fichier .json.
uat: no spec with the id "<id>" in <dir>/specsAucun fichier du dossier specs ne porte cet id.Vérifiez --dir et --directory ; la correspondance porte sur le champ id, pas seulement sur le nom du fichier.
step <id>: ... ou unknown key at spec level: "<key>" ... (listés comme error)Une faute de frappe ou un champ manquant dans la spécification : les clés inconnues sont refusées, pas ignorées.Corrigez la spécification et relancez lint.
the label "<text>" is in no source fileUn libellé d’écran cité est introuvable dans les dossiers donnés avec --src.Copiez le libellé depuis le composant, accents compris ou non. Sans --src, ce contrôle ne s’exécute pas.
<id>: not built, N error(s)build lance le lint et refuse d’écrire la page à la moindre erreur.Corrigez les erreurs listées.
the page template ... lost a guarantee — not builtLe gabarit de page ne porte plus l’une des 17 garanties.Réinstallez ou mettez BMAD+ à jour ; ne modifiez pas le gabarit à la main.
no page at <file> — run "bmad-plus uat build <id>" firstserve exige une page construite.Lancez build, puis serve.
--input <file> or --input - is requiredimport sans --input.Passez le JSON exporté, ou - pour l’entrée standard.
these results answer <a>, not <b>L’exécution importée appartient à une autre recette.Importez-le avec l’identifiant auquel il répond.
unsupported results schema: ... ou results without runIdLe fichier n’est pas une exécution exportée par la page.Exportez de nouveau depuis la page, ou utilisez l’export de l’artefact.
<id>: no run yet (code 2)Aucun JSON dans <dir>/results/<id>/.Servez ou envoyez la page, puis import des réponses.
unknown action "<x>" (lint, build, serve, import, read, gate, order)Action mal écrite.Utilisez l’une des sept actions.

Exemples

Faire écrire et construire la recette par Sentinel

Une version est prête pour l’environnement de test. Vous voulez une page qu’un collègue non technique peut jouer.

Dans votre assistant IA
Sentinel, écris la recette d’acceptation de cette livraison sur notre environnement de test. Valide-la avec lint sur src, construis la page et dis-moi quelles étapes écrivent pour de bon.

Ce que vous devriez obtenir Sentinel écrit la spécification dans _bmad-output/uat/specs/<id>.json, lance bmad-plus uat lint <id> --src src et corrige ce qui est signalé, puis lance bmad-plus uat build <id>, qui écrit _bmad-output/uat/pages/uat-<id>.html et liste les garanties de la page. Il vous remet le lien ou le fichier, la durée et les étapes marquées writes: true, chacune avec son contrôle verify en lecture seule. Si la CLI n’est pas disponible, il le dit au lieu de prétendre que la page est construite.

Lire l’exécution, trier, demander la porte

Le testeur a terminé la page et renvoyé le JSON.

Dans votre assistant IA
Sentinel, importe le fichier de résultats results.json pour la recette demo-1.0.0, lis l’exécution, classe chaque échec et dis-moi si la porte passe.

Ce que vous devriez obtenir Sentinel lance uat import demo-1.0.0 --input results.json, puis uat read demo-1.0.0, qui affiche chaque attendu en échec ou bloqué avec son texte et la note du testeur. Il écrit une classe et une décision pour chacun dans _bmad-output/uat/triage/demo-1.0.0.json, vous interroge quand une note n’explique pas l’échec (la classe undecided garde la porte au rouge), puis rapporte uat gate demo-1.0.0 avec le statut et le code de sortie (0 passed, 1 failed, 2 awaiting, 3 stale). Il étiquette la preuve « observé par un humain ».

Brancher la porte dans un script de livraison (porte de projet copiée depuis templates/)
node scripts/uat-release-gate.mjs || exit 1
# deploy only below this line

La compétence livre deux portes de projet dans .agents/skills/bmad-plus-uat/templates/ : uat-spec-present.mjs échoue quand aucune recette ne nomme la version de package.json, et uat-release-gate.mjs lance uat gate avec la CLI installée dans le projet (0 passed, 1 failed, 2 aucune exécution terminée, 3 autre révision, 4 la porte n’a pas pu s’exécuter, ce qui n’est pas un succès).