Files
bmad-code-org__bmad-method/docs/build/autonomous-development-loops.md
Alex Verkhovsky b0d27c3c4a fix(skills): defer all-maybe-false entries only at medium-or-worse (#2809)
Today every all-maybe-false entry routes to defer, so the deferred-work
ledger accumulates low-stakes hypotheticals that later sweeps read back
as work. Dropping the bucket wholesale would go too far the other way:
maybe-false means triage could not decide, and the claims that would be
serious if true are exactly the ones worth a durable record.

So gate the route on what the claim would be if true: medium or high
defers, with that severity marked unverified and what would settle it
as the evidence; low rejects, keeping the same note in the triage log.

Applied at the four triage sites (bmad-build step-04 and oneshot,
bmad-build-auto step-04, bmad-code-review step-03), the build-auto
deferred-list severity comment, and autonomous-development-loops.md.
2026-09-01 07:20:51 -06:00

286 lines
17 KiB
Markdown

---
title: Autonomous Development Loops
description: Run bmad-build-auto as the unattended worker for one session-sized unit, and let an orchestrator drive many of them.
sidebar:
order: 6
---
`bmad-build-auto` is the unattended worker for one session-sized unit in the
canonical [Build a Change](./build-a-change.md) implementation model. One invocation
clarifies, plans, implements, and reviews one intent or story, then exposes a
terminal status that a human or orchestrator can act on.
Build Auto does not choose the next story, repeat across a backlog, coordinate
epics, or run a retrospective. It owns only its implementation run and the
record it creates or resumes. A human or an orchestrator, such as an AI coding
session or bmad-loop, owns backlog policy and dispatch.
## What It Does
`bmad-build-auto` performs one unattended implementation run:
1. Clarify the incoming intent
2. Create (or find and resume) a spec file
3. Implement the change
4. Review the result
5. Finish by writing a terminal status to the spec file or fallback result artifact
## Prerequisites
This skill relies on an ability to run subagents. If subagents are unavailable,
the workflow halts `blocked` with `no subagents`. An AI coding session that
orchestrates several stories must start one Build Auto worker per story. Each
worker must be able to start the review subagents used inside its own run.
Version control, while optional, is strongly recommended. If present, the working tree must be clean and the agent must be able to update repository metadata.
## Inputs
### Primary Invocation Input
The main input is the invocation prompt. `bmad-build-auto` treats that prompt as workflow input, not as a finished implementation plan.
Supported intent shapes include:
- A short free-form change request
- A ticket, issue, or story identifier
- A path to an intent file
- A path to an existing spec file generated by this workflow
- A spec folder plus a story id, with no specific spec file path (**folder+id dispatch** — see below)
### Resume Input
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 |
### Folder+ID Dispatch
Instead of a spec-file path, the invocation prompt can supply a spec folder and a story id, with no specific spec file path. Any further prompt text (e.g. `invoke_dev_with` guidance a caller appends) is carried forward as extra planning context, not a competing description of the work.
The workflow reads `<spec-folder>/stories.yaml` and looks up the entry whose `id` matches. It takes only that entry's `title` and `description` — `spec_checkpoint`, `done_checkpoint`, and `invoke_dev_with` are the dispatching caller's fields and are never read from the file itself.
It then checks `<spec-folder>/stories/<story-id>-*.md` (id-prefix match) to tell a first dispatch from a resume:
| On-disk match | Outcome |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| None | First dispatch. Requires `<spec-folder>/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` — build-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.
Whenever planning runs — on a first dispatch, or on a resume of interrupted planning (`draft`) — the workflow also loads every other file matching `<spec-folder>/stories/*.md` and carries forward each one's Code Map, Design Notes, Spec Change Log, Tasks & Acceptance checklist state, and Auto Run Result details as extra planning context, so planning for one story can see what other stories in the same folder have already decided or produced. Resumes that skip planning skip this too.
Exactly one `stories.yaml` entry is dispatched per invocation: the workflow never reads another entry or advances to a different story id, regardless of outcome.
The shared spec-backed epic layout is:
```text
<spec-folder>/
├── SPEC.md
├── stories.yaml
└── stories/
├── 1-<slug>.md
├── 2-<slug>.md
└── ...
```
`stories.yaml` is the ordered inventory. Build and Build Auto create or resume
the Markdown records under `stories/`, and each record carries its lifecycle
status in frontmatter. Downstream consumers use the location and status rather
than depending on which Build workflow produced the record.
## Orchestration Options
Build Auto is the worker in each option below. The orchestrator selects a unit,
starts one worker, reads its result, and decides what happens next.
### Run an ordered manifest with bmad-loop
The optional [bmad-loop](https://github.com/bmad-code-org/bmad-loop)
orchestrator processes a spec folder's `stories.yaml` in list order. It is a
linear scheduler: it does not infer a dependency graph. Arrange the list so
each story's prerequisites appear first.
Selecting one story runs only that story. It does not mean “start here and run
the remainder.” Retrospective is a separate epic-closing activity; bmad-loop
may recommend it, but `bmad-retrospective` performs it.
### Use an AI coding session as the orchestrator
An AI coding session can act as the orchestrator, dispatch one Build Auto
worker per unit, inspect the resulting evidence, and revise later work
when the parent spec or story list no longer fits what implementation revealed.
The orchestrating session remains responsible for keeping those revisions
consistent with the larger intent.
### Coordinate parallel epic streams
Project-level parallelism needs a higher coordination layer or separate epic
owners. Independent epic streams can run in parallel when dependencies and
integration boundaries are explicit. bmad-loop's ordered story scheduler does
not provide that project-level coordination.
## Context Inputs
On activation, the workflow resolves:
- `_bmad/config.toml`, `_bmad/config.user.toml`, and optional team/user overrides under `_bmad/custom/`
- Any configured workflow customizations from `customize.toml`, team overrides, and user overrides
- Persistent facts listed in workflow config — empty unless you opt in, so nothing is loaded here by default
It may also look at:
- BMAD planning artifacts
- A cached or newly compiled epic context file for epic-based work
- The most recent completed prior-story spec from the same epic for continuity
- Other `stories/*.md` records in the same spec folder, under folder+id dispatch (see Folder+ID Dispatch above)
## Spec Status
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 |
### 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`); a maybe-false entry carries its if-true grade plus " (unverified)"
A `maybe-false` finding is deferred only when its claim, if true, would be `medium` or worse; its evidence records what would settle it. Weaker ones are rejected in the spec's triage log with the same note.
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`
`ready-for-dev` is normally a resume state the workflow passes straight through on its way to implementation. It becomes a genuine halt outcome when the invocation prompt directs a halt after planning: once the spec passes the READY FOR DEVELOPMENT gate, the workflow sets status `ready-for-dev` and stops there instead of continuing to implementation. Re-dispatching the same spec (or the same spec folder and story id) resumes at implementation via the routing above.
### On `done`
On successful completion, the workflow writes or updates the spec with:
- Final `status: done`
- An `Auto Run Result` section containing:
- Summary of implemented change
- Files changed
- Review findings breakdown
- Verification performed
- 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` — the full canonical revision before implementation. `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. The working copy is clean at exit.
### On `blocked`
On blocked completion, the workflow writes:
- Final `status: blocked` when a spec exists
- A blocking condition
- Supporting detail in the spec or fallback result artifact
Typical blocking conditions include:
- `unclear intent`
- `intent gap`
- `no subagents`
- `missing spec_file before implementation`
- `implementation verification failed`
- `review repair loop exceeded 5 iterations (non-convergence)`
- `blocked spec supplied` (a directly-invoked spec file already had `status: blocked`)
- `no stories.yaml found`
- `story id not found in stories.yaml`
- `no epic spec found`
- `ambiguous story file match`
- `unrecognized status in existing story file`
- `story already blocked` (folder+id dispatch only — contrast with `blocked spec supplied` above)
An `intent gap` means the captured intent cannot answer a question the run hit — it can halt the planning step (before any code exists) or the review step. When review halts on it, the working tree is reverted as usual, but the attempted change is first saved as a patch file in `{implementation_artifacts}`, referenced from the spec's triage log and the halt output. The patch shows which reading of the intent the run implemented — concrete evidence for repairing the intent. If the attempted reading turns out to be correct, `git apply` the patch and set the spec status to `in-review` to resume review on it instead of re-running from scratch.
## Output Artifacts
The workflow always tries to leave behind a durable artifact describing what happened.
### Primary Spec Artifact
For new work, the workflow creates:
`{implementation_artifacts}/spec-<slug>.md`
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 `<intent-contract>` block
- Code map
- Tasks and acceptance criteria
- Spec change log
- Review triage log
- Verification notes
### Story Spec Artifact (Folder+ID Dispatch)
Under folder+id dispatch, the workflow writes to `<spec-folder>/stories/<story-id>-<slug>.md` instead of the primary spec or fallback result paths — including for halts before planning starts. The fallback result artifact below is never used in this mode.
When a halt happens before a slug can be derived from the story's title, the write-back falls back to a fixed slug segment instead:
| Situation | Slug segment used |
| -------------------------------------------------------------------- | ------------------------------------------------------- |
| `stories.yaml` missing/unparseable, or no entry matches the story id | `unresolved` |
| More than one on-disk file already matches `<story-id>-*.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 <story_id>` if the entry couldn't be resolved or the on-disk match was ambiguous), and an `## Auto Run Result` section.
### Fallback Result Artifact
If the workflow halts before it has a valid `spec_file` (outside folder+id dispatch — see above), it writes:
`{implementation_artifacts}/bmad-build-auto-result-<slug-or-timestamp>.md`
This records the terminal status and blocking condition.
### Additional Artifacts
Depending on the route, the workflow may also write:
- `{implementation_artifacts}/epic-<N>-context.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
An orchestrator integrating `bmad-build-auto` should:
- Pass one coherent intent at a time
- 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..<next story's baseline_revision>` to identify a story's commits, or `baseline_revision..HEAD` at exit when there is no next story yet
- Expect autonomous file changes and local commits
- Handle `blocked` as a routing signal, not just a failure signal
In practice, `blocked` usually means the workflow ran into a situation where unattended execution would be unsafe. That is often the point where a higher-level orchestrator, another workflow, or a human should take over.
After resolving a blocked run, the orchestrator should usually start a fresh `bmad-build-auto` run. If it reuses prior work, it should pass an explicit known-good spec path rather than relying on implicit discovery.