bmad-method 6.10.1-next.26 → 6.10.1-next.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/package.json +1 -1
  2. package/src/bmm-skills/4-implementation/bmad-code-review/customize.toml +27 -17
  3. package/src/bmm-skills/4-implementation/bmad-code-review/review-prompts/adversarial.md +3 -4
  4. package/src/bmm-skills/4-implementation/bmad-code-review/review-prompts/edge-case-hunter.md +3 -5
  5. package/src/bmm-skills/4-implementation/bmad-code-review/review-prompts/verification-gap.md +2 -3
  6. package/src/bmm-skills/4-implementation/bmad-code-review/steps/step-02-review.md +1 -1
  7. package/src/bmm-skills/4-implementation/bmad-dev-auto/customize.toml +31 -22
  8. package/src/bmm-skills/4-implementation/bmad-dev-auto/review-prompts/adversarial.md +3 -4
  9. package/src/bmm-skills/4-implementation/bmad-dev-auto/review-prompts/edge-case-hunter.md +3 -5
  10. package/src/bmm-skills/4-implementation/bmad-dev-auto/review-prompts/verification-gap.md +2 -3
  11. package/src/bmm-skills/4-implementation/bmad-dev-auto/step-04-review.md +2 -2
  12. package/src/bmm-skills/4-implementation/bmad-quick-dev/customize.toml +27 -17
  13. package/src/bmm-skills/4-implementation/bmad-quick-dev/render.py +35 -3
  14. package/src/bmm-skills/4-implementation/bmad-quick-dev/review-prompts/adversarial.md +3 -4
  15. package/src/bmm-skills/4-implementation/bmad-quick-dev/review-prompts/edge-case-hunter.md +3 -5
  16. package/src/bmm-skills/4-implementation/bmad-quick-dev/review-prompts/verification-gap.md +2 -3
  17. package/src/bmm-skills/4-implementation/bmad-quick-dev/step-04-review.md +2 -2
  18. package/src/bmm-skills/4-implementation/bmad-quick-dev/step-oneshot.md +2 -2
  19. package/src/bmm-skills/v6-shims/README.md +5 -4
  20. package/src/bmm-skills/{4-implementation → v6-shims}/bmad-create-story/SKILL.md +3 -1
  21. package/src/bmm-skills/{4-implementation → v6-shims}/bmad-dev-story/SKILL.md +3 -1
  22. package/src/scripts/__pycache__/config_utils.cpython-311.pyc +0 -0
  23. package/src/scripts/tests/__pycache__/test_config_utils.cpython-311.pyc +0 -0
  24. package/src/scripts/tests/__pycache__/test_resolve_config.cpython-311.pyc +0 -0
  25. package/src/scripts/tests/__pycache__/test_resolve_customization.cpython-311.pyc +0 -0
  26. package/tools/validate-published-implementation-model.mjs +65 -0
  27. /package/src/bmm-skills/{4-implementation → v6-shims}/bmad-create-story/checklist.md +0 -0
  28. /package/src/bmm-skills/{4-implementation → v6-shims}/bmad-create-story/customize.toml +0 -0
  29. /package/src/bmm-skills/{4-implementation → v6-shims}/bmad-create-story/discover-inputs.md +0 -0
  30. /package/src/bmm-skills/{4-implementation → v6-shims}/bmad-create-story/template.md +0 -0
  31. /package/src/bmm-skills/{4-implementation → v6-shims}/bmad-dev-story/checklist.md +0 -0
  32. /package/src/bmm-skills/{4-implementation → v6-shims}/bmad-dev-story/customize.toml +0 -0
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "bmad-method",
4
- "version": "6.10.1-next.26",
4
+ "version": "6.10.1-next.28",
5
5
  "description": "Breakthrough Method of Agile AI-driven Development",
6
6
  "keywords": [
7
7
  "agile",
@@ -50,39 +50,48 @@ on_complete = ""
50
50
  id = "blind-hunter"
51
51
  name = "Blind Hunter"
52
52
  instruction = """
53
- Read `{skill-root}/review-prompts/adversarial.md` fully and replace its
54
- `{review_content}` placeholder with the following diff:
53
+ Launch a context-free subagent with this prompt:
54
+
55
+ Read `{skill-root}/review-prompts/adversarial.md` completely and follow it as your review instructions.
56
+
57
+ Review content:
55
58
 
56
59
  {diff_output}
57
60
 
58
- Launch a subagent with no prior conversation context using the entire rendered
59
- prompt directly.
61
+ Do not invoke any skill. If the instruction file is unreadable, report that exact failure and stop. Return only the review result.
62
+
60
63
  """
61
64
 
62
65
  [[workflow.review_layers]]
63
66
  id = "edge-case-hunter"
64
67
  name = "Edge Case Hunter"
65
68
  instruction = """
66
- Read `{skill-root}/review-prompts/edge-case-hunter.md` fully and replace its
67
- `{review_content}` placeholder with the following diff:
69
+ Launch a context-free subagent with this prompt:
70
+
71
+ Read `{skill-root}/review-prompts/edge-case-hunter.md` completely and follow it as your review instructions.
72
+
73
+ Review content:
68
74
 
69
75
  {diff_output}
70
76
 
71
- Launch a subagent with no prior conversation context using the entire rendered
72
- prompt directly.
77
+ Do not invoke any skill. If the instruction file is unreadable, report that exact failure and stop. Return only the review result.
78
+
73
79
  """
74
80
 
75
81
  [[workflow.review_layers]]
76
82
  id = "verification-gap"
77
83
  name = "Verification Gap Reviewer"
78
84
  instruction = """
79
- Read `{skill-root}/review-prompts/verification-gap.md` fully and replace its
80
- `{review_content}` placeholder with the following diff:
85
+ Launch a context-free subagent with this prompt:
86
+
87
+ Read `{skill-root}/review-prompts/verification-gap.md` completely and follow it as your review instructions.
88
+
89
+ Review content:
81
90
 
82
91
  {diff_output}
83
92
 
84
- Launch a subagent with no prior conversation context using the entire rendered
85
- prompt directly.
93
+ Do not invoke any skill. If the instruction file is unreadable, report that exact failure and stop. Return only the review result.
94
+
86
95
  """
87
96
 
88
97
  [[workflow.review_layers]]
@@ -90,10 +99,11 @@ id = "acceptance-auditor"
90
99
  name = "Acceptance Auditor"
91
100
  when = 'Only when {review_mode} = "full".'
92
101
  instruction = """
93
- Launch a subagent with no prior conversation context, with this prompt:
102
+ Launch a subagent with this prompt:
94
103
 
95
- > You are an Acceptance Auditor. Review the provided diff against `{spec_file}` and any loaded 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.
96
- >
97
- > Diff:
98
- > {diff_output}
104
+ You are an Acceptance Auditor. Review the provided diff against `{spec_file}` and any loaded 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.
105
+
106
+ Diff:
107
+
108
+ {diff_output}
99
109
  """
@@ -13,7 +13,7 @@
13
13
 
14
14
  ### Step 1: Receive Content
15
15
 
16
- - Load the content to review from provided input or context
16
+ - Load the content to review from the parent message that launched you (not from this instruction file)
17
17
  - If content to review is empty, ask for clarification and abort
18
18
  - Identify content type (diff, branch, uncommitted changes, document, etc.)
19
19
 
@@ -30,8 +30,7 @@ Output findings as a Markdown list: descriptions only, no severity, priority, or
30
30
 
31
31
  - HALT if zero findings — this is suspicious, re-analyze or ask for guidance
32
32
  - HALT if content is empty or unreadable
33
- ## PROVIDED INPUTS
34
33
 
35
- **content:**
34
+ ## CONTENT SOURCE
36
35
 
37
- {review_content}
36
+ Load the review target from the parent message, or from a trailing `## REVIEW TARGET` section if present (offline fallback). This file has no `{review_content}` slot. If neither supplies content, treat content as empty and follow the empty-content halt rules above.
@@ -19,7 +19,7 @@ A brief secondary deletion check runs as Step 4 when the diff removes code.
19
19
 
20
20
  ### Step 1: Receive Content
21
21
 
22
- - Load the content to review strictly from provided input
22
+ - Load the content to review strictly from the parent message that launched you (not from this instruction file)
23
23
  - If content is empty, or cannot be decoded as text, return `[{"location":"N/A","trigger_condition":"Input empty or undecodable","guard_snippet":"Provide valid content to review","potential_consequence":"Review skipped — no analysis performed"}]` and stop
24
24
  - Identify content type (diff, full file, or function) to determine scope rules
25
25
 
@@ -83,8 +83,6 @@ For a deletion finding the standard fields read as: `location` = the removed ite
83
83
  Add nothing if nothing qualifies.
84
84
  </reference>
85
85
 
86
- ## PROVIDED INPUTS
86
+ ## CONTENT SOURCE
87
87
 
88
- **content:**
89
-
90
- {review_content}
88
+ Load the review target from the parent message, or from a trailing `## REVIEW TARGET` section if present (offline fallback). This file has no `{review_content}` slot. If neither supplies content, treat content as empty and follow the empty-content halt rules above.
@@ -99,8 +99,7 @@ If you noticed genuine non-gap problems while tracing verification, append:
99
99
  When you find no verification gaps and no other findings, output exactly this single line, not an empty response:
100
100
 
101
101
  `No verification gaps found.`
102
- ## PROVIDED INPUTS
103
102
 
104
- **content:**
103
+ ## CONTENT SOURCE
105
104
 
106
- {review_content}
105
+ Load the change set from the parent message, or from a trailing `## REVIEW TARGET` section if present (offline fallback). This file has no `{review_content}` slot. If neither supplies a change set, stop with exactly: `No verification gaps found.`
@@ -21,7 +21,7 @@ failed_layers: '' # set at runtime: comma-separated list of layers that failed o
21
21
 
22
22
  If no layer is active, HALT with status `blocked` and blocking condition `no active review layers`.
23
23
 
24
- 3. Execute all active layers in parallel wherever their execution methods allow: substitute the runtime placeholders (`{diff_output}`, `{spec_file}`) into each layer's `instruction`, then follow it verbatim. If a layer's instruction requires subagents and subagents are not available, generate prompt files in `{implementation_artifacts}` for each such layer and HALT. Ask the user to run each in a separate session (ideally a different LLM) and paste back the findings. When findings are pasted, treat them as those layers' findings and resume from this point.
24
+ 3. Execute all active layers in parallel wherever their execution methods allow: expand `{skill-root}` in each layer's `instruction` to this skill's absolute installed directory, then substitute the runtime placeholders (`{diff_output}`, `{spec_file}`). For an instruction that launches a reviewer subagent, launch that child with the prompt text after placeholder substitution; do not load the reviewer instruction file yourself. For any other customized instruction, execute it as written. Do not leave `{skill-root}` unresolved in a child prompt. If a layer's instruction requires subagents and subagents are not available, for each such layer read its reviewer instruction file, write a self-contained prompt under `{implementation_artifacts}` (full instruction body + `## REVIEW TARGET` with the review content — not a path-only pointer), then HALT. Ask the user to run each in a separate session (ideally a different LLM) and paste back the findings. When findings are pasted, treat them as those layers' findings and resume from this point. This is the only allowed parent-side read of a reviewer instruction file.
25
25
 
26
26
  4. **Layer failure handling**: If any layer fails, times out, or returns empty results, append the layer's `name` to `{failed_layers}` (comma-separated) and proceed with findings from the remaining layers.
27
27
 
@@ -55,54 +55,63 @@ Launch a subagent with no prior conversation context, with this prompt:
55
55
  id = "blind-hunter"
56
56
  name = "Blind Hunter"
57
57
  instruction = """
58
- Read `{skill-root}/review-prompts/adversarial.md` fully and replace its
59
- `{review_content}` placeholder with the following diff:
58
+ Launch a context-free subagent with this prompt:
59
+
60
+ Read `{skill-root}/review-prompts/adversarial.md` completely and follow it as your review instructions.
61
+
62
+ Review content:
60
63
 
61
64
  {diff_output}
62
65
 
63
- Launch a subagent with no prior conversation context using the entire rendered
64
- prompt directly.
66
+ Do not invoke any skill. If the instruction file is unreadable, report that exact failure and stop. Return only the review result.
67
+
65
68
  """
66
69
 
67
70
  [[workflow.review_layers]]
68
71
  id = "edge-case-hunter"
69
72
  name = "Edge Case Hunter"
70
73
  instruction = """
71
- Read `{skill-root}/review-prompts/edge-case-hunter.md` fully and replace its
72
- `{review_content}` placeholder with the following diff:
74
+ Launch a context-free subagent with this prompt:
75
+
76
+ Read `{skill-root}/review-prompts/edge-case-hunter.md` completely and follow it as your review instructions.
77
+
78
+ Review content:
73
79
 
74
80
  {diff_output}
75
81
 
76
- Launch a subagent with no prior conversation context using the entire rendered
77
- prompt directly.
82
+ Do not invoke any skill. If the instruction file is unreadable, report that exact failure and stop. Return only the review result.
83
+
78
84
  """
79
85
 
80
86
  [[workflow.review_layers]]
81
87
  id = "verification-gap"
82
88
  name = "Verification Gap Reviewer"
83
89
  instruction = """
84
- Read `{skill-root}/review-prompts/verification-gap.md` fully and replace its
85
- `{review_content}` placeholder with the following diff:
90
+ Launch a context-free subagent with this prompt:
91
+
92
+ Read `{skill-root}/review-prompts/verification-gap.md` completely and follow it as your review instructions.
93
+
94
+ Review content:
86
95
 
87
96
  {diff_output}
88
97
 
89
- Launch a subagent with no prior conversation context using the entire rendered
90
- prompt directly.
98
+ Do not invoke any skill. If the instruction file is unreadable, report that exact failure and stop. Return only the review result.
99
+
91
100
  """
92
101
 
93
102
  [[workflow.review_layers]]
94
103
  id = "intent-alignment"
95
104
  name = "Intent Alignment Auditor"
96
105
  instruction = """
97
- Launch a subagent with no prior conversation context, with this prompt:
106
+ Launch a subagent with this prompt:
98
107
 
99
- > You are an intent-alignment auditor. You have no other context about how this change was produced. Here is the verbatim intent this work started from:
100
- >
101
- > {verbatim_intent}
102
- >
103
- > Here is the diff:
104
- >
105
- > {diff_output}
106
- >
107
- > Your task is strictly descriptive — do not prescribe additional work. Report: (1) the defensible readings of the intent, enumerated; (2) which reading this diff implements; (3) where the readings and the diff diverge — specifically, which surface the intent's expectations live at versus which surface the diff's changes and its tests exercise.
108
+ You are an intent-alignment auditor. You have no other context about how this change was produced. Here is the verbatim intent this work started from:
109
+
110
+ {verbatim_intent}
111
+
112
+ Here is the diff:
113
+
114
+ {diff_output}
115
+
116
+ Your task is strictly descriptive — do not prescribe additional work. Report: (1) the defensible readings of the intent, enumerated; (2) which reading this diff implements; (3) where the readings and the diff diverge — specifically, which surface the intent's expectations live at versus which surface the diff's changes and its tests exercise.
108
117
  """
@@ -13,7 +13,7 @@
13
13
 
14
14
  ### Step 1: Receive Content
15
15
 
16
- - Load the content to review from provided input or context
16
+ - Load the content to review from the parent message that launched you (not from this instruction file)
17
17
  - If content to review is empty, ask for clarification and abort
18
18
  - Identify content type (diff, branch, uncommitted changes, document, etc.)
19
19
 
@@ -30,8 +30,7 @@ Output findings as a Markdown list: descriptions only, no severity, priority, or
30
30
 
31
31
  - HALT if zero findings — this is suspicious, re-analyze or ask for guidance
32
32
  - HALT if content is empty or unreadable
33
- ## PROVIDED INPUTS
34
33
 
35
- **content:**
34
+ ## CONTENT SOURCE
36
35
 
37
- {review_content}
36
+ Load the review target from the parent message, or from a trailing `## REVIEW TARGET` section if present (offline fallback). This file has no `{review_content}` slot. If neither supplies content, treat content as empty and follow the empty-content halt rules above.
@@ -19,7 +19,7 @@ A brief secondary deletion check runs as Step 4 when the diff removes code.
19
19
 
20
20
  ### Step 1: Receive Content
21
21
 
22
- - Load the content to review strictly from provided input
22
+ - Load the content to review strictly from the parent message that launched you (not from this instruction file)
23
23
  - If content is empty, or cannot be decoded as text, return `[{"location":"N/A","trigger_condition":"Input empty or undecodable","guard_snippet":"Provide valid content to review","potential_consequence":"Review skipped — no analysis performed"}]` and stop
24
24
  - Identify content type (diff, full file, or function) to determine scope rules
25
25
 
@@ -83,8 +83,6 @@ For a deletion finding the standard fields read as: `location` = the removed ite
83
83
  Add nothing if nothing qualifies.
84
84
  </reference>
85
85
 
86
- ## PROVIDED INPUTS
86
+ ## CONTENT SOURCE
87
87
 
88
- **content:**
89
-
90
- {review_content}
88
+ Load the review target from the parent message, or from a trailing `## REVIEW TARGET` section if present (offline fallback). This file has no `{review_content}` slot. If neither supplies content, treat content as empty and follow the empty-content halt rules above.
@@ -99,8 +99,7 @@ If you noticed genuine non-gap problems while tracing verification, append:
99
99
  When you find no verification gaps and no other findings, output exactly this single line, not an empty response:
100
100
 
101
101
  `No verification gaps found.`
102
- ## PROVIDED INPUTS
103
102
 
104
- **content:**
103
+ ## CONTENT SOURCE
105
104
 
106
- {review_content}
105
+ Load the change set from the parent message, or from a trailing `## REVIEW TARGET` section if present (offline fallback). This file has no `{review_content}` slot. If neither supplies a change set, stop with exactly: `No verification gaps found.`
@@ -18,9 +18,9 @@ Do NOT `git add` anything — this is read-only inspection.
18
18
 
19
19
  ### Review
20
20
 
21
- Runtime placeholders: `{diff_output}` is the diff constructed above. `{verbatim_intent}` is the invocation intent exactly as this run received it at step-01; if the run started from an existing spec file rather than a fresh intent, it is the spec's `<intent-contract>` block instead.
21
+ Runtime placeholders: `{diff_output}` is the diff constructed above. `{verbatim_intent}` is the invocation intent exactly as this run received it at step-01; if the run started from an existing spec file rather than a fresh intent, it is the spec's `<intent-contract>` block instead. Before launching a layer, expand its skill-root placeholder to this skill's absolute installed directory; never leave that placeholder unresolved in a child prompt.
22
22
 
23
- Execute these review layers in parallel wherever their execution methods allow: substitute the runtime placeholders (e.g. `{diff_output}`) into each layer's instruction, then follow it verbatim. Parallel means several blocking calls awaited together in this turn — never backgrounded or detached, never ending the turn to await results (see workflow.md → Subagents). Spawn every reviewer subagent before reading or reacting to any of their output; begin collection and triage only once all are launched.
23
+ Execute these review layers in parallel wherever their execution methods allow: substitute the runtime placeholders (e.g. `{diff_output}`) into each layer's instruction. When an instruction launches a reviewer subagent, launch that child with the prompt text after placeholder substitution; do not load the reviewer instruction file yourself. For any other customized instruction, execute it as written. Parallel means several blocking calls awaited together in this turn — never backgrounded or detached, never ending the turn to await results (see workflow.md → Subagents). Spawn every reviewer subagent before reading or reacting to any of their output; begin collection and triage only once all are launched.
24
24
 
25
25
  {workflow.review_layers}
26
26
 
@@ -55,39 +55,48 @@ Launch a subagent with no prior conversation context, with this prompt:
55
55
  id = "blind-hunter"
56
56
  name = "Blind Hunter"
57
57
  instruction = """
58
- Read `{skill-root}/review-prompts/adversarial.md` fully and replace its
59
- `{review_content}` placeholder with the following diff:
58
+ Launch a context-free subagent with this prompt:
59
+
60
+ Read `{skill-root}/review-prompts/adversarial.md` completely and follow it as your review instructions.
61
+
62
+ Review content:
60
63
 
61
64
  {diff_output}
62
65
 
63
- Launch a subagent with no prior conversation context using the entire rendered
64
- prompt directly.
66
+ Do not invoke any skill. If the instruction file is unreadable, report that exact failure and stop. Return only the review result.
67
+
65
68
  """
66
69
 
67
70
  [[workflow.review_layers]]
68
71
  id = "edge-case-hunter"
69
72
  name = "Edge Case Hunter"
70
73
  instruction = """
71
- Read `{skill-root}/review-prompts/edge-case-hunter.md` fully and replace its
72
- `{review_content}` placeholder with the following diff:
74
+ Launch a context-free subagent with this prompt:
75
+
76
+ Read `{skill-root}/review-prompts/edge-case-hunter.md` completely and follow it as your review instructions.
77
+
78
+ Review content:
73
79
 
74
80
  {diff_output}
75
81
 
76
- Launch a subagent with no prior conversation context using the entire rendered
77
- prompt directly.
82
+ Do not invoke any skill. If the instruction file is unreadable, report that exact failure and stop. Return only the review result.
83
+
78
84
  """
79
85
 
80
86
  [[workflow.review_layers]]
81
87
  id = "verification-gap"
82
88
  name = "Verification Gap Reviewer"
83
89
  instruction = """
84
- Read `{skill-root}/review-prompts/verification-gap.md` fully and replace its
85
- `{review_content}` placeholder with the following diff:
90
+ Launch a context-free subagent with this prompt:
91
+
92
+ Read `{skill-root}/review-prompts/verification-gap.md` completely and follow it as your review instructions.
93
+
94
+ Review content:
86
95
 
87
96
  {diff_output}
88
97
 
89
- Launch a subagent with no prior conversation context using the entire rendered
90
- prompt directly.
98
+ Do not invoke any skill. If the instruction file is unreadable, report that exact failure and stop. Return only the review result.
99
+
91
100
  """
92
101
 
93
102
  # Review layers for the one-shot route.
@@ -96,11 +105,12 @@ prompt directly.
96
105
  id = "blind-hunter"
97
106
  name = "Blind Hunter"
98
107
  instruction = """
99
- Read `{skill-root}/review-prompts/adversarial.md` fully and replace its
100
- `{review_content}` placeholder with this review target:
108
+ Launch a context-free subagent with this prompt:
109
+
110
+ Read `{skill-root}/review-prompts/adversarial.md` completely and follow it as your review instructions.
111
+
112
+ Review content: the changed files in the current worktree. Inspect them directly before reviewing.
101
113
 
102
- The changed files in the current worktree. Inspect them directly before reviewing.
114
+ Do not invoke any skill. If the instruction file is unreadable, report that exact failure and stop. Return only the review result.
103
115
 
104
- Launch a subagent with no prior conversation context using the entire rendered
105
- prompt directly.
106
116
  """
@@ -21,8 +21,10 @@ Customization: three-layer merge of {skill}/customize.toml +
21
21
  _bmad/custom/bmad-quick-dev.toml + .user.toml (same structural rules as
22
22
  resolve_customization.py). The resolved [workflow] values fill {workflow.*}
23
23
  placeholders, so this skill needs no runtime resolve_customization.py call.
24
- Other single-curly placeholders ({project-root}, {spec_file}, {skill-root},
25
- ...) pass through untouched for the LLM to resolve during workflow execution.
24
+ Other single-curly placeholders ({project-root}, {spec_file}, ...) pass
25
+ through untouched for the LLM to resolve during workflow execution. The sole
26
+ exception is {skill-root} in resolved review-layer instructions, which must be
27
+ an absolute prompt-file path before those instructions reach the parent LLM.
26
28
 
27
29
  Every invocation rebuilds from scratch — no hash, no cache.
28
30
  Python 3.11+ stdlib only. UTF-8 I/O.
@@ -242,6 +244,34 @@ def _scalar_str(value):
242
244
  _REVIEW_LAYER_KEYS = ("review_layers", "oneshot_review_layers")
243
245
 
244
246
 
247
+ def expand_review_layer_skill_roots(workflow, skill_root):
248
+ """Expand only {skill-root} inside resolved review-layer instructions.
249
+
250
+ Review layers originate in customization after regular template rendering,
251
+ so their prompt paths need this explicit pass. Runtime placeholders remain
252
+ untouched for the parent to supply to each child at dispatch time.
253
+ """
254
+ expanded_workflow = dict(workflow)
255
+ for key in _REVIEW_LAYER_KEYS:
256
+ layers = workflow.get(key)
257
+ if not isinstance(layers, list):
258
+ continue
259
+ expanded_layers = []
260
+ for layer in layers:
261
+ if not isinstance(layer, dict):
262
+ expanded_layers.append(layer)
263
+ continue
264
+ expanded_layer = dict(layer)
265
+ instruction = expanded_layer.get("instruction")
266
+ if isinstance(instruction, str):
267
+ expanded_layer["instruction"] = instruction.replace(
268
+ "{skill-root}", skill_root
269
+ )
270
+ expanded_layers.append(expanded_layer)
271
+ expanded_workflow[key] = expanded_layers
272
+ return expanded_workflow
273
+
274
+
245
275
  def _render_review_layers(layers):
246
276
  """Materialize review layers into direct invocation blocks. A layer with an
247
277
  empty or missing instruction is disabled (that is how an override turns off
@@ -359,7 +389,9 @@ def main():
359
389
  )
360
390
  sys.exit(1)
361
391
 
362
- workflow = resolve_workflow(root, script_dir.replace(os.sep, "/"), skill_name)
392
+ skill_dir = script_dir.replace(os.sep, "/")
393
+ workflow = resolve_workflow(root, skill_dir, skill_name)
394
+ workflow = expand_review_layer_skill_roots(workflow, skill_dir)
363
395
 
364
396
  out_dir = posixpath.join(root, "_bmad", "render", skill_name)
365
397
  os.makedirs(out_dir, exist_ok=True)
@@ -13,7 +13,7 @@
13
13
 
14
14
  ### Step 1: Receive Content
15
15
 
16
- - Load the content to review from provided input or context
16
+ - Load the content to review from the parent message that launched you (not from this instruction file)
17
17
  - If content to review is empty, ask for clarification and abort
18
18
  - Identify content type (diff, branch, uncommitted changes, document, etc.)
19
19
 
@@ -30,8 +30,7 @@ Output findings as a Markdown list: descriptions only, no severity, priority, or
30
30
 
31
31
  - HALT if zero findings — this is suspicious, re-analyze or ask for guidance
32
32
  - HALT if content is empty or unreadable
33
- ## PROVIDED INPUTS
34
33
 
35
- **content:**
34
+ ## CONTENT SOURCE
36
35
 
37
- {review_content}
36
+ Load the review target from the parent message, or from a trailing `## REVIEW TARGET` section if present (offline fallback). This file has no `{review_content}` slot. If neither supplies content, treat content as empty and follow the empty-content halt rules above.
@@ -19,7 +19,7 @@ A brief secondary deletion check runs as Step 4 when the diff removes code.
19
19
 
20
20
  ### Step 1: Receive Content
21
21
 
22
- - Load the content to review strictly from provided input
22
+ - Load the content to review strictly from the parent message that launched you (not from this instruction file)
23
23
  - If content is empty, or cannot be decoded as text, return `[{"location":"N/A","trigger_condition":"Input empty or undecodable","guard_snippet":"Provide valid content to review","potential_consequence":"Review skipped — no analysis performed"}]` and stop
24
24
  - Identify content type (diff, full file, or function) to determine scope rules
25
25
 
@@ -83,8 +83,6 @@ For a deletion finding the standard fields read as: `location` = the removed ite
83
83
  Add nothing if nothing qualifies.
84
84
  </reference>
85
85
 
86
- ## PROVIDED INPUTS
86
+ ## CONTENT SOURCE
87
87
 
88
- **content:**
89
-
90
- {review_content}
88
+ Load the review target from the parent message, or from a trailing `## REVIEW TARGET` section if present (offline fallback). This file has no `{review_content}` slot. If neither supplies content, treat content as empty and follow the empty-content halt rules above.
@@ -99,8 +99,7 @@ If you noticed genuine non-gap problems while tracing verification, append:
99
99
  When you find no verification gaps and no other findings, output exactly this single line, not an empty response:
100
100
 
101
101
  `No verification gaps found.`
102
- ## PROVIDED INPUTS
103
102
 
104
- **content:**
103
+ ## CONTENT SOURCE
105
104
 
106
- {review_content}
105
+ Load the change set from the parent message, or from a trailing `## REVIEW TARGET` section if present (offline fallback). This file has no `{review_content}` slot. If neither supplies a change set, stop with exactly: `No verification gaps found.`
@@ -18,11 +18,11 @@ Do NOT `git add` anything — this is read-only inspection.
18
18
 
19
19
  ### Review
20
20
 
21
- Execute these review layers in parallel wherever their execution methods allow: substitute the runtime placeholders (e.g. `{diff_output}`) into each layer's instruction, then follow it verbatim. Parallel means several blocking calls awaited together in this turn — never backgrounded or detached, never ending the turn to await results. When running layers as subagents, spawn every reviewer before reading or reacting to any of their output; begin collection and triage only once all are launched.
21
+ Execute these review layers in parallel wherever their execution methods allow: substitute the runtime placeholders (e.g. `{diff_output}`) into each layer's instruction. When an instruction launches a reviewer subagent, launch that child with the prompt text after placeholder substitution; do not load the reviewer instruction file yourself. For any other customized instruction, execute it as written. Parallel means several blocking calls awaited together in this turn — never backgrounded or detached, never ending the turn to await results. When running layers as subagents, spawn every reviewer before reading or reacting to any of their output; begin collection and triage only once all are launched.
22
22
 
23
23
  {workflow.review_layers}
24
24
 
25
- If a layer's instruction requires subagents and none are available, generate one review prompt file per such layer in `{{.implementation_artifacts}}` and HALT. Ask the human to run each in a separate session (ideally a different LLM) and paste back the findings.
25
+ If a layer's instruction requires subagents and none are available, for each such layer read its reviewer instruction file, write a self-contained prompt under `{{.implementation_artifacts}}` (full instruction body + `## REVIEW TARGET` with the review content — not a path-only pointer), then HALT. Ask the human to run each in a separate session (ideally a different LLM) and paste back the findings. This is the only allowed parent-side read of a reviewer instruction file.
26
26
 
27
27
  ### Classify
28
28
 
@@ -17,11 +17,11 @@ Implement the clarified intent directly.
17
17
 
18
18
  ### Review
19
19
 
20
- Execute these review layers in parallel wherever their execution methods allow, following each layer's instruction verbatim after substituting any runtime placeholders:
20
+ Execute these review layers in parallel wherever their execution methods allow. After substituting runtime placeholders, when an instruction launches a reviewer subagent, launch that child with the prompt text; do not load the reviewer instruction file yourself. For any other customized instruction, execute it as written:
21
21
 
22
22
  {workflow.oneshot_review_layers}
23
23
 
24
- If a layer's instruction requires subagents and none are available, generate one review prompt file per such layer in `{{.implementation_artifacts}}` and HALT. Ask the human to run each in a separate session and paste back the findings.
24
+ If a layer's instruction requires subagents and none are available, for each such layer read its reviewer instruction file, write a self-contained prompt under `{{.implementation_artifacts}}` (full instruction body + `## REVIEW TARGET` with the review content — not a path-only pointer), then HALT. Ask the human to run each in a separate session and paste back the findings. This is the only allowed parent-side read of a reviewer instruction file.
25
25
 
26
26
  ### Classify
27
27
 
@@ -1,12 +1,13 @@
1
1
  # v6 Deprecation Shims
2
2
 
3
- Skills in this folder are forwarders kept for backward compatibility with v6 skill IDs.
4
- Each one holds no logic of its own — it forwards to the skill that replaced it, passing a
5
- stated intent and pre-resolved customization fields so the target skips its own intent
6
- inference.
3
+ Skills in this folder are deprecated skills kept for backward compatibility with v6 skill IDs.
4
+ Some retain their full workflow, while others forward to the skill that replaced them, passing a
5
+ stated intent and pre-resolved customization fields so the target skips its own intent inference.
7
6
 
8
7
  | Shim | Forwards to |
9
8
  | -------------------------- | ------------------------------------ |
9
+ | `bmad-create-story` | Retained in full |
10
+ | `bmad-dev-story` | Retained in full |
10
11
  | `bmad-create-prd` | `bmad-prd` (create intent) |
11
12
  | `bmad-edit-prd` | `bmad-prd` (update intent) |
12
13
  | `bmad-validate-prd` | `bmad-prd` (validate intent) |
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: bmad-create-story
3
- description: 'Creates a dedicated story file with all the context the agent will need to implement it later. Use when the user says "create the next story" or "create story [story identifier]"'
3
+ description: "Deprecated: `bmad-quick-dev` is now the official implementation method. Only use this when explicitly invoked by name."
4
4
  ---
5
5
 
6
6
  # Create Story Workflow
@@ -62,6 +62,8 @@ Load config from `{project-root}/_bmad/bmm/config.yaml` and resolve:
62
62
 
63
63
  Greet `{user_name}`, speaking in `{communication_language}`.
64
64
 
65
+ <output>Deprecated: `bmad-quick-dev` is now the official implementation method. Only use this when explicitly invoked by name.</output>
66
+
65
67
  ### Step 6: Execute Append Steps
66
68
 
67
69
  Execute each entry in `{workflow.activation_steps_append}` in order.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: bmad-dev-story
3
- description: 'Execute story implementation following a context filled story spec file. Use when the user says "dev this story [story file]" or "implement the next story in the sprint plan"'
3
+ description: "Deprecated: `bmad-quick-dev` is now the official implementation method. Only use this when explicitly invoked by name."
4
4
  ---
5
5
 
6
6
  # Dev Story Workflow
@@ -60,6 +60,8 @@ Load config from `{project-root}/_bmad/bmm/config.yaml` and resolve:
60
60
 
61
61
  Greet `{user_name}`, speaking in `{communication_language}`.
62
62
 
63
+ <output>Deprecated: `bmad-quick-dev` is now the official implementation method. Only use this when explicitly invoked by name.</output>
64
+
63
65
  ### Step 6: Execute Append Steps
64
66
 
65
67
  Execute each entry in `{workflow.activation_steps_append}` in order.
@@ -0,0 +1,65 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+
4
+ const CANONICAL_LLMS_ENTRY = '**[Quick Dev]';
5
+ const CANONICAL_LLMS_DESCRIPTION = 'Canonical implementation workflow for direct intent and fully planned work';
6
+
7
+ const FORBIDDEN_TERMS = [
8
+ /\bbmad-(?:create|dev)-story\b/gi,
9
+ /\b(?:create-story|dev-story)\b/gi,
10
+ /\b(?:Create Story|Dev Story)\b/g,
11
+ /\b(?:createStory|devStory|create_story|dev_story)\b/g,
12
+ /\bquick[ -]?flow\b/gi,
13
+ /flux rapide|parcours parallèle/gi,
14
+ /paralelní cesta/gi,
15
+ /luồng nhanh|nhánh nhanh/gi,
16
+ /快速流程|并行快线/g,
17
+ ];
18
+
19
+ export function validatePublishedImplementationModel(siteDir) {
20
+ const findings = findObsoleteImplementationTerms(siteDir);
21
+ if (findings.length > 0) {
22
+ const details = findings.map(({ file, line, match }) => `${file}:${line}: ${match}`).join('\n ');
23
+ throw new Error(`Obsolete implementation terminology found in deployable documentation:\n ${details}`);
24
+ }
25
+
26
+ const llmsPath = path.join(siteDir, 'llms.txt');
27
+ const llmsContent = fs.readFileSync(llmsPath, 'utf-8');
28
+ if (!llmsContent.includes(CANONICAL_LLMS_ENTRY) || !llmsContent.includes(CANONICAL_LLMS_DESCRIPTION)) {
29
+ throw new Error('llms.txt must describe Quick Dev as canonical for both direct intent and fully planned work');
30
+ }
31
+ }
32
+
33
+ export function findObsoleteImplementationTerms(siteDir) {
34
+ const findings = [];
35
+
36
+ for (const filePath of getPublishedTextFiles(siteDir)) {
37
+ const content = fs.readFileSync(filePath, 'utf-8');
38
+ for (const pattern of FORBIDDEN_TERMS) {
39
+ for (const match of content.matchAll(pattern)) {
40
+ findings.push({
41
+ file: path.relative(siteDir, filePath),
42
+ line: content.slice(0, match.index).split('\n').length,
43
+ match: match[0],
44
+ });
45
+ }
46
+ }
47
+ }
48
+
49
+ return findings;
50
+ }
51
+
52
+ function getPublishedTextFiles(dir) {
53
+ const files = [];
54
+
55
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
56
+ const fullPath = path.join(dir, entry.name);
57
+ if (entry.isDirectory()) {
58
+ files.push(...getPublishedTextFiles(fullPath));
59
+ } else if (/\.(?:html|txt|xml|json|svg)$/i.test(entry.name)) {
60
+ files.push(fullPath);
61
+ }
62
+ }
63
+
64
+ return files;
65
+ }