# bmad-plus review

> Référence de bmad-plus review : sceller un périmètre, ancrer les constats dans le code, tirer un verdict de la couverture, reprendre, comparer, lister les règles, avec options et codes de sortie.

Canonical: https://bmad-plus.rochetta.fr/fr/docs/reference/cli-review/
Language: fr
BMAD+ version: 0.23.1
Documentation reviewed: 2026-10-19
Author: Laurent Rochetta
License: MIT

Documentation BMAD+ › [Référence](https://bmad-plus.rochetta.fr/fr/docs/reference/) › bmad-plus review

`bmad-plus review` est la couche de preuves d’une revue de code. Il ne lit pas votre code avec un modèle et ne le juge pas : la lecture revient à l’assistant (souvent Sentinel). La commande fige ce qui est relu (le périmètre), vérifie que chaque constat cité se trouve vraiment dans le code, et tire le verdict de ce qui a réellement été couvert : une revue arrêtée à mi-chemin ne peut donc jamais être déclarée propre. Servez-vous-en quand vous voulez une revue dont le résultat se vérifie, se script ou conditionne une pull request.

> **Remarque · Ce que « clean » veut dire** `clean` signifie : aucun constat ouvert dans un périmètre entièrement couvert. Cela ne prouve pas que le code est correct, et une revue sans aucun constat est permise. Une preuve manquante, en échec ou invalide donne `incomplete`, jamais `clean`.

<a id="synopsis"></a>
## Synopsis

**Dans le terminal de votre projet**

```sh
npx bmad-plus review <action> [id] [options]
npx bmad-plus review rules [path]
npx bmad-plus review compare <id> --since <earlier-id>
```

`id` nomme une revue et devient un dossier : lettres minuscules, chiffres, points et tirets, en commençant par une lettre ou un chiffre, 81 caractères au plus (par exemple `pr-42`). `rules` est la seule action qui prend un chemin au lieu d’un identifiant.

**Les six actions**

| Action | Ce qu’elle fait | Écrit |
| --- | --- | --- |
| `scope <id>` | Fige ce qui est relu : les fichiers modifiés entre deux commits (ou l’arbre de travail), ceux qui sont retenus, les règles qui s’appliquent à chacun et le plan de revue. | `scope.json`, `checklist.md` |
| `anchor <id>` | Valide `findings.json`, puis localise chaque extrait cité dans le code à la tête. Les valeurs qui ressemblent à des identifiants sont remplacées par `[REDACTED]` dans la trace écrite. | `findings.anchored.json` |
| `gate <id>` | Tire le verdict du périmètre, de la couverture et des constats ancrés : `clean`, `findings` ou `incomplete`. | éventuellement un fichier de contrôle pour la CI |
| `continue <id>` | Liste ce qu’une revue interrompue doit encore, sur le même périmètre scellé. Refusé si le code ou les règles ont bougé. | `continue.json` |
| `compare <id> --since <earlier-id>` | Classe les constats de cette revue par rapport à une revue précédente : nouveaux, persistants, résolus, réfutés, non relus. | `compare.json` |
| `rules [path]` | Affiche le jeu de règles effectif, ou les règles qu’un chemin donné recevrait. | rien |

**Options de review**

| Option | Argument | Défaut | Ce qu’elle fait |
| --- | --- | --- | --- |
| `-d, --directory` | `<path>` | dossier courant | Dossier du projet. |
| `--dir` | `<path>` | `_bmad-output/review` | Dossier des revues dans le projet. Chaque revue vit dans `<dir>/<id>/`. |
| `--base` | `<ref>` | `HEAD~1` (`HEAD` avec `--workspace`) | Commit ou branche de base. Le périmètre part de la base de fusion entre base et tête. |
| `--head` | `<ref>` | `HEAD` | Commit ou branche de tête. |
| `--workspace` | - | désactivé | Relire l’arbre de travail par rapport à la base, fichiers non suivis compris. |
| `--include` | `<glob>` | aucun | Ne relire que les chemins correspondants. Répétable. |
| `--exclude` | `<glob>` | aucun | Ne jamais relire les chemins correspondants. Répétable. |
| `--effort` | `low\|medium\|high` | `medium` | Profondeur de la revue (voir plus bas). |
| `--since` | `<id>` | aucun | `compare` seulement : la revue précédente à laquelle comparer. Obligatoire dans ce cas. |
| `--emit-check` | `<file>` | aucun | `gate` seulement : écrit aussi le verdict en résultat de contrôle JSON pour la CI. Doit être un fichier `.json`. |
| `--json` | - | désactivé | Sortie lisible par une machine au lieu du texte. |

<a id="workflow"></a>
## L’ordre du travail

1. **Sceller le périmètre** `review scope <id>` écrit `scope.json` et une liste de contrôle des règles qui s’appliquent aux chemins modifiés. Le périmètre a une empreinte : tout changement ultérieur du code ou des règles est détectable.

   ```sh
   npx bmad-plus review scope pr-42 --base main --effort high
   ```
2. **Relire et écrire les preuves** L’assistant lit les fichiers, écrit `findings.json` (chaque constat cite son code mot pour mot, avec catégorie, gravité, confiance et disposition) et `coverage.json` (chaque fichier retenu finit `completed`, `failed` ou `waived` avec une raison). BMAD+ n’appelle jamais de modèle pour cela.
3. **Ancrer les constats** `review anchor <id>` retrouve chaque extrait cité dans le code. Les numéros de ligne écrits par un modèle ne servent jamais ; seule la citation compte.

   ```sh
   npx bmad-plus review anchor pr-42
   ```
4. **Demander le verdict** `review gate <id>` tire `clean`, `findings` ou `incomplete`. Ajoutez `--emit-check` pour obtenir un document JSON qu’une étape de CI peut consommer.

   ```sh
   npx bmad-plus review gate pr-42 --emit-check ci/review-check.json
   ```
5. **Reprendre ou comparer au besoin** `review continue <id>` après une interruption ; `review compare <new-id> --since <id>` quand le code a changé et que vous avez relu.

<a id="reads-writes"></a>
## Ce qu’il lit et écrit

La commande lit l’historique git et les fichiers du projet (elle lance `git` pour `rev-parse`, `diff`, `merge-base` et `ls-files`) ainsi que les règles de revue. Elle n’écrit que dans `<dir>/<id>/`, plus le fichier de `--emit-check`. Elle n’ouvre aucune connexion réseau et n’appelle aucun modèle.

**Fichiers du dossier de revue**

| Fichier | Écrit par | Contenu |
| --- | --- | --- |
| `scope.json` | `scope` | Base, tête, base de fusion, fichiers retenus et exclus avec raisons, règles par fichier, unités, plan, empreinte. |
| `checklist.md` | `scope` | Les règles qui s’appliquent aux chemins modifiés, sous forme de liste de contrôle pour le relecteur. |
| `findings.json` | l’assistant | Schéma `bmad-plus/review-findings/1` ; chaque constat cite `existing_code` mot pour mot. |
| `coverage.json` | l’assistant | Un élément par fichier retenu (`completed`, `failed`, `waived` avec raison) et la manière dont l’exécution s’est terminée (`run.stop`). |
| `findings.anchored.json` | `anchor` | Les constats avec leurs lignes localisées et les nombres de constats localisés, ambigus et non localisés. |
| `continue.json` | `continue` | Le lot de travail restant. |
| `compare.json` | `compare` | Les constats nouveaux, persistants, résolus, réfutés et non relus. |

<a id="finding-vocabulary"></a>
### Vocabulaires fermés

**Valeurs permises dans findings.json et coverage.json**

| Champ | Valeurs |
| --- | --- |
| `severity` | `critical`, `high`, `medium`, `low` |
| `category` | `correctness`, `security`, `data-loss`, `concurrency`, `performance`, `error-handling`, `compatibility`, `test-gap`, `maintainability`, `documentation` |
| `confidence` | `high`, `medium`, `low` |
| `disposition` | `confirmed`, `refuted`, `unresolved` |
| coverage `outcome` | `completed`, `failed`, `waived` |
| `run.stop` | `completed`, `budget`, `time-limit`, `failure-streak`, `interrupted` |

Une valeur inconnue est une erreur, jamais corrigée en silence. Un constat réfuté garde sa réfutation, un constat confirmé exige une preuve, un fichier en échec ou écarté exige une raison. Seul `run.stop: completed` permet à la porte d’atteindre un verdict ; toute autre raison la laisse `incomplete`. Une unité qui échoue trois tentatives de suite est abandonnée et reste en échec.

<a id="effort"></a>
## Niveaux d’effort et plan

**--effort**

| Niveau | Passes | Passe de réfutation |
| --- | --- | --- |
| `low` | 1 | non |
| `medium` (défaut) | 2 | oui |
| `high` | 3 | oui |

Une passe est une lecture complète du périmètre ; les suivantes cherchent ce que les précédentes ont manqué. Le plan affiché par `scope` dépend aussi de la taille : à partir de 150 lignes modifiées, le relecteur planifie avant de lire, et avec plusieurs unités et au moins 400 lignes modifiées les unités peuvent être relues en parallèle. Une unité regroupe au plus 8 fichiers et 400 lignes.

<a id="exclusions"></a>
### Fichiers jamais retenus

- `secret` : `.env*`, clés et certificats (`*.pem`, `*.key`, `*.p12`, `*.pfx`, `id_rsa*`, `id_ed25519*`), `.npmrc`, `.netrc`, et tout ce qui est sous `credentials/`, `.credentials/` ou `secrets/`. Contrôlé avant tout `--include` : aucun motif ne peut les faire entrer.
- `binary`, `deleted`, `excluded-by-pattern` (votre `--exclude`), `not-included` (hors de votre `--include`).
- `generated-or-vendored` : `node_modules`, `dist`, `build`, `coverage`, `vendor`, fichiers minifiés, source maps et fichiers de verrouillage, sauf si un motif `--include` les capte.
- Le dossier de revue lui-même : écrire des constats ne change jamais le périmètre auquel ils répondent.

<a id="rules"></a>
## Règles de revue

Une règle est une liste de contrôle Markdown choisie selon le chemin du fichier. Toute règle dont un motif correspond s’applique au fichier : les règles s’additionnent. Huit sont livrées avec la CLI.

**Règles intégrées**

| Identifiant | Groupe | S’applique à |
| --- | --- | --- |
| `general` | code | tous les fichiers |
| `javascript-typescript` | code | `js cjs mjs jsx ts cts mts tsx vue svelte` |
| `python` | code | `py pyi` |
| `sql-and-migrations` | data | `*.sql`, dossiers de migrations, `*.prisma`, `schema.rb` |
| `shell` | code | `sh bash zsh ps1 psm1`, `Makefile` |
| `ci-workflows` | delivery | GitHub Actions, GitLab CI, pipelines Bitbucket et Azure |
| `containers` | delivery | `Dockerfile`, `Containerfile`, fichiers compose, manifestes Kubernetes et Helm |
| `configuration` | delivery | `json yml yaml toml ini properties`, `package.json`, `pyproject.toml`, `requirements*.txt`, `go.mod`, `Cargo.toml`, `composer.json` |

Quand le pack Shield est installé, six règles de conformité s’ajoutent (elles ne remplacent ni ne désactivent jamais une règle intégrée) : `shield-access-control`, `shield-personal-data`, `shield-cryptography`, `shield-logging`, `shield-ai-integrations` et `shield-change-and-supply-chain`. Chacune nomme les contrôles qu’elle examine sous la forme CADRE:ID, par exemple `ISO27001:A.8.5`, `SOC2:CC6.1`, `NIST-800-53:AC-3` ou `NIS2:Art.21(2)(i)`, et un constat ne peut citer que des contrôles examinés par les règles de son fichier.

Un projet ajoute, remplace (même identifiant) ou désactive des règles dans `_bmad/review-rules.yaml`. Ses fichiers `doc` sont du Markdown, résolus à côté de ce fichier. Désactiver un identifiant inconnu est une erreur.

**_bmad/review-rules.yaml**

```yaml
schema: bmad-plus/review-rules/1
rules:
  - id: billing-money
    title: Money amounts
    group: code
    globs: ['src/billing/**/*.ts']
    doc: review-rules/billing-money.md
disable:
  - python
```

<a id="exit-codes"></a>
## Codes de sortie

**Codes de sortie par action**

| Action | Code | Signification |
| --- | --- | --- |
| `scope`, `rules`, `compare` | 0 | Terminé. |
| `anchor` | 0 | Tous les constats sont localisés. |
| `anchor` | 1 | `findings.json` est invalide, ou au moins un constat est ambigu ou non localisé : citez un extrait exact plus long. |
| `gate` | 0 | `clean`. |
| `gate` | 1 | `findings` : au moins un constat confirmé ou non résolu est ouvert. |
| `gate` | 2 | `incomplete` : un fichier n’est pas pris en compte ou en échec, les preuves sont invalides ou absentes, l’exécution s’est arrêtée tôt, ou un constat ouvert n’est pas ancré. |
| `continue` | 0 | Un lot de travail restant a été écrit. |
| `continue` | 3 | `moved` : le code ou les règles ont changé depuis le scellement du périmètre (ou `coverage.json` est invalide). |
| toute action | 3 | Erreur : action inconnue, identifiant invalide, périmètre ou constats absents, échec de git, JSON illisible ou invalide. |

<a id="real-output"></a>
## Exemple de sortie

Ces transcriptions sont simulées : les lignes suivent les modèles de message de la commande, les nombres et l’empreinte sont illustratifs. Les chemins affichés par la vraie commande sont absolus.

**Sceller un périmètre** (Simulé)

```text
$ npx bmad-plus review scope pr-42 --base main --effort high
<project>/_bmad-output/review/pr-42/scope.json
3 file(s) to review, 41 changed lines, 1 unit(s) — scope 3f9a1c0d52b7
  excluded 1 × generated-or-vendored
checklist: <project>/_bmad-output/review/pr-42/checklist.md
plan: high effort, 3 pass(es), refutation pass
Every selected file must end in coverage.json as completed, failed or waived (with a reason).
```

Transcription illustrative, non capturée lors d’une exécution réelle. Source: tools/cli/commands/review.js (modèles de messages de l’action scope)

**Une porte pas encore prête** (Simulé)

```text
$ npx bmad-plus review gate pr-42
pr-42: incomplete — coverage 1/3 completed (0 waived), 0 open finding(s), 0 refuted
  - 2 selected file(s) never accounted for: src/a.js, src/b.js
# Code de sortie 2. La revue doit encore deux fichiers.
```

Transcription illustrative, non capturée lors d’une exécution réelle. Source: tools/cli/commands/review.js (action gate) et tools/cli/lib/review.js (motifs de reviewGate)

**Un verdict propre** (Simulé)

```text
$ npx bmad-plus review gate pr-42 --emit-check ci/review-check.json
pr-42: clean — coverage 3/3 completed (0 waived), 0 open finding(s), 0 refuted
  check: <project>/ci/review-check.json
  clean: no open finding within a fully covered scope. It does not prove the code correct.
# Code de sortie 0.
```

Transcription illustrative, non capturée lors d’une exécution réelle. Source: tools/cli/commands/review.js (action gate)

Le document de `--emit-check` est stable (sans horodatage, donc les mêmes preuves donnent les mêmes octets). Il porte le statut, le code de sortie, les raisons, les nombres, le périmètre auquel il répond, les constats ouverts avec leurs lignes et un bloc `github` calqué sur l’API des check-runs : `conclusion` (`success` ou `failure`) et un `output` avec un résumé Markdown et jusqu’à 50 annotations. Une revue de l’arbre de travail écrit son contrôle dans le dossier de revue ou hors du projet, pour qu’il n’entre pas dans le changement dont il rend compte.

<a id="errors"></a>
## Erreurs et que faire

Les erreurs affichent `review: <message>` sur le flux d’erreur (ou un objet JSON avec `status: "error"` sous `--json`) et sortent avec 3.

**Messages**

| Message | Cause | Que faire |
| --- | --- | --- |
| `unknown action "x" (scope, anchor, gate, continue, compare, rules)` | L’action n’est pas l’une des six. | Utiliser une des actions listées. |
| `a review id is required: lowercase letters, digits, dots and dashes` | Pas d’identifiant, ou un identifiant avec d’autres caractères. | Passer un identifiant comme `pr-42`. |
| `no scope at <path> — run "bmad-plus review scope <id>" first` | Le dossier de revue n’a pas de `scope.json`. | Lancer `review scope <id>` avec le même `--dir`. |
| `invalid ref "..."` ou `git rev-parse failed: ...` | Un `--base` ou `--head` qui ne désigne pas un commit. | Vérifier la référence (la récupérer en CI) ; les références commençant par `-` sont refusées. |
| `git is unavailable: ...` | git n’est pas dans le chemin du processus. | Installer git ou corriger le chemin. |
| `effort must be one of low\|medium\|high` | `--effort` inconnu. | Utiliser `low`, `medium` ou `high`. |
| `no findings at <path>` | `anchor` ou `compare` n’a pas trouvé de `findings.json`. | L’écrire, même avec une liste vide. |
| `--since <earlier review id> is required: ...` / `--since must name a different review` | `compare` sans `--since`, ou contre lui-même. | Passer l’identifiant de la revue précédente. |
| `--emit-check writes a .json file` / `--emit-check must not overwrite the review evidence` | Le chemin n’est pas un fichier `.json`, ou c’est l’un des fichiers de preuves. | Choisir un autre chemin `.json`. |
| `<id> cannot continue: the sealed scope no longer describes the code.` | Code 3 de `continue` : la tête a bougé, des fichiers ou les règles ont changé. | Sceller un nouveau périmètre avec les mêmes options, puis `review compare <new-id> --since <id>`. |
| raisons de la porte : `no coverage.json: ...`, `no findings.json: ...`, `N selected file(s) never accounted for: ...`, `the review stopped before the end (budget): ...` | Les preuves manquent, sont partielles ou l’exécution s’est arrêtée tôt. Code 2. | Terminer la revue (`continue`), écrire les deux fichiers, ne mettre `run.stop` à `completed` que si c’est vrai. |

<a id="examples"></a>
## Exemples

<a id="example-cli-review-seal-and-gate"></a>
### Relire une pull request avec des preuves vérifiables

Vous voulez que Sentinel relise les changements de la branche par rapport à main et rende un verdict fiable.

**Dans votre assistant IA**

```text
Sentinel, relis cette branche par rapport à main. Si la CLI BMAD+ est disponible, scelle le périmètre avec bmad-plus review scope pr-42 --base main --effort high, cite chaque constat mot pour mot, puis ancre-le et passe la porte, et rapporte la réponse de la porte sans la surévaluer.
```

**Ce que vous devriez obtenir** Sentinel lance `review scope`, qui écrit `scope.json` et `checklist.md` dans `_bmad-output/review/pr-42/`. Il relit les fichiers retenus, écrit `findings.json` et `coverage.json`, lance `review anchor` (code 1 si une citation reste introuvable) puis `review gate`. Il rapporte `clean`, `findings` ou `incomplete` tel que la porte l’a affiché. Une revue arrêtée ou partielle est déclarée incomplète, jamais propre.

<a id="example-cli-review-resume"></a>
### Reprendre une revue interrompue

La session s’est arrêtée avant que tous les fichiers soient lus et coverage.json note run.stop à interrupted.

**Dans votre assistant IA**

```text
Sentinel, reprends la revue pr-42 là où elle s’est arrêtée. Utilise bmad-plus review continue pr-42 et ne fais que ce qu’il liste.
```

**Ce que vous devriez obtenir** `review continue` écrit `continue.json` et affiche les fichiers et unités encore à relire, les constats à citer de nouveau, les passes restantes et toute unité abandonnée après trois tentatives en échec. Si le code ou les règles ont bougé, il refuse avec le code 3 et demande de sceller un nouveau périmètre puis d’utiliser `review compare`. Quand il ne reste rien, il invite à lancer `review gate` dès que `coverage.json` note l’exécution comme terminée.

<a id="example-cli-review-compare"></a>
### Relire après des corrections

L’auteur a poussé des corrections. Vous avez scellé un nouveau périmètre pr-43 et terminé la seconde revue.

**Dans votre assistant IA**

```text
Sentinel, compare la revue pr-43 à pr-42 avec bmad-plus review compare pr-43 --since pr-42 et dis-moi ce qui est nouveau, ce qui persiste et ce qui est vraiment résolu.
```

**Ce que vous devriez obtenir** La commande affiche `pr-43 since pr-42: N new, N persisting, N resolved, N refuted, N not reviewed` et écrit `compare.json`. Un constat de la revue précédente situé dans un fichier que la nouvelle revue n’a pas terminé est compté comme non relu : on ne sait pas s’il est corrigé.

<a id="example-cli-review-rules"></a>
### Voir quelles règles s’appliquent à un fichier

Vous vous demandez ce que Sentinel vérifiera dans un fichier d’authentification quand Shield est installé.

**Dans votre assistant IA**

```text
Sentinel, lance bmad-plus review rules src/auth/login.ts et dis-moi quelles règles et quels contrôles de conformité s’appliquent.
```

**Ce que vous devriez obtenir** La commande affiche l’empreinte du jeu de règles et les couches qui le composent (intégrées, fichiers de pack, fichier du projet), puis `src/auth/login.ts gets N rule(s)`, une ligne par règle avec son identifiant, son groupe, sa couche et ses motifs, et pour les règles Shield les contrôles comme `ISO27001:A.8.5` et `SOC2:CC6.1`. Les règles désactivées par le projet sont listées comme telles. Rien n’est écrit.

<a id="ci"></a>
## L’utiliser en CI

Le dépôt fournit des recettes GitHub Actions prêtes à copier dans `docs/recipes/ci-review/` : `review-scope.yml` scelle le périmètre et publie la liste de contrôle (ni agent ni modèle), `review-gate.yml` fait écrire les preuves par l’agent hôte installé sur un runner auto-hébergé, vérifie que rien n’a changé hors du dossier de revue, ancre les constats et fait échouer le contrôle sur `incomplete` ou des constats ouverts. Elles ne tournent que pour les pull requests du dépôt lui-même, jamais pour les forks, et n’exigent aucune clé de modèle stockée dans GitHub. Dans un script, les trois codes suffisent : 0 passe, 1 signifie des constats à lire, 2 signifie que les preuves ne sont pas encore là.

**Voir aussi**

- [Codes de sortie de toutes les commandes](https://bmad-plus.rochetta.fr/fr/docs/reference/cli-overview/#exit-codes)
- [assurance : dossiers de preuves pour Shield](https://bmad-plus.rochetta.fr/fr/docs/reference/cli-assurance/)
- [uat : recettes d’acceptation humaine](https://bmad-plus.rochetta.fr/fr/docs/reference/cli-uat/)
- [nexus : exécutions durables et vérification indépendante](https://bmad-plus.rochetta.fr/fr/docs/reference/cli-nexus/)
- [Dépannage](https://bmad-plus.rochetta.fr/fr/docs/faq/troubleshooting/)

[Documentation BMAD+](https://bmad-plus.rochetta.fr/fr/docs/) · [Référence](https://bmad-plus.rochetta.fr/fr/docs/reference/)

[Code sur GitHub](https://github.com/lrochetta/BMAD-PLUS)
