Skill Tracer
Skills › BMAD Method › bmad-code-review › step-01-gather-context.md

step-01-gather-context.md

59 lines · skills/bmad-code-review/step-01-gather-context.md at bd70c64

Open on GitHub

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

1---
2diff_file: '' # set at runtime: path to the diff file
3claims_file: '' # set at runtime (path or empty)
4plan_file: '' # set at runtime (path or empty)
5ticket_file: '' # set at runtime: the story file, else the epic file, of the ticket under review (path or empty)
6review_mode: '' # set at runtime: full or no-plan
7---
8
9# Step 1: Gather Context

Step 1: Gather Context

Raw lines 1 to 10
11## RULES
13- The triggering prompt and the conversation before it name the review target — act on them; do not start from a blank slate.
14- Writing `{diff_file}` and the claims file is the only change this step may make. Otherwise it is read-only.
15{% if not workflow.interactive %}
16- No human can answer during this run: never ask and never HALT for input. Wherever an instruction below would ask, take the default it names instead; where it names none, stop and report what is missing.
17{% endif %}

RULES

  • The triggering prompt and the conversation before it name the review target — act on them; do not start from a blank slate.
  • Writing {diff_file} and the claims file is the only change this step may make. Otherwise it is read-only.

{% if not workflow.interactive %}

  • No human can answer during this run: never ask and never HALT for input. Wherever an instruction below would ask, take the default it names instead; where it names none, stop and report what is missing.

{% endif %}

Raw lines 11 to 18
19## INSTRUCTIONS
211. **Find the review target.** Check in this order and stop at the first that identifies it:
22 - **Request or recent conversation.** A PR (resolve via `gh pr view`; if that fails, ask for a SHA or branch), commit, branch, commit range, staged or uncommitted changes, a provided diff or file list, or a plan file. A plan sets `plan_file`, and when its frontmatter `ticket` is set, `tickets.py find <the plan's folder> <ticket>` (command form in the next bullet) names the ticket to read the same way; a non-empty frontmatter `baseline_revision` other than `NO_VCS` makes the diff source the **plan baseline** — otherwise say so and continue, since a plan without one does not identify the diff.
23 - **The ticket tree.** Run `uv run {project-root}/_bmad/method/scripts/tickets.py --project-root {project-root} status`. On a non-zero exit, continue. Otherwise offer the `tickets` rows whose `state` is `review`, `<ref>` and `<title>` each, plus a choice of another target, and HALT for the user's pick. With none, or another target chosen, continue. For a picked ticket, run `tickets.py find <ref>` (same command form): set `ticket_file` to its `story_file`, else its `epic_file`, read that file in full (with `story_file` null, the entry's `description` and `verify` are in `find`'s output), and treat its `plan` as a plan file from the request.
24 - **Current git state.** If HEAD is not on the default branch, confirm: "I see HEAD is `<short-sha>` on `<branch>` — do you want to review this branch's changes?" If confirmed, it is a branch diff against the default branch.
25 - **Ask.** Go to instruction 2.
27{% if not workflow.interactive %}
28 Skip the ticket-tree offer, take the current branch's diff against the default branch without confirming, and if HEAD is on the default branch and nothing else identifies a target, stop and report that there is nothing identified to review.
29{% endif %}
312. HALT. Ask the user what to review: uncommitted changes, staged changes, a branch diff (which base), a commit range, or a provided diff or file list.
333. Write the diff to `{diff_file}`, a uniquely-named temp file outside the repository, so concurrent reviews cannot collide. A plan baseline diffs every change since `baseline_revision`, untracked files included. A branch diff runs from the merge-base (`<base>...HEAD`), so later commits on the base do not show up as reverted. For a file list, include untracked files. If the source does not resolve, HALT and ask for a valid one; if the diff is empty, HALT — there is nothing to review. The review lenses read that file; the diff text is never pasted into their prompts. Read `{diff_file}` yourself when you need the diff later in this workflow.
354. **Stage the claims file.** Collect the change's own narrative: for a plan baseline, branch diff, or commit range, the commit messages it covers (`git log <base>..<head>`, where a plan baseline's head is `HEAD`); for other sources, whatever description of the change the user or conversation supplied. Write it verbatim to another uniquely-named temp file outside the repository and set `claims_file` to its path, or `''` if there is none. Do not analyze or summarize it — it is input for one review lens, staged as a file so the other lenses never see it.
375. **Set the plan context.**
38 - The request or conversation explicitly says there is no plan → `review_mode` = `no-plan`, `plan_file` = `''`. Do not ask.
39 - `plan_file` is set → verify it is readable; `review_mode` = `full`.
40{% if workflow.interactive %}
41 - Otherwise, ask for a plan file path, or to continue without one, and set `plan_file` and `review_mode` accordingly. Do not assume no-plan just because none was given.
42{% else %}
43 - Otherwise → `review_mode` = `no-plan`, `plan_file` = `''`.
44{% endif %}
466. If `review_mode` = `full` and `{plan_file}`'s frontmatter has a `context` list, load each referenced doc and warn about any that cannot be found. Open a file `{ticket_file}` lists in `sources:` or `companions:` only for a section the ticket cites; never re-derive requirements from it.
487. If `{diff_file}` exceeds about 3000 lines, warn the user and offer to chunk the review by file group. If they accept, agree on the first group, rebuild `{diff_file}` for it, and list the remaining groups for follow-up runs.

INSTRUCTIONS

  1. Find the review target. Check in this order and stop at the first that identifies it:
  2. Request or recent conversation. A PR (resolve via gh pr view; if that fails, ask for a SHA or branch), commit, branch, commit range, staged or uncommitted changes, a provided diff or file list, or a plan file. A plan sets plan_file, and when its frontmatter ticket is set, tickets.py find <the plan's folder> <ticket> (command form in the next bullet) names the ticket to read the same way; a non-empty frontmatter baseline_revision other than NO_VCS makes the diff source the plan baseline — otherwise say so and continue, since a plan without one does not identify the diff.
  3. The ticket tree. Run uv run {project-root}/_bmad/method/scripts/tickets.py --project-root {project-root} status. On a non-zero exit, continue. Otherwise offer the tickets rows whose state is review, <ref> and <title> each, plus a choice of another target, and HALT for the user's pick. With none, or another target chosen, continue. For a picked ticket, run tickets.py find <ref> (same command form): set ticket_file to its story_file, else its epic_file, read that file in full (with story_file null, the entry's description and verify are in find's output), and treat its plan as a plan file from the request.
  4. Current git state. If HEAD is not on the default branch, confirm: "I see HEAD is <short-sha> on <branch> — do you want to review this branch's changes?" If confirmed, it is a branch diff against the default branch.
  5. Ask. Go to instruction 2.

{% if not workflow.interactive %} Skip the ticket-tree offer, take the current branch's diff against the default branch without confirming, and if HEAD is on the default branch and nothing else identifies a target, stop and report that there is nothing identified to review. {% endif %}

  1. HALT. Ask the user what to review: uncommitted changes, staged changes, a branch diff (which base), a commit range, or a provided diff or file list.
  1. Write the diff to {diff_file}, a uniquely-named temp file outside the repository, so concurrent reviews cannot collide. A plan baseline diffs every change since baseline_revision, untracked files included. A branch diff runs from the merge-base (<base>...HEAD), so later commits on the base do not show up as reverted. For a file list, include untracked files. If the source does not resolve, HALT and ask for a valid one; if the diff is empty, HALT — there is nothing to review. The review lenses read that file; the diff text is never pasted into their prompts. Read {diff_file} yourself when you need the diff later in this workflow.
  1. Stage the claims file. Collect the change's own narrative: for a plan baseline, branch diff, or commit range, the commit messages it covers (git log <base>..<head>, where a plan baseline's head is HEAD); for other sources, whatever description of the change the user or conversation supplied. Write it verbatim to another uniquely-named temp file outside the repository and set claims_file to its path, or '' if there is none. Do not analyze or summarize it — it is input for one review lens, staged as a file so the other lenses never see it.
  1. Set the plan context.
  2. The request or conversation explicitly says there is no plan → review_mode = no-plan, plan_file = ''. Do not ask.
  3. plan_file is set → verify it is readable; review_mode = full.

{% if workflow.interactive %}

  • Otherwise, ask for a plan file path, or to continue without one, and set plan_file and review_mode accordingly. Do not assume no-plan just because none was given.

{% else %}

  • Otherwise → review_mode = no-plan, plan_file = ''.

{% endif %}

  1. If review_mode = full and {plan_file}'s frontmatter has a context list, load each referenced doc and warn about any that cannot be found. Open a file {ticket_file} lists in sources: or companions: only for a section the ticket cites; never re-derive requirements from it.
  1. If {diff_file} exceeds about 3000 lines, warn the user and offer to chunk the review by file group. If they accept, agree on the first group, rebuild {diff_file} for it, and list the remaining groups for follow-up runs.
Raw lines 19 to 49
Runs code scripts/tickets.py :23
Involves a person Ask the user :31
Involves a person HALT and ask :33
50### CHECKPOINT
52Present a summary before proceeding: diff stats (files changed, lines added/removed), `{review_mode}`, and the loaded ticket, plan, and context docs (if any).
53{% if workflow.interactive %}
54HALT and wait for user confirmation to proceed.
55{% endif %}

CHECKPOINT

Present a summary before proceeding: diff stats (files changed, lines added/removed), {review_mode}, and the loaded ticket, plan, and context docs (if any). {% if workflow.interactive %} HALT and wait for user confirmation to proceed. {% endif %}

Raw lines 50 to 56
Involves a person HALT and wait :54
57## NEXT
59Read fully and follow `{{ rendered("step-02-review.md") }}`

NEXT

Read fully and follow {{ rendered("step-02-review.md") }}

Raw lines 57 to 59