diff --git a/docs/reference/dev-auto.md b/docs/reference/dev-auto.md index b90427f9d..a0355c6ac 100644 --- a/docs/reference/dev-auto.md +++ b/docs/reference/dev-auto.md @@ -7,6 +7,8 @@ sidebar: To use BMad in an autonomous development loop, use the `bmad-dev-auto` skill. It is like [Quick Dev](../explanation/quick-dev.md), but designed to keep moving without human interaction. You can use it in an interactive session, but its main purpose is to be used by an orchestrator. +The important architectural boundary is this: `bmad-dev-auto` owns the implementation run and the spec artifact it produces, but it does not own your backlog policy. When review finds something real that is not this story's problem, the skill records that finding in the spec it owns and stops there. Deciding whether to queue it, deduplicate it, escalate it, or ignore it is the orchestrator's responsibility. + ## What It Does `bmad-dev-auto` performs one unattended development-loop iteration: @@ -41,14 +43,14 @@ Supported intent shapes include: If the invocation points to an existing spec file with one of the known `status` values in the frontmatter, the workflow resumes from that state: -| Spec status | Entry point | -| --- | --- | -| `draft` | plan | -| `ready-for-dev` | implement | -| `in-progress` | implement | -| `in-review` | review | -| `done` | review again as a fresh follow-up pass | -| `blocked` | halt immediately | +| Spec status | Entry point | +| --------------- | -------------------------------------- | +| `draft` | plan | +| `ready-for-dev` | implement | +| `in-progress` | implement | +| `in-review` | review | +| `done` | review again as a fresh follow-up pass | +| `blocked` | halt immediately | ### Folder+ID Dispatch @@ -58,11 +60,11 @@ The workflow reads `/stories.yaml` and looks up the entry whose `id It then checks `/stories/-*.md` (id-prefix match) to tell a first dispatch from a resume: -| On-disk match | Outcome | -| --- | --- | -| None | First dispatch. Requires `/SPEC.md` to exist (otherwise halts `blocked` / `no epic spec found`). Loads `SPEC.md` and its companions, then proceeds to planning. | -| Exactly one | Resume: routes on that file's `status` exactly like the Resume Input table above. A `blocked` status here reports blocking condition `story already blocked`, not `blocked spec supplied` — dev-auto discovered the file by id, the caller didn't hand it a blocked spec. A missing or unrecognized `status` halts `blocked` / `unrecognized status in existing story file`. | -| More than one | Halts `blocked` / `ambiguous story file match`. | +| On-disk match | Outcome | +| ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| None | First dispatch. Requires `/SPEC.md` to exist (otherwise halts `blocked` / `no epic spec found`). Loads `SPEC.md` and its companions, then proceeds to planning. | +| Exactly one | Resume: routes on that file's `status` exactly like the Resume Input table above. A `blocked` status here reports blocking condition `story already blocked`, not `blocked spec supplied` — dev-auto discovered the file by id, the caller didn't hand it a blocked spec. A missing or unrecognized `status` halts `blocked` / `unrecognized status in existing story file`. | +| More than one | Halts `blocked` / `ambiguous story file match`. | A `blocked` story file is permanent: every later dispatch of that id halts with `story already blocked`, even after the cause is fixed. To retry, delete the story file — the id then reads as pending and the next dispatch starts fresh. @@ -90,14 +92,25 @@ It may also look at: The spec frontmatter `status` is the main machine-readable state for orchestration: -| Spec Status | Meaning | -| --- | --- | -| `draft` | Spec exists but has not passed ready-for-dev validation | -| `ready-for-dev` | Spec is complete enough to implement | -| `in-progress` | Implementation is underway | -| `in-review` | Review/triage is underway | -| `done` | Workflow completed successfully | -| `blocked` | Workflow cannot safely continue unattended | +| Spec Status | Meaning | +| --------------- | ------------------------------------------------------- | +| `draft` | Spec exists but has not passed ready-for-dev validation | +| `ready-for-dev` | Spec is complete enough to implement | +| `in-progress` | Implementation is underway | +| `in-review` | Review/triage is underway | +| `done` | Workflow completed successfully | +| `blocked` | Workflow cannot safely continue unattended | + +### Deferred Findings + +`deferred` is where the skill reports real findings that are not this story's problem. Each item contains: + +- `summary` — one-sentence description of the deferred issue +- `evidence` — why the finding is real +- `location` — optional file:line or component hint +- `severity` — optional final triage severity (`high`, `medium`, `low`) + +This is intentionally not a backlog. It is a machine-readable review output. The orchestrator has to decide what happens next: create a ticket, append to a central queue, correlate duplicates across runs, or do nothing. ### On `ready-for-dev` @@ -116,6 +129,7 @@ On successful completion, the workflow writes or updates the spec with: - Residual risks - `followup_review_recommended` flag. True if LLM decided another review pass seems worthwhile. It's a suggestion, not a must. Simplest way to give it a second review pass is to re-run the skill pointing it at the spec file. - `baseline_revision` and `final_revision` — the full canonical revisions before implementation and at the reviewed change's endpoint. `git log baseline_revision..final_revision` lists the reviewed change commits. Both are `NO_VCS` without version control. +- `deferred` frontmatter entries for review findings triaged `defer`. Each item records `summary`, `evidence`, and, when known, `location` plus `severity`. The workflow commits but does not push. If the spec is tracked in the implementation repository, clean HEAD is one spec-finalization commit beyond `final_revision`; otherwise the implementation repository ends at `final_revision`. @@ -158,6 +172,7 @@ For new work, the workflow creates: That spec is the contract between planning, implementation, and review. It contains: - Frontmatter status +- Frontmatter machine state (`followup_review_recommended`, `warnings`, `deferred`, revision markers) - The immutable `` block - Code map - Tasks and acceptance criteria @@ -171,11 +186,11 @@ Under folder+id dispatch, the workflow writes to `/stories/-*.md` | `ambiguous` | -| Entry resolved and no on-disk ambiguity | slug derived from `title` (and `description` if needed) | +| Situation | Slug segment used | +| -------------------------------------------------------------------- | ------------------------------------------------------- | +| `stories.yaml` missing/unparseable, or no entry matches the story id | `unresolved` | +| More than one on-disk file already matches `-*.md` | `ambiguous` | +| Entry resolved and no on-disk ambiguity | slug derived from `title` (and `description` if needed) | If the resolved path already exists, the workflow updates its `status` frontmatter and appends result details under `## Auto Run Result`, same as the primary spec artifact. If it doesn't exist, the workflow creates a skeletal story spec: frontmatter status, a heading (the entry's title, or `Story ` if the entry couldn't be resolved or the on-disk match was ambiguous), and an `## Auto Run Result` section. @@ -192,7 +207,6 @@ This records the terminal status and blocking condition. Depending on the route, the workflow may also write: - `{implementation_artifacts}/epic--context.md` -- `{implementation_artifacts}/deferred-work.md` - A patch file preserving the attempted change when the review step halts on `intent gap` (path recorded in the spec's triage log) ## Orchestrator Responsibilities @@ -203,6 +217,7 @@ An orchestrator integrating `bmad-dev-auto` should: - Prefer passing a spec path when resuming prior work — or the same spec folder and story id, under folder+id dispatch - Monitor the produced spec file, story spec artifact, or fallback result file for terminal state - Read `status`, `blocking condition`, and `followup_review_recommended` rather than inferring success from chat output alone +- Read deferred findings from the spec frontmatter `deferred:` list - Use `baseline_revision..final_revision` to identify the reviewed change commits; do not assume `final_revision` equals HEAD - Expect autonomous file changes and local commits - Handle `blocked` as a routing signal, not just a failure signal diff --git a/docs/zh-cn/reference/dev-auto.md b/docs/zh-cn/reference/dev-auto.md index 2aadcc316..c8c7f5ab4 100644 --- a/docs/zh-cn/reference/dev-auto.md +++ b/docs/zh-cn/reference/dev-auto.md @@ -7,6 +7,8 @@ sidebar: 要在自主开发循环里使用 BMad,请用 `bmad-dev-auto` skill。它类似 [Quick Dev](../explanation/quick-dev.md),但设计为在无人交互的情况下持续推进。你可以在交互式会话里用它,主要用途是被 orchestrator 调用。 +这里有一条重要的架构边界:`bmad-dev-auto` 负责 implementation run 及其生成的 spec artifact,但不负责 backlog policy。当 review 发现真实但不属于当前 story 的问题时,skill 会把 finding 记录在自己负责的 spec 中,仅此而已。是排入队列、去重、升级还是忽略,由 orchestrator 决定。 + ## 它做什么 `bmad-dev-auto` 执行一次无人值守的开发循环迭代: @@ -99,6 +101,17 @@ spec frontmatter 的 `status` 是 orchestration 的主要 machine-readable 状 | `done` | Workflow 成功完成 | | `blocked` | Workflow 无法安全 unattended 继续 | +### Deferred Findings + +`deferred` 用于记录 skill 发现的真实问题,但这些问题不属于当前 story。每个条目包含: + +- `summary` —— deferred issue 的单句描述 +- `evidence` —— 证明 finding 真实存在的依据 +- `location` —— 可选的 file:line 或 component 提示 +- `severity` —— 可选的最终 triage severity(`high`、`medium`、`low`) + +它不是 backlog,而是 machine-readable review output。Orchestrator 必须决定下一步:创建 ticket、追加到 central queue、关联多次 run 中的重复项,或不做处理。 + ### 在 `ready-for-dev` 时 `ready-for-dev` 通常是 workflow 直通 implement 的 resume 状态。当 invocation prompt 指示 planning 后 halt 时,它成为真正的 halt 结果:spec 通过 READY FOR DEVELOPMENT gate 后,workflow 设 status `ready-for-dev` 并停在那里,而不是继续 implement。重新 dispatch 同一 spec(或同一 spec 文件夹和 story id)会经上述路由在 implement resume。 @@ -116,6 +129,7 @@ spec frontmatter 的 `status` 是 orchestration 的主要 machine-readable 状 - Residual risks - `followup_review_recommended` 标志。若 LLM 认为值得再 review 一轮则为 true。只是建议,非必须。最简单的二次 review 是重新运行 skill 并指向 spec 文件。 - `baseline_revision` 和 `final_revision` —— implementation 前与 reviewed change endpoint 的完整 canonical revision。`git log baseline_revision..final_revision` 列出 reviewed change commits。无版本控制时两者均为 `NO_VCS`。 +- triage 为 `defer` 的 review findings 会写入 frontmatter 的 `deferred` 条目。每个条目记录 `summary`、`evidence`,以及已知时的 `location` 和 `severity`。 Workflow 会 commit,但不会 push。若 spec 由 implementation repository track,clean HEAD 会比 `final_revision` 多一个 spec-finalization commit;否则 implementation repository 会停在 `final_revision`。 @@ -158,6 +172,7 @@ workflow 总是尽量留下 durable artifact 描述发生了什么。 该 spec 是 planning、implementation 和 review 之间的 contract,包含: - Frontmatter status +- Frontmatter machine state(`followup_review_recommended`、`warnings`、`deferred`、revision markers) - 不可变的 `` 块 - Code map - Tasks 和 acceptance criteria @@ -192,7 +207,6 @@ workflow 在尚无 valid `spec_file` 时 halt(folder+id dispatch 外 —— 视路由,workflow 还可能写入: - `{implementation_artifacts}/epic--context.md` -- `{implementation_artifacts}/deferred-work.md` - review step 因 `intent gap` halt 时保存 attempted change 的 patch 文件(路径记录在 spec triage log) ## Orchestrator 职责 @@ -203,6 +217,7 @@ workflow 在尚无 valid `spec_file` 时 halt(folder+id dispatch 外 —— - Resume 时优先传 spec 路径 —— 或 folder+id dispatch 下同一 spec 文件夹和 story id - 监控产出的 spec 文件、story spec artifact 或 fallback result 文件的 terminal state - 读 `status`、`blocking condition`、`followup_review_recommended`,不要只从 chat 输出推断成功 +- 从 spec frontmatter 的 `deferred:` list 读取 deferred findings - 用 `baseline_revision..final_revision` 识别 reviewed change commits;不要假设 `final_revision` 等于 HEAD - 预期 autonomous 文件变更和 local commits - 把 `blocked` 当作 routing signal,而不只是 failure signal diff --git a/package.json b/package.json index 1addebc19..d291fb533 100644 --- a/package.json +++ b/package.json @@ -40,10 +40,11 @@ "lint:fix": "eslint . --ext .js,.cjs,.mjs,.yaml --fix", "lint:md": "markdownlint-cli2 \"**/*.md\"", "prepare": "command -v husky >/dev/null 2>&1 && husky || exit 0", - "quality": "npm run format:check && npm run lint && npm run lint:md && npm run docs:build && npm run test:install && npm run test:urls && npm run test:renderer && npm run validate:refs && npm run validate:skills && npm run docs:validate-sidebar", + "quality": "npm run format:check && npm run lint && npm run lint:md && npm run docs:build && npm run test:install && npm run test:urls && npm run test:renderer && npm run test:dev-auto-contract && npm run validate:refs && npm run validate:skills && npm run docs:validate-sidebar", "rebundle": "node tools/installer/bundlers/bundle-web.js rebundle", - "test": "npm run test:refs && npm run test:install && npm run test:urls && npm run test:channels && npm run test:renderer && npm run test:skills && npm run lint && npm run lint:md && npm run format:check", + "test": "npm run test:refs && npm run test:install && npm run test:urls && npm run test:channels && npm run test:renderer && npm run test:dev-auto-contract && npm run test:skills && npm run lint && npm run lint:md && npm run format:check", "test:channels": "node test/test-installer-channels.js", + "test:dev-auto-contract": "node test/test-dev-auto-contract.js", "test:install": "node test/test-installation-components.js", "test:refs": "node test/test-file-refs-csv.js", "test:renderer": "uv run --python 3.11 python -m unittest src/scripts/tests/test_config_utils.py src/scripts/tests/test_resolve_config.py src/scripts/tests/test_resolve_customization.py && node test/test-quick-dev-renderer.js && node test/test-dev-auto-renderer.js", diff --git a/src/bmm-skills/4-implementation/bmad-dev-auto/spec-template.md b/src/bmm-skills/4-implementation/bmad-dev-auto/spec-template.md index 498e85ee0..07178f988 100644 --- a/src/bmm-skills/4-implementation/bmad-dev-auto/spec-template.md +++ b/src/bmm-skills/4-implementation/bmad-dev-auto/spec-template.md @@ -7,6 +7,7 @@ review_loop_iteration: 0 # incremented by step-04 before each review loopback followup_review_recommended: false # set by step-04 on status: done — true if the LLM decided another review pass is worthwhile context: [] # optional: `{project-root}/`-prefixed paths to project-wide standards/docs the implementation agent should load. Keep short — only what isn't already distilled into the spec body. warnings: [] # optional: machine-readable warnings for orchestration, e.g. oversized, multiple-goals +deferred: [] # append-only machine-readable deferred review findings; each item carries summary/evidence and optional location/severity ---