bmad-method 6.10.1-next.8 → 6.10.1-next.9

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.
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.8",
4
+ "version": "6.10.1-next.9",
5
5
  "description": "Breakthrough Method of Agile AI-driven Development",
6
6
  "keywords": [
7
7
  "agile",
@@ -13,18 +13,38 @@ description: 'One iteration of an unattended development loop. Use when invoked
13
13
 
14
14
  To HALT with a final status and optional blocking condition:
15
15
 
16
- 1. If `{spec_file}` is known and exists, update `status` in frontmatter and append missing result details under `## Auto Run Result`.
17
- 2. If `{spec_file}` is unknown or missing, create `{implementation_artifacts}/bmad-dev-auto-result-<slug-or-timestamp>.md` with:
18
- ```markdown
19
- ---
20
- status: <final status>
21
- ---
22
-
23
- # BMad Dev Auto Result
24
-
25
- Status: <final status>
26
- Blocking condition: <blocking condition, if any>
27
- ```
16
+ 1. **Folder+id dispatch** (`{spec_folder}` and `{story_id}` are set): the write-back always lands at the id-keyed story spec. The `{implementation_artifacts}` fallback in step 2 below is never used in this mode, even for halts before planning starts.
17
+ - If `{spec_file}` is still empty, resolve it now:
18
+ - **Entry not resolved** (`stories.yaml` is missing/unparseable, or `{story_id}` has no matching entry): use the fixed slug segment `unresolved`: `{spec_file}` = `{spec_folder}/stories/{story_id}-unresolved.md`.
19
+ - **Ambiguous on-disk match** (the halt is `ambiguous story file match` — more than one file already matches `{spec_folder}/stories/{story_id}-*.md`): use the fixed slug segment `ambiguous` instead of deriving from the title, so the write-back neither creates a third title-derived candidate nor risks silently landing on one of the existing ambiguous files: `{spec_file}` = `{spec_folder}/stories/{story_id}-ambiguous.md`.
20
+ - **Otherwise** (the entry was resolved and no ambiguous on-disk match exists): derive `{spec_file}` = `{spec_folder}/stories/{story_id}-{slug}.md`, where `{slug}` is a kebab-case slug from `title` (and `description` if needed) with no `{story_id}` prefix — the same derivation step-01's Route uses.
21
+ - If `{spec_file}` exists on disk, update `status` in frontmatter and append missing result details under `## Auto Run Result`.
22
+ - If it does not exist, create it as a skeletal story spec:
23
+ ```markdown
24
+ ---
25
+ status: <final status>
26
+ ---
27
+
28
+ # <entry title, or "Story {story_id}" if the entry could not be resolved or the on-disk match was ambiguous>
29
+
30
+ ## Auto Run Result
31
+
32
+ Status: <final status>
33
+ Blocking condition: <blocking condition, if any>
34
+ ```
35
+ 2. **Otherwise:**
36
+ - If `{spec_file}` is known and exists, update `status` in frontmatter and append missing result details under `## Auto Run Result`.
37
+ - If `{spec_file}` is unknown or missing, create `{implementation_artifacts}/bmad-dev-auto-result-<slug-or-timestamp>.md` with:
38
+ ```markdown
39
+ ---
40
+ status: <final status>
41
+ ---
42
+
43
+ # BMad Dev Auto Result
44
+
45
+ Status: <final status>
46
+ Blocking condition: <blocking condition, if any>
47
+ ```
28
48
  3. Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete`
29
49
  4. If the resolved `workflow.on_complete` is non-empty, follow it as the final instruction before exiting.
30
50
  5. Stop the workflow.
@@ -1,6 +1,8 @@
1
1
  ---
2
2
  deferred_work_file: '{implementation_artifacts}/deferred-work.md'
3
- spec_file: '' # set at runtime for both routes before leaving this step
3
+ spec_file: '' # set at runtime once a route resolves it; some HALT branches exit before it is set
4
+ spec_folder: '' # set at runtime under folder+id dispatch only
5
+ story_id: '' # set at runtime under folder+id dispatch only
4
6
  ---
5
7
 
6
8
  # Step 1: Clarify and Route
@@ -22,6 +24,20 @@ If the invocation prompt explicitly points to an existing spec file with recogni
22
24
  - `blocked` → HALT with status `blocked` and blocking condition `blocked spec supplied`.
23
25
  - `done` → set `review_loop_iteration` to `0` in the frontmatter, then **EARLY EXIT** to `./step-04-review.md` for a fresh review pass. (A `done` spec is a completed run, so this starts a follow-up review, not a resumption.)
24
26
 
27
+ If the invocation prompt instead supplies a spec folder and a story id, with no specific spec file path, this is a **folder+id dispatch**: set `spec_folder` (a `{project-root}`-relative or absolute path) and `story_id` from the prompt. Any further prompt text (e.g. `invoke_dev_with` guidance the caller appended) is additional planning context to carry into step-02 — not a competing description of what to implement.
28
+
29
+ Read `{spec_folder}/stories.yaml`. If the file does not exist or fails to parse, HALT with status `blocked` and blocking condition `no stories.yaml found`. Find the entry whose `id` equals `{story_id}`; if none matches, HALT with status `blocked` and blocking condition `story id not found in stories.yaml`. Take only that entry's `title` and `description` — never read the checkpoint fields or `invoke_dev_with`; those are the caller's orchestration fields, not dev-auto's.
30
+
31
+ Look for files matching `{spec_folder}/stories/{story_id}-*.md` (id-prefix match — story ids are prefix-free, so at most one should match):
32
+ - **If more than one matches**, HALT with status `blocked` and blocking condition `ambiguous story file match`.
33
+ - **If exactly one matches**, set `spec_file` to that path.
34
+ - `draft` (planning was interrupted mid-flight): accumulate cross-story context before resuming — load every other file matching `{spec_folder}/stories/*.md` (every match except `{spec_file}` itself), regardless of `status`, and carry forward each one's **Code Map**, **Design Notes**, **Spec Change Log**, **Tasks & Acceptance** checklist state, and **Auto Run Result** details, where present, as additional planning context for step-02. Then **EARLY EXIT** to `./step-02-plan.md`.
35
+ - Any other recognized `status`: **EARLY EXIT** using the same routing as above, including the `review_loop_iteration` reset for `done`. One difference: a `blocked` story HALTs with blocking condition `story already blocked`, not `blocked spec supplied` — the caller did not supply this file; dev-auto found it by id.
36
+ - `status` missing or unrecognized: HALT with status `blocked` and blocking condition `unrecognized status in existing story file`.
37
+ - **If none matches**, this is the first dispatch for `{story_id}`. The entry's `title` and `description` are the resolved intent. If `{spec_folder}/SPEC.md` does not exist, HALT with status `blocked` and blocking condition `no epic spec found`. Otherwise load it and the files listed in its `companions:` frontmatter as planning context, then accumulate cross-story context the same way as the `draft` case above — load every file matching `{spec_folder}/stories/*.md` (none yet exists for `{story_id}` at this point, so nothing is excluded), regardless of `status`, carrying forward the same fields, where present, as additional planning context for step-02. Then continue to INSTRUCTIONS item 3 below — not `step-03-implement.md`, item 3 of the numbered list in this file (items 1 and 2 do not apply — context and intent are already resolved; item 1.A.5's previous-story continuity scan in particular never runs here, since folder+id dispatch already skips items 1 and 2 entirely — the cross-story accumulation above is its replacement for this dispatch mode).
38
+
39
+ One `stories.yaml` entry per invocation: never read another entry, and never advance to a different story id regardless of outcome.
40
+
25
41
  Otherwise, treat the invocation prompt as starting intent. This may be a story ID, ticket ID, file path, short description, or longer free-form intent. Do not infer workflow state from non-spec files.
26
42
  If the invocation prompt does not contain enough intent to identify what to implement, HALT with status `blocked` and blocking condition `unclear intent`.
27
43
 
@@ -55,11 +71,13 @@ If the invocation prompt does not contain enough intent to identify what to impl
55
71
  - **Product Brief** (`*brief*`) — project vision and scope
56
72
  - Scan the listing for files matching these patterns. If any look relevant to the current intent, load them selectively — you don't need all of them, but you need the right constraints and requirements rather than guessing from code alone.
57
73
  2. Resolve intent from the invocation prompt and loaded artifacts. Do not fantasize or leave open questions. If the intent cannot be resolved, HALT with status `blocked` and the unresolved questions as blocking condition.
58
- 3. Version control sanity check. Is the working tree clean? Does the current branch make sense for this intent — considering its name and recent history? If the tree is dirty or the branch is an obvious mismatch, HALT with status `blocked` and that condition as blocking condition. If version control is unavailable, skip this check.
74
+ 3. Version control sanity check. Is the working tree clean? Does the current branch make sense for this intent — considering its name and recent history? Under folder+id dispatch, judge the branch against the epic spec, not the story title: one branch usually carries all of an epic's stories. If the tree is dirty or the branch is an obvious mismatch, HALT with status `blocked` and that condition as blocking condition. If version control is unavailable, skip this check.
59
75
  4. Multi-goal warning. If the intent appears to contain multiple independently shippable goals, carry `multiple-goals` forward so step-02 can add it to `{spec_file}` frontmatter `warnings`. Do not split or block.
60
76
  5. Route:
61
77
 
62
- Derive a valid kebab-case slug from the clarified intent. If the intent references a tracking identifier (story number, issue number, ticket ID), lead the slug with it (e.g. `3-2-digest-delivery`, `gh-47-fix-auth`). If `{implementation_artifacts}/spec-{slug}.md` already exists: if its status is `draft`, treat it as the same work and resume it (set `spec_file` to that path, **EARLY EXIT** → `./step-02-plan.md`); otherwise append `-2`, `-3`, etc. Set `spec_file` = `{implementation_artifacts}/spec-{slug}.md`.
78
+ **Folder+id dispatch:** derive a valid kebab-case slug from the entry's `title` (and `description` if needed) the same kebab-casing convention as below, but never prefixed with `{story_id}`, since the id is already the filename's separate leading segment. Set `spec_file` = `{spec_folder}/stories/{story_id}-{slug}.md`. The id already disambiguates: no `{implementation_artifacts}` fallback, no `-2`/`-3` suffixing.
79
+
80
+ **Otherwise:** derive a valid kebab-case slug from the clarified intent. If the intent references a tracking identifier (story number, issue number, ticket ID), lead the slug with it (e.g. `3-2-digest-delivery`, `gh-47-fix-auth`). If `{implementation_artifacts}/spec-{slug}.md` already exists: if its status is `draft`, treat it as the same work and resume it (set `spec_file` to that path, **EARLY EXIT** → `./step-02-plan.md`); otherwise append `-2`, `-3`, etc. Set `spec_file` = `{implementation_artifacts}/spec-{slug}.md`.
63
81
 
64
82
  ## NEXT
65
83
 
@@ -23,8 +23,8 @@ deferred_work_file: '{implementation_artifacts}/deferred-work.md'
23
23
  Re-read `./SKILL.md`, then re-read `{spec_file}` from disk and verify the spec meets the READY FOR DEVELOPMENT standard.
24
24
 
25
25
  - **If the file is missing:** HALT with status `blocked` and blocking condition `planned spec file disappeared before implementation`.
26
- - **If the spec meets the standard:** set `{spec_file}` frontmatter status to `ready-for-dev`, then continue to step 3.
27
- - **If the spec does not meet the standard:** repair it once, then re-read it from disk and verify again. If it still does not meet the standard, HALT with status `blocked`, blocking condition `spec failed ready-for-development standard`, and include the failing criteria and evidence gathered.
26
+ - **If the spec meets the standard:** set `{spec_file}` frontmatter status to `ready-for-dev`. If the invocation prompt directs a halt after planning (standard phrasing: `Halt after planning.` — accept any clear equivalent), HALT with status `ready-for-dev`; otherwise continue to step 3.
27
+ - **If the spec does not meet the standard:** repair it once, then re-read it from disk and verify again. If it now meets the standard, apply the **If the spec meets the standard** handling above, including the halt-after-planning check. If it still does not meet the standard, HALT with status `blocked`, blocking condition `spec failed ready-for-development standard`, and include the failing criteria and evidence gathered.
28
28
 
29
29
  ## NEXT
30
30
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: bmad-spec
3
- description: Distill any intent input into the SPEC kernel + companions — the canonical, preservation-validated machine contract for downstream work. Use when the user says "create a spec", "distill this into a spec", "validate this spec", or "update the spec".
3
+ description: Distill any intent input into the SPEC kernel + companions — the canonical, preservation-validated machine contract for downstream work. Use when the user says "create a spec", "distill this into a spec", "validate this spec", "update the spec", or "break this into stories".
4
4
  ---
5
5
 
6
6
  # BMad Spec
@@ -46,6 +46,7 @@ Inside the spec folder:
46
46
  SPEC.md ← uppercase, the kernel — DERIVED from .memlog.md, never hand-edited
47
47
  <companion-1>.md ← optional, content-typed (e.g. glossary.md); spec-authored ones are derived too
48
48
  <companion-2>.md
49
+ stories.yaml ← optional, written only by Story Breakdown — fixed name, never in companions:
49
50
  .memlog.md ← canonical, append-only memory; what SPEC.md is distilled from
50
51
  ```
51
52
 
@@ -99,6 +100,8 @@ Two rules govern companions:
99
100
 
100
101
  Pre-existing project-wide docs (e.g. `project-context.md`) that downstream needs are listed as **adopted companions**, never duplicated into SPEC.md or a spec-authored companion.
101
102
 
103
+ `stories.yaml`, when produced, is spec-authored but deliberately **not** a companion — see Story Breakdown below.
104
+
102
105
  ## Spec Law
103
106
 
104
107
  Every spec must satisfy these eight rules. The operation aims for them; the self-validate sweep enforces them.
@@ -126,9 +129,21 @@ Record the verdict for each pass to `.memlog.md` (`append --type event`). In int
126
129
 
127
130
  When the user points the skill at an existing spec folder (or its SPEC.md) with no change signal, offer to review assumptions or open questions, or determine what they want to do.
128
131
 
132
+ ## Story Breakdown (optional, interactive-only)
133
+
134
+ Requires `SPEC.md` on disk — run the normal Operation first if it doesn't exist yet. Headless runs never do this, even when the invocation text asks for it: if mode detection (On Activation, step 4) resolved headless, skip this section entirely and proceed with the normal headless response. In interactive mode, offer it at most once per run when the input reads as multiple independently shippable slices; a decline ends the offer for this run, not forever. Also run it on direct request ("break this into stories") whenever `SPEC.md` exists. When a spec update runs and `stories.yaml` exists, check the story descriptions against the updated spec; if any no longer matches, say so and offer to re-run Story Breakdown. The update itself never rewrites `stories.yaml`.
135
+
136
+ Either way, walk the capabilities and constraints with the user and propose a story per independently reviewable slice — this is a conversation, not a silent render. For each story, ask the user for `spec_checkpoint`, `done_checkpoint`, and any `invoke_dev_with` note rather than defaulting them silently; capturing that human judgment is what the fields are for. If the conversation surfaces load-bearing detail beyond dispatch notes (a constraint, a design decision), route it into SPEC.md or a companion — `invoke_dev_with` carries dispatch notes only (Spec Law rule 7 still applies).
137
+
138
+ The output is `stories.yaml`, a sibling of `SPEC.md` inside the spec folder, discovered by that fixed name — same convention as `SPEC.md` and `.memlog.md`. Never list it in `companions:` and never point a frontmatter key at it: companions carry the what-to-build contract every consumer reads; `stories.yaml` is input for whichever tool dispatches the stories.
139
+
140
+ Field definitions, the validity rules, and a worked example live in `assets/stories-schema.md`. Before writing or re-writing the file, check every entry against those rules; fix violations rather than presenting a file that fails them. Record the check's verdict to `.memlog.md` (`append --type event`), the same discipline as Self-Validate.
141
+
142
+ Derive `stories.yaml` from `.memlog.md` exactly like any other spec-authored artifact: log each proposed story (`--type decision`) as the user agrees to it, then render. On a later run against the same spec folder, re-derive the same way, handling ids per the schema's update semantics.
143
+
129
144
  ## Output
130
145
 
131
- **Interactive** — share the spec folder path conversationally. Name the capability count, the companions produced, and the verdict in one or two sentences. If `assumptions[]` or `open_questions[]` are non-empty, list them (short — one line each) and invite the user to walk through them. Make clear that addressing them can update the source input (if it was a file), the spec, or both — whichever combination the user prefers. Do not dump JSON or present a wall of output.
146
+ **Interactive** — share the spec folder path conversationally. Name the capability count, the companions produced, and the verdict in one or two sentences. Name the story count too if `stories.yaml` was written this run. If `assumptions[]` or `open_questions[]` are non-empty, list them (short — one line each) and invite the user to walk through them. Make clear that addressing them can update the source input (if it was a file), the spec, or both — whichever combination the user prefers. Do not dump JSON or present a wall of output.
132
147
 
133
148
  **Headless** — return JSON per `assets/headless-schemas.md`.
134
149
 
@@ -0,0 +1,44 @@
1
+ # Stories schema
2
+
3
+ `stories.yaml` — the optional output of Story Breakdown: a top-level YAML list, one entry per story, in execution order — stories run top to bottom. Sibling of `SPEC.md`, discovered by its fixed filename (same convention as `SPEC.md` and `.memlog.md`); never listed in `companions:`, never referenced from frontmatter.
4
+
5
+ ## Fields
6
+
7
+ | Field | Type | Required | Meaning |
8
+ |---|---|---|---|
9
+ | `id` | string | yes | Identity, unique within the file. Compared for equality and used as a filename prefix; carries no other meaning. Use unpadded integers (`"1"`), or composites (`"3-2"`) when the epic sits inside a larger project spec. No zero-padding — execution order is the list order, not filename sort. Pinned once the story's spec file exists (see Update semantics); until then it may be renumbered. |
10
+ | `title` | string, one line | yes | Display name; becomes the story's heading downstream. |
11
+ | `description` | string | yes | What this story covers, pointing into `SPEC.md` — not a story spec. Keep it to two sentences; a writing rule, not something tooling enforces. |
12
+ | `spec_checkpoint` | boolean | no (default `false`) | Set by the human at breakdown time; read only by the dispatching caller, never by the implementing dev skill. When true, a human reviews the story spec between planning and implementation. |
13
+ | `done_checkpoint` | boolean | no (default `false`) | Caller-only, like `spec_checkpoint`. When true, dispatch pauses after this story completes, before anything further runs. |
14
+ | `invoke_dev_with` | string | no (default `""`) | Free text appended verbatim to the prompt that dispatches this story; the implementing dev skill reads it as part of its prompt, and nothing else interprets it. If the text needs structure, put it inside the string. Which dev skill to invoke is the caller's configuration, never data in this file. |
15
+
16
+ ## Validity rules
17
+
18
+ 1. Every entry parses with all required fields; ids unique.
19
+ 2. Ids are prefix-free under the `<id>-` filename-matching convention: no id may equal another id plus a dash-suffix (`"3"` and `"3-2"` cannot coexist).
20
+ 3. No `status` field, ever.
21
+ 4. Ids are YAML strings, always quoted, containing only letters, digits, and dashes. An unquoted `id: 1` parses as a number and breaks string comparison; characters like `/` or `*` break the filename match.
22
+
23
+ ## Example
24
+
25
+ ```yaml
26
+ - id: "1"
27
+ title: Add rate limiting to the public API
28
+ description: >-
29
+ Introduce a token-bucket limiter in front of the public endpoints;
30
+ return 429 with a Retry-After header on limit breach.
31
+ spec_checkpoint: true
32
+ invoke_dev_with: >-
33
+ Rate limit state must be shared across instances; use the existing
34
+ Redis client, not in-process memory.
35
+ - id: "2"
36
+ title: Expose limiter metrics to the ops dashboard
37
+ description: >-
38
+ Emit per-route accept/reject counters the existing dashboard can
39
+ scrape; no new dashboard panels in this story.
40
+ ```
41
+
42
+ ## Update semantics
43
+
44
+ Updates to `stories.yaml` go through Story Breakdown: append the change to `.memlog.md`, then re-derive. An id is pinned once its story spec file exists (any `stories/<id>-*.md` in the spec folder): a pinned story keeps its id through edits, its removal retires the id, and retired ids are never reassigned. Stories with no spec file yet may be renumbered, reordered, or removed freely on re-derive — typically so ids keep following list order. Never give a story an id that collides with a `stories/` file belonging to a different story.