Skip to content

Commit 09bca11

Browse files
authored
Merge pull request #2007 from bmad-code-org/feat/code-review-rewrite
feat(skills): rewrite code-review with sharded step-file architecture
2 parents 4404b4b + 6a91eb6 commit 09bca11

7 files changed

Lines changed: 228 additions & 351 deletions

File tree

src/bmm/workflows/4-implementation/bmad-code-review/checklist.md

Lines changed: 0 additions & 23 deletions
This file was deleted.

src/bmm/workflows/4-implementation/bmad-code-review/discover-inputs.md

Lines changed: 0 additions & 88 deletions
This file was deleted.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
---
2+
name: Gather Context
3+
description: 'Determine what to review, construct the diff, and load any spec/context documents.'
4+
diff_output: '' # set at runtime
5+
spec_file: '' # set at runtime (path or empty)
6+
review_mode: '' # set at runtime: "full" or "no-spec"
7+
---
8+
9+
# Step 1: Gather Context
10+
11+
## RULES
12+
13+
- YOU MUST ALWAYS SPEAK OUTPUT in your Agent communication style with the config `{communication_language}`
14+
- The prompt that triggered this workflow IS the intent — not a hint.
15+
- Do not modify any files. This step is read-only.
16+
17+
## INSTRUCTIONS
18+
19+
1. **Detect review intent from invocation text.** Check the triggering prompt for phrases that map to a review mode:
20+
- "staged" / "staged changes" → Staged changes only
21+
- "uncommitted" / "working tree" / "all changes" → Uncommitted changes (staged + unstaged)
22+
- "branch diff" / "vs main" / "against main" / "compared to {branch}" → Branch diff (extract base branch if mentioned)
23+
- "commit range" / "last N commits" / "{sha}..{sha}" → Specific commit range
24+
- "this diff" / "provided diff" / "paste" → User-provided diff (do not match bare "diff" — it appears in other modes)
25+
- When multiple phrases match, prefer the most specific match (e.g., "branch diff" over bare "diff").
26+
- **If a clear match is found:** Announce the detected mode (e.g., "Detected intent: review staged changes only") and proceed directly to constructing `{diff_output}` using the corresponding sub-case from instruction 3. Skip to instruction 4 (spec question).
27+
- **If no match from invocation text, check sprint tracking.** Look for a sprint status file (`*sprint-status*`) in `{implementation_artifacts}` or `{planning_artifacts}`. If found, scan for any story with status `review`. Handle as follows:
28+
- **Exactly one `review` story:** Suggest it: "I found story {story-id} in `review` status. Would you like to review its changes? [Y] Yes / [N] No, let me choose". If confirmed, use the story context to determine the diff source (branch name derived from story slug, or uncommitted changes). If declined, fall through to instruction 2.
29+
- **Multiple `review` stories:** Present them as numbered options alongside a manual choice option. Wait for user selection. Then use the selected story's context to determine the diff source as in the single-story case above, and proceed to instruction 3.
30+
- **If no match and no sprint tracking:** Fall through to instruction 2.
31+
32+
2. Ask the user: **What do you want to review?** Present these options:
33+
- **Uncommitted changes** (staged + unstaged)
34+
- **Staged changes only**
35+
- **Branch diff** vs a base branch (ask which base branch)
36+
- **Specific commit range** (ask for the range)
37+
- **Provided diff or file list** (user pastes or provides a path)
38+
39+
3. Construct `{diff_output}` from the chosen source.
40+
- For **branch diff**: verify the base branch exists before running `git diff`. If it does not exist, HALT and ask the user for a valid branch.
41+
- For **commit range**: verify the range resolves. If it does not, HALT and ask the user for a valid range.
42+
- For **provided diff**: validate the content is non-empty and parseable as a unified diff. If it is not parseable, HALT and ask the user to provide a valid diff.
43+
- For **file list**: validate each path exists in the working tree. Construct `{diff_output}` by running `git diff HEAD -- <path1> <path2> ...`. If the diff is empty (files have no uncommitted changes), ask the user whether to review the full file contents or to specify a different baseline.
44+
- After constructing `{diff_output}`, verify it is non-empty regardless of source type. If empty, HALT and tell the user there is nothing to review.
45+
46+
4. Ask the user: **Is there a spec or story file that provides context for these changes?**
47+
- If yes: set `{spec_file}` to the path provided, verify the file exists and is readable, then set `{review_mode}` = `"full"`.
48+
- If no: set `{review_mode}` = `"no-spec"`.
49+
50+
5. If `{review_mode}` = `"full"` and the file at `{spec_file}` has a `context` field in its frontmatter listing additional docs, load each referenced document. Warn the user about any docs that cannot be found.
51+
52+
6. Sanity check: if `{diff_output}` exceeds approximately 3000 lines, warn the user and offer to chunk the review by file group.
53+
- If the user opts to chunk: agree on the first group, narrow `{diff_output}` accordingly, and list the remaining groups for the user to note for follow-up runs.
54+
- If the user declines: proceed as-is with the full diff.
55+
56+
### CHECKPOINT
57+
58+
Present a summary before proceeding: diff stats (files changed, lines added/removed), `{review_mode}`, and loaded spec/context docs (if any). HALT and wait for user confirmation to proceed.
59+
60+
61+
## NEXT
62+
63+
Read fully and follow `./step-02-review.md`
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
---
2+
name: Review
3+
description: 'Launch parallel adversarial review layers and collect findings.'
4+
---
5+
6+
# Step 2: Review
7+
8+
## RULES
9+
10+
- YOU MUST ALWAYS SPEAK OUTPUT in your Agent communication style with the config `{communication_language}`
11+
- The Blind Hunter subagent receives NO project context — diff only.
12+
- The Edge Case Hunter subagent receives diff and project read access.
13+
- The Acceptance Auditor subagent receives diff, spec, and context docs.
14+
15+
## INSTRUCTIONS
16+
17+
1. Launch parallel subagents. Each subagent gets NO conversation history from this session:
18+
19+
- **Blind Hunter** -- Invoke the `bmad-review-adversarial-general` skill in a subagent. Pass `content` = `{diff_output}` only. No spec, no project access.
20+
21+
- **Edge Case Hunter** -- Invoke the `bmad-review-edge-case-hunter` skill in a subagent. Pass `content` = `{diff_output}`. This subagent has read access to the project.
22+
23+
- **Acceptance Auditor** (only if `{review_mode}` = `"full"`) -- A subagent that receives `{diff_output}`, the content of the file at `{spec_file}`, and any loaded context docs. Its prompt:
24+
> You are an Acceptance Auditor. Review this diff against the spec and context docs. Check for: violations of acceptance criteria, deviations from spec intent, missing implementation of specified behavior, contradictions between spec constraints and actual code. Output findings as a markdown list. Each finding: one-line title, which AC/constraint it violates, and evidence from the diff.
25+
26+
2. **Subagent failure handling**: If any subagent fails, times out, or returns empty results, note the failed layer and proceed with findings from the remaining layers. Report the failure to the user in the next step.
27+
28+
3. **Fallback** (if subagents are not available): Generate prompt files in `{implementation_artifacts}` -- one per active reviewer:
29+
- `review-blind-hunter.md` (always)
30+
- `review-edge-case-hunter.md` (always)
31+
- `review-acceptance-auditor.md` (only if `{review_mode}` = `"full"`)
32+
33+
HALT. Tell the user to run each prompt in a separate session and paste back findings. When findings are pasted, resume from this point and proceed to step 3.
34+
35+
4. Collect all findings from the completed layers.
36+
37+
38+
## NEXT
39+
40+
Read fully and follow `./step-03-triage.md`
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
---
2+
name: Triage
3+
description: 'Normalize, deduplicate, and classify all review findings into actionable categories.'
4+
---
5+
6+
# Step 3: Triage
7+
8+
## RULES
9+
10+
- YOU MUST ALWAYS SPEAK OUTPUT in your Agent communication style with the config `{communication_language}`
11+
- Be precise. When uncertain between categories, prefer the more conservative classification.
12+
13+
## INSTRUCTIONS
14+
15+
1. **Normalize** findings into a common format. Expected input formats:
16+
- Adversarial (Blind Hunter): markdown list of descriptions
17+
- Edge Case Hunter: JSON array with `location`, `trigger_condition`, `guard_snippet`, `potential_consequence` fields
18+
- Acceptance Auditor: markdown list with title, AC/constraint reference, and evidence
19+
20+
If a layer's output does not match its expected format, attempt best-effort parsing. Note any parsing issues for the user.
21+
22+
Convert all to a unified list where each finding has:
23+
- `id` -- sequential integer
24+
- `source` -- `blind`, `edge`, `auditor`, or merged sources (e.g., `blind+edge`)
25+
- `title` -- one-line summary
26+
- `detail` -- full description
27+
- `location` -- file and line reference (if available)
28+
29+
2. **Deduplicate.** If two or more findings describe the same issue, merge them into one:
30+
- Use the most specific finding as the base (prefer edge-case JSON with location over adversarial prose).
31+
- Append any unique detail, reasoning, or location references from the other finding(s) into the surviving `detail` field.
32+
- Set `source` to the merged sources (e.g., `blind+edge`).
33+
34+
3. **Classify** each finding into exactly one bucket:
35+
- **intent_gap** -- The spec/intent is incomplete; cannot resolve from existing information. Only possible if `{review_mode}` = `"full"`.
36+
- **bad_spec** -- The spec should have prevented this; spec is wrong or ambiguous. Only possible if `{review_mode}` = `"full"`.
37+
- **patch** -- Code issue that is trivially fixable without human input. Just needs a code change.
38+
- **defer** -- Pre-existing issue not caused by the current change. Real but not actionable now.
39+
- **reject** -- Noise, false positive, or handled elsewhere.
40+
41+
If `{review_mode}` = `"no-spec"` and a finding would otherwise be `intent_gap` or `bad_spec`, reclassify it as `patch` (if code-fixable) or `defer` (if not).
42+
43+
4. **Drop** all `reject` findings. Record the reject count for the summary.
44+
45+
5. If zero findings remain after dropping rejects, note clean review.
46+
47+
6. If any review layer failed or returned empty (noted in step 2), report this to the user now.
48+
49+
50+
## NEXT
51+
52+
Read fully and follow `./step-04-present.md`
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
---
2+
name: Present
3+
description: 'Present triaged findings grouped by category with actionable recommendations.'
4+
---
5+
6+
# Step 4: Present
7+
8+
## RULES
9+
10+
- YOU MUST ALWAYS SPEAK OUTPUT in your Agent communication style with the config `{communication_language}`
11+
- Do NOT auto-fix anything. Present findings and let the user decide next steps.
12+
13+
## INSTRUCTIONS
14+
15+
1. Group remaining findings by category.
16+
17+
2. Present to the user in this order (include a section only if findings exist in that category):
18+
19+
- **Intent Gaps**: "These findings suggest the captured intent is incomplete. Consider clarifying intent before proceeding."
20+
- List each with title + detail.
21+
22+
- **Bad Spec**: "These findings suggest the spec should be amended. Consider regenerating or amending the spec with this context:"
23+
- List each with title + detail + suggested spec amendment.
24+
25+
- **Patch**: "These are fixable code issues:"
26+
- List each with title + detail + location (if available).
27+
28+
- **Defer**: "Pre-existing issues surfaced by this review (not caused by current changes):"
29+
- List each with title + detail.
30+
31+
3. Summary line: **X** intent_gap, **Y** bad_spec, **Z** patch, **W** defer findings. **R** findings rejected as noise.
32+
33+
4. If clean review (zero findings across all layers after triage): state that N findings were raised but all were classified as noise, or that no findings were raised at all (as applicable).
34+
35+
5. Offer the user next steps (recommendations, not automated actions):
36+
- If `patch` findings exist: "You can ask me to apply these patches, or address them manually."
37+
- If `intent_gap` or `bad_spec` findings exist: "Consider running the planning workflow to clarify intent or amend the spec before continuing."
38+
- If only `defer` findings remain: "No action needed for this change. Deferred items are noted for future attention."
39+
40+
Workflow complete.

0 commit comments

Comments
 (0)