Skill Tracer
Skills › BMAD Method › bmad-review

bmad-review

skill · 54 lines · MIT · skills/bmad-review/SKILL.md

The facts

Its description

Runs one or more installed review lenses — adversarial critique, edge cases, verification gaps, structure, prose — and reports triaged findings. Use when, and only when, the user asks you to review a diff, a pull request, or an artifact — code or documents, one or many — and actually says "review"; an explicit skill:bmad-review directive from another skill counts as that ask. A request to act on feedback from an earlier review is a change, not a review. Never invoke this uninvited, including on edits you just made.

The description the agent reads to decide when to use it.

From its settingsline 3

When it starts

The agent picks this skill when the user explicitly asks it to review a diff, pull request, or artifact — code or documents, one or many — and actually says "review"; an explicit skill:bmad-review directive from another skill counts as that ask. It is never invoked uninvited, including on edits the agent just made, and acting on earlier review feedback is a change, not a review.

Things a person might say (the model's guesses)

  • “Review this diff before I merge it.”
  • “Can you review the pull request on the feature/login branch?”
  • “Review this PRD document for me.”

A model's summary of when it is used.

A model's reading

Starts other agents

2 lines mention starting other agents

Lines in the file that mention starting another agent. Found by matching words, so treat them as pointers.

Found by matching wordsline 36 line 37

Runs scripts

scripts/resolve_customization.py

Scripts the text names. Found by matching words, so treat them as pointers.

Found by matching wordsline 28

Files it mentions

references/lens-edge-case-hunter.md, customize.toml

Files the text names, such as ones to read or write. Found by matching words, so treat them as pointers.

Found by matching wordsline 22 line 23 line 32

What it leads to

Other skills this one hands off to, calls, requires or offers instead, as a model read them.

A model's reading

What leads to it

Other skills that hand off to this one, call it, require it or offer it instead, as a model read them.

A model's reading

Names skills outside this collection

Skills the text names that are not in this collection, as a model read them.

A model's reading

Licence

MIT, from LICENSE

The terms its author shares it under, which let it be shown here.

From the repositorylicence text
Other files in this skill (10) Close

The text

Open on GitHub

Most marks come from matching words in the file, so treat them as pointers.

1---
2name: bmad-review
3description: 'Runs one or more installed review lenses — adversarial critique, edge cases, verification gaps, structure, prose — and reports triaged findings. Use when, and only when, the user asks you to review a diff, a pull request, or an artifact — code or documents, one or many — and actually says "review"; an explicit skill:bmad-review directive from another skill counts as that ask. A request to act on feedback from an earlier review is a change, not a review. Never invoke this uninvited, including on edits you just made.'
4---
5
6# BMad Review
7
8Review content through lenses — each a distinct method and stance — and report findings in one canonical shape. Report what is real — never pad to look thorough. Each lens sets its own stance toward the content and toward zero findings: for most an empty result is valid; the adversarial lens requires at least ten concrete findings and treats an empty list as a signal to re-check; the editorial lenses hold content sacrosanct and critique only how it is organized and expressed.
9
10The lens set is whatever `{workflow.lenses}` resolves to, not a fixed list — overrides add lenses and replace shipped ones. Never claim a capability from this file; read the resolved lenses and work from those.

BMad Review

Review content through lenses — each a distinct method and stance — and report findings in one canonical shape. Report what is real — never pad to look thorough. Each lens sets its own stance toward the content and toward zero findings: for most an empty result is valid; the adversarial lens requires at least ten concrete findings and treats an empty list as a signal to re-check; the editorial lenses hold content sacrosanct and critique only how it is organized and expressed.

The lens set is whatever {workflow.lenses} resolves to, not a fixed list — overrides add lenses and replace shipped ones. Never claim a capability from this file; read the resolved lenses and work from those.

Raw lines 1 to 11
12## Inputs
14- **content** — what to review: a diff, branch, uncommitted changes, file, ticket (initiative, epic, story, spike, bug), or any document. Args: `[path]`.
15- **lenses** (optional) — one or more lens codes or names, however the caller expresses them: a spoken request, or a directive of the form `skill:bmad-review lenses=<code>[,<code>...]` (the form bmm's `doc_standards` uses). Default: every applicable lens (a full review).
16- **also_consider** (optional) — areas to keep in mind alongside each lens's normal analysis.
17- **claims** (optional) — the change's own narrative: the commit messages it covers, or whatever description of it the caller supplied. Goes to the edge-case lens alone.
18- **pre-resolved customization** (optional) — `[workflow]` field values supplied by a forwarding caller. See Execution step 1.

Inputs

  • content — what to review: a diff, branch, uncommitted changes, file, ticket (initiative, epic, story, spike, bug), or any document. Args: [path].
  • lenses (optional) — one or more lens codes or names, however the caller expresses them: a spoken request, or a directive of the form skill:bmad-review lenses=<code>[,<code>...] (the form bmm's doc_standards uses). Default: every applicable lens (a full review).
  • also_consider (optional) — areas to keep in mind alongside each lens's normal analysis.
  • claims (optional) — the change's own narrative: the commit messages it covers, or whatever description of it the caller supplied. Goes to the edge-case lens alone.
  • pre-resolved customization (optional) — [workflow] field values supplied by a forwarding caller. See Execution step 1.
Raw lines 12 to 19
20## Conventions
22- Bare paths (e.g. `references/lens-edge-case-hunter.md`) resolve from `{skill-root}` — this skill's installed directory, where `customize.toml` lives. `{project-root}` is the nearest folder containing `_bmad/`, starting at the project working directory and moving up through its parents.
23- `{workflow.<name>}` resolves to fields in `customize.toml`'s `[workflow]` table (overrides win per BMad merge rules).
24- In `style_guide`, `review_guidance`, and `persistent_facts`, a value prefixed `file:` is a path or glob — load that file's contents. If a `file:` value cannot be read, name the failed file in the output header and continue: the shipped baseline for `style_guide`, the remaining entries otherwise.

Conventions

  • Bare paths (e.g. references/lens-edge-case-hunter.md) resolve from {skill-root} — this skill's installed directory, where customize.toml lives. {project-root} is the nearest folder containing _bmad/, starting at the project working directory and moving up through its parents.
  • {workflow.<name>} resolves to fields in customize.toml's [workflow] table (overrides win per BMad merge rules).
  • In style_guide, review_guidance, and persistent_facts, a value prefixed file: is a path or glob — load that file's contents. If a file: value cannot be read, name the failed file in the output header and continue: the shipped baseline for style_guide, the remaining entries otherwise.
Raw lines 20 to 25
Reads a file customize.toml :22
26## Execution
281. **Resolve customization:** `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --project-root {project-root} --key workflow`.
29 - Script not found: BMad is not set up here. Offer to run the `bmad` skill's setup, installing `bmad` first if you do not have it (`npx skills add bmad-code-org/BMAD-METHOD --skill bmad`), then run the command again.
30 - Any other failure: read `{skill-root}/customize.toml` directly and use defaults.
32 **Forwarded activation:** if a caller invoked you with pre-resolved customization fields (e.g. the `bmad-editorial-review` shim), honor them verbatim for those named fields — they already carry the user's overrides — and resolve only the remaining fields from your own `customize.toml`. Then execute each `{workflow.activation_steps_prepend}` entry in order, hold `{workflow.persistent_facts}` as standing context for the session, and treat `{workflow.review_guidance}` entries as standing review directives for every lens.
332. **Load the content.** Stage it once as a file: when the content is a branch, uncommitted work, or a commit range, use the repository's version-control tooling to write the unified diff to a uniquely-named file in the system temp directory and take that file's absolute path as the content. A branch means its diff against the merge base with its base branch; uncommitted work includes untracked files. Stage `claims` to its own file the same way — it is input for one lens, staged separately precisely so the other lenses never see it. If the content is empty or cannot be decoded as text: when the caller expects the raw findings JSON array (e.g. the legacy edge-case forwarder), return `[{"location":"N/A","trigger_condition":"Input empty or undecodable","guard_snippet":"Provide valid content to review","potential_consequence":"Review skipped — no analysis performed"}]` (no `lens` field) and stop; otherwise say what's wrong and ask for reviewable content. Classify the content — diff, source file, function, or document — and whether it is **code** or **docs**; scope rules and lens applicability both depend on it. A document that defines behavior (a ticket, a plan, requirements) is `docs` that a behavioral lens may still apply to; judge by `when`.
343. **Select lenses** from `{workflow.lenses}`. A lens with an empty `instruction` is disabled. If the user or caller named lenses, run exactly those only — `applies_to` and `when` do not filter an explicit request. Otherwise run every enabled lens whose `applies_to` covers the content class (`any` always covers) and whose `when` applies.
354. **Announce the plan** in one line before running anything: the content class, the lenses about to run, and — when any lens has `after` set — that it runs on top of the named lens's findings. Skip the announcement entirely when the caller pinned an exact output contract (the legacy forwarders that demand raw JSON or one exact line) — their contract covers everything you emit, not just the findings block. Then execute each `{workflow.activation_steps_append}` entry in order.
365. **Run the independent lenses** — every selected lens without `after`. Each sees the content and `also_consider`, never another lens's findings. Follow each lens's `instruction`; the shipped lenses load their reference file just-in-time, so load only what runs. When subagents are available, launch every independent lens before handling any lens's result. Try running them simultaneously: spawn one per lens; give it the lens `instruction` with `{skill-root}` and paths resolved absolute, the absolute path of the staged content file (a lens prompt carries the path and the lens reads the file, never the content bytes; inline the content only when it was never staged as a file), any `also_consider` areas, the standing review directives, the `claims` path to the edge-case lens alone (marked to leave unread until its instructions call for it), and the constraint "Return ONLY your findings — no other output. Do not invoke any skill, and do not spawn subagents of your own — you are the reviewer. Return your findings as text in your final message; do not route them through any findings-reporting tool the host may offer." Otherwise run the lenses sequentially yourself, completing one before starting the next.
376. **Run the dependent lenses** — every selected lens with `after`, once the lens it names has completed, passing that lens's findings in. A lens whose `after` target was not selected or produced nothing still runs, with no prior findings. Dependent lenses that name different targets are independent of each other: launch every ready one before handling any of their results. Try running them simultaneously. When subagents are available, spawn them with the same constraint as independent lenses: "Return ONLY your findings — no other output. Do not invoke any skill, and do not spawn subagents of your own — you are the reviewer. Return your findings as text in your final message; do not route them through any findings-reporting tool the host may offer."
387. **Assemble and present** per Output below. Keep every lens's findings — overlap between lenses is signal, not duplication; note it in the markdown report rather than deduping. Execute `{workflow.on_complete}` if set.

Execution

  1. Resolve customization: uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --project-root {project-root} --key workflow.
  2. Script not found: BMad is not set up here. Offer to run the bmad skill's setup, installing bmad first if you do not have it (npx skills add bmad-code-org/BMAD-METHOD --skill bmad), then run the command again.
  3. Any other failure: read {skill-root}/customize.toml directly and use defaults.

Forwarded activation: if a caller invoked you with pre-resolved customization fields (e.g. the bmad-editorial-review shim), honor them verbatim for those named fields — they already carry the user's overrides — and resolve only the remaining fields from your own customize.toml. Then execute each {workflow.activation_steps_prepend} entry in order, hold {workflow.persistent_facts} as standing context for the session, and treat {workflow.review_guidance} entries as standing review directives for every lens.

  1. Load the content. Stage it once as a file: when the content is a branch, uncommitted work, or a commit range, use the repository's version-control tooling to write the unified diff to a uniquely-named file in the system temp directory and take that file's absolute path as the content. A branch means its diff against the merge base with its base branch; uncommitted work includes untracked files. Stage claims to its own file the same way — it is input for one lens, staged separately precisely so the other lenses never see it. If the content is empty or cannot be decoded as text: when the caller expects the raw findings JSON array (e.g. the legacy edge-case forwarder), return [{"location":"N/A","trigger_condition":"Input empty or undecodable","guard_snippet":"Provide valid content to review","potential_consequence":"Review skipped — no analysis performed"}] (no lens field) and stop; otherwise say what's wrong and ask for reviewable content. Classify the content — diff, source file, function, or document — and whether it is code or docs; scope rules and lens applicability both depend on it. A document that defines behavior (a ticket, a plan, requirements) is docs that a behavioral lens may still apply to; judge by when.
  2. Select lenses from {workflow.lenses}. A lens with an empty instruction is disabled. If the user or caller named lenses, run exactly those only — applies_to and when do not filter an explicit request. Otherwise run every enabled lens whose applies_to covers the content class (any always covers) and whose when applies.
  3. Announce the plan in one line before running anything: the content class, the lenses about to run, and — when any lens has after set — that it runs on top of the named lens's findings. Skip the announcement entirely when the caller pinned an exact output contract (the legacy forwarders that demand raw JSON or one exact line) — their contract covers everything you emit, not just the findings block. Then execute each {workflow.activation_steps_append} entry in order.
  4. Run the independent lenses — every selected lens without after. Each sees the content and also_consider, never another lens's findings. Follow each lens's instruction; the shipped lenses load their reference file just-in-time, so load only what runs. When subagents are available, launch every independent lens before handling any lens's result. Try running them simultaneously: spawn one per lens; give it the lens instruction with {skill-root} and paths resolved absolute, the absolute path of the staged content file (a lens prompt carries the path and the lens reads the file, never the content bytes; inline the content only when it was never staged as a file), any also_consider areas, the standing review directives, the claims path to the edge-case lens alone (marked to leave unread until its instructions call for it), and the constraint "Return ONLY your findings — no other output. Do not invoke any skill, and do not spawn subagents of your own — you are the reviewer. Return your findings as text in your final message; do not route them through any findings-reporting tool the host may offer." Otherwise run the lenses sequentially yourself, completing one before starting the next.
  5. Run the dependent lenses — every selected lens with after, once the lens it names has completed, passing that lens's findings in. A lens whose after target was not selected or produced nothing still runs, with no prior findings. Dependent lenses that name different targets are independent of each other: launch every ready one before handling any of their results. Try running them simultaneously. When subagents are available, spawn them with the same constraint as independent lenses: "Return ONLY your findings — no other output. Do not invoke any skill, and do not spawn subagents of your own — you are the reviewer. Return your findings as text in your final message; do not route them through any findings-reporting tool the host may offer."
  6. Assemble and present per Output below. Keep every lens's findings — overlap between lenses is signal, not duplication; note it in the markdown report rather than deduping. Execute {workflow.on_complete} if set.
Raw lines 26 to 39
Runs code scripts/resolve_customization.py :28
Names a skill bmad :29
Reads a file customize.toml :32
Starts an agent subagents :36
Starts an agent spawn :36
40## Output
42One JSON array holding every finding from every lens. Each finding carries:
44- `lens` — the code of the lens that produced it
45- `location` — where in the content (file:line-range for code, section for documents)
46- `trigger_condition` — the problem, or the condition that exposes it, in one line
47- `guard_snippet` — the concrete fix, guard, or missing check
48- `potential_consequence` — what goes wrong if it ships as-is
50Each lens file refines these semantics for its findings and may add lens-specific fields (e.g. `kind`/`confidence` on deletion findings, `gap_shape`/`consumer`/`evidence` on verification-gap findings). A lens file may instead declare its own findings shape and rendering — the editorial lenses render a findings table — and that shape wins for that lens's findings. `[]` is valid when nothing is found. No severity, priority, or ranking anywhere.
52Present per `{workflow.output_format}` — `"json"` (the raw array in a fenced json block), `"markdown"`, or `"both"` — unless the caller requested a specific shape; a legacy forwarder's output contract always wins, and governs everything you emit rather than the findings block alone. The markdown report groups findings by lens, each rendered in its declared shape: a short block per finding rendering the fields plus any extras worth surfacing, one line for a lens that found nothing, and a plain clean statement when the whole review is clean. Shape the report per `{workflow.output_preferences}`.
54When `{workflow.report_path}` is set, write the report there; otherwise present it in chat.

Output

One JSON array holding every finding from every lens. Each finding carries:

  • lens — the code of the lens that produced it
  • location — where in the content (file:line-range for code, section for documents)
  • trigger_condition — the problem, or the condition that exposes it, in one line
  • guard_snippet — the concrete fix, guard, or missing check
  • potential_consequence — what goes wrong if it ships as-is

Each lens file refines these semantics for its findings and may add lens-specific fields (e.g. kind/confidence on deletion findings, gap_shape/consumer/evidence on verification-gap findings). A lens file may instead declare its own findings shape and rendering — the editorial lenses render a findings table — and that shape wins for that lens's findings. [] is valid when nothing is found. No severity, priority, or ranking anywhere.

Present per {workflow.output_format} — "json" (the raw array in a fenced json block), "markdown", or "both" — unless the caller requested a specific shape; a legacy forwarder's output contract always wins, and governs everything you emit rather than the findings block alone. The markdown report groups findings by lens, each rendered in its declared shape: a short block per finding rendering the fields plus any extras worth surfacing, one line for a lens that found nothing, and a plain clean statement when the whole review is clean. Shape the report per {workflow.output_preferences}.

When {workflow.report_path} is set, write the report there; otherwise present it in chat.

Raw lines 40 to 54

From bmad-code-org/BMAD-METHOD at bd70c64, 2026-10-31. Skills read by DeepSeek V4.1 Flash on 2026-11-04. Summary and techniques by Claude Opus 5.5 on 2026-11-06.