fix: run dev auto completion hook on blocked exits

This commit is contained in:
Alex Verkhovsky 2026-06-23 01:34:27 -07:00
parent 1ff6730909
commit ae7554e530
6 changed files with 38 additions and 26 deletions

View File

@ -9,11 +9,29 @@ description: 'One iteration of an unattended development loop. Use when invoked
**CRITICAL:** If a step says "read fully and follow step-XX", you read and follow step-XX. No exceptions. **CRITICAL:** If a step says "read fully and follow step-XX", you read and follow step-XX. No exceptions.
Using subagents when instructed is mandatory. If you cannot, record `no subagents` in the result artifact and end the run. ## HALT
## Result Artifact To HALT with a final status and optional blocking condition:
The result artifact is `{spec_file}` once it is known. If `{spec_file}` is unknown, create `{implementation_artifacts}/bmad-dev-auto-result-{slug-or-timestamp}.md`. 1. If `{spec_file}` is known and exists, update `status` in frontmatter and append missing result details under `## Auto Run Result`.
2. If `{spec_file}` is unknown or missing, create `{implementation_artifacts}/bmad-dev-auto-result-{slug-or-timestamp}.md` with:
```markdown
---
status: <final status>
---
# BMad Dev Auto Result
Status: <final status>
Blocking condition: <blocking condition, if any>
```
3. Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete`
4. If the resolved `workflow.on_complete` is non-empty, follow it as the final instruction before exiting.
5. Stop the workflow.
## Subagents
Using subagents when instructed is mandatory. If you cannot, HALT with status `blocked` and blocking condition `no subagents`.
## READY FOR DEVELOPMENT STANDARD ## READY FOR DEVELOPMENT STANDARD
@ -74,10 +92,10 @@ Execute each entry in `{workflow.activation_steps_append}` in order.
Activation is complete after all activation steps have run. Activation is complete after all activation steps have run.
## WORKFLOW EXECUTION ## Workflow Execution
Follow the step files in order. Read one step fully, execute it, then load the next step only when directed. Do not skip, reorder, or pre-load steps. Follow the step files in order. Read one step fully, execute it, then load the next step only when directed. Do not skip, reorder, or pre-load steps.
## FIRST WORKFLOW STEP ## First workflow step
Read fully and follow: `./step-01-clarify-and-route.md` to begin the workflow. Read fully and follow: `./step-01-clarify-and-route.md` to begin the workflow.

View File

@ -29,7 +29,7 @@ warnings: [] # optional: machine-readable warnings for orchestration, e.g. overs
**Always:** INVARIANT_RULES **Always:** INVARIANT_RULES
**Block If:** DECISIONS_REQUIRING_HUMAN_INPUT **Block If:** DECISIONS_REQUIRING_HUMAN_INPUT
<!-- Agent: if any of these trigger during execution, write the blocked condition to the result artifact and terminate cleanly. --> <!-- Agent: if any of these trigger during execution, HALT with status blocked and the blocking condition. -->
**Never:** NON_GOALS_AND_FORBIDDEN_APPROACHES **Never:** NON_GOALS_AND_FORBIDDEN_APPROACHES

View File

@ -10,7 +10,6 @@ spec_file: '' # set at runtime for both routes before leaving this step
- YOU MUST ALWAYS SPEAK OUTPUT in your Agent communication style with the config `{communication_language}` - YOU MUST ALWAYS SPEAK OUTPUT in your Agent communication style with the config `{communication_language}`
- Treat the invocation intent as workflow input, not as a substitute for step-02 investigation and spec generation. - Treat the invocation intent as workflow input, not as a substitute for step-02 investigation and spec generation.
- **EARLY EXIT** means: stop this step immediately, then read and follow the target file. Return here only if a later step explicitly says to loop back. - **EARLY EXIT** means: stop this step immediately, then read and follow the target file. Return here only if a later step explicitly says to loop back.
- **BLOCKED EXIT** means: write the blocked reason to the result artifact and end the run.
## Intent check (do this first) ## Intent check (do this first)
@ -23,7 +22,7 @@ If the invocation prompt explicitly points to an existing spec file with recogni
- `done` → ingest as context and proceed to INSTRUCTIONS — do not resume. - `done` → ingest as context and proceed to INSTRUCTIONS — do not resume.
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. 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.
If the invocation prompt does not contain enough intent to identify what to implement, write `unclear intent` to the result artifact and **BLOCKED EXIT**. If the invocation prompt does not contain enough intent to identify what to implement, HALT with status `blocked` and blocking condition `unclear intent`.
## INSTRUCTIONS ## INSTRUCTIONS
@ -40,11 +39,11 @@ If the invocation prompt does not contain enough intent to identify what to impl
- **If valid:** load it as the primary planning context. Do not load raw planning docs (PRD, architecture, UX, etc.). - **If valid:** load it as the primary planning context. Do not load raw planning docs (PRD, architecture, UX, etc.).
- **If missing, empty, or invalid:** compile it in the next bullet. - **If missing, empty, or invalid:** compile it in the next bullet.
3. **Compile epic context if needed.** If no valid cached epic context was loaded, produce `{implementation_artifacts}/epic-<N>-context.md` by spawning a sub-agent with `./compile-epic-context.md` as its prompt. Pass it the epic number, the epics file path, the `{planning_artifacts}` directory, and the output path `{implementation_artifacts}/epic-<N>-context.md`. If sub-agents are unavailable, write `no subagents` to the result artifact and **BLOCKED EXIT**. 3. **Compile epic context if needed.** If no valid cached epic context was loaded, produce `{implementation_artifacts}/epic-<N>-context.md` by spawning a sub-agent with `./compile-epic-context.md` as its prompt. Pass it the epic number, the epics file path, the `{planning_artifacts}` directory, and the output path `{implementation_artifacts}/epic-<N>-context.md`. If sub-agents are unavailable, HALT with status `blocked` and blocking condition `no subagents`.
4. **Verify if compiled.** If epic context was compiled, verify the output file exists, is non-empty, and starts with `# Epic <N> Context:`. If valid, load it. If verification fails, write the failed context-compilation condition to the result artifact and **BLOCKED EXIT**. 4. **Verify if compiled.** If epic context was compiled, verify the output file exists, is non-empty, and starts with `# Epic <N> Context:`. If valid, load it. If verification fails, HALT with status `blocked` and blocking condition `context compilation verification failed`.
5. **Previous story continuity.** Regardless of which context source succeeded above, scan `{implementation_artifacts}` for specs from the same epic with `status: done` and a lower story number. Load the most recent one (highest story number below current). Extract its **Code Map**, **Design Notes**, **Spec Change Log**, and **task list** as continuity context for step-02 planning. If no `done` spec is found but an `in-review` spec exists for the same epic with a lower story number, write the missing continuity decision to the result artifact and **BLOCKED EXIT**. 5. **Previous story continuity.** Regardless of which context source succeeded above, scan `{implementation_artifacts}` for specs from the same epic with `status: done` and a lower story number. Load the most recent one (highest story number below current). Extract its **Code Map**, **Design Notes**, **Spec Change Log**, and **task list** as continuity context for step-02 planning. If no `done` spec is found but an `in-review` spec exists for the same epic with a lower story number, HALT with status `blocked` and blocking condition `missing previous-story continuity decision`.
**B) Freeform path** — if the intent is not an epic story: **B) Freeform path** — if the intent is not an epic story:
- Planning artifacts are the output of BMAD phases 1-3. Typical files include: - Planning artifacts are the output of BMAD phases 1-3. Typical files include:
@ -54,8 +53,8 @@ If the invocation prompt does not contain enough intent to identify what to impl
- **Epics** (`*epic*`) — feature breakdown into implementable stories - **Epics** (`*epic*`) — feature breakdown into implementable stories
- **Product Brief** (`*brief*`) — project vision and scope - **Product Brief** (`*brief*`) — project vision and scope
- 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. - 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.
2. Clarify intent. Do not fantasize, do not leave open questions. If you must ask questions, write them as a blocked condition in the result artifact and **BLOCKED EXIT**. 2. Clarify intent. Do not fantasize, do not leave open questions. If you must ask questions, HALT with status `blocked` and those questions as blocking condition.
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, write the condition to the result artifact and **BLOCKED EXIT**. If version control is unavailable, skip this check. 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.
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. 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.
5. Route: 5. Route:

View File

@ -15,16 +15,16 @@ deferred_work_file: '{implementation_artifacts}/deferred-work.md'
2. Investigate codebase. _Isolate deep exploration in sub-agents/tasks where available. To prevent context snowballing, instruct subagents to give you distilled summaries only._ 2. Investigate codebase. _Isolate deep exploration in sub-agents/tasks where available. To prevent context snowballing, instruct subagents to give you distilled summaries only._
3. Read `./spec-template.md` fully. Fill it out based on the intent and investigation. If `{preserved_intent}` is non-empty, substitute it for the `<frozen-after-approval>` block in your filled spec before writing. Write the result to `{spec_file}`. 3. Read `./spec-template.md` fully. Fill it out based on the intent and investigation. If `{preserved_intent}` is non-empty, substitute it for the `<frozen-after-approval>` block in your filled spec before writing. Write the result to `{spec_file}`.
4. Self-review against READY FOR DEVELOPMENT standard. 4. Self-review against READY FOR DEVELOPMENT standard.
5. If intent gaps exist, do not fantasize and do not leave open questions. Set `{spec_file}` frontmatter status to `blocked`, append `## Auto Run Result` with `Status: blocked`, the unanswered questions, and evidence gathered, then terminate cleanly. 5. If intent gaps exist, do not fantasize and do not leave open questions. HALT with status `blocked`, blocking condition `intent gaps`, and include the unanswered questions and evidence gathered.
6. Warning check. If step-01 carried `multiple-goals`, add it to `{spec_file}` frontmatter `warnings`. If `{spec_file}` exceeds 1600 tokens, add `oversized` to frontmatter `warnings`. Continue either way. 6. Warning check. If step-01 carried `multiple-goals`, add it to `{spec_file}` frontmatter `warnings`. If `{spec_file}` exceeds 1600 tokens, add `oversized` to frontmatter `warnings`. Continue either way.
### READY-FOR-DEVELOPMENT GATE ### READY-FOR-DEVELOPMENT GATE
Re-read `{spec_file}` from disk and verify it meets the READY FOR DEVELOPMENT standard in `./SKILL.md`. Re-read `{spec_file}` from disk and verify it meets the READY FOR DEVELOPMENT standard in `./SKILL.md`.
- **If the file is missing:** write a best-effort result artifact in `{implementation_artifacts}` with `Status: blocked`, `Blocking condition: planned spec file disappeared before implementation`, and terminate cleanly. - **If the file is missing:** HALT with status `blocked` and blocking condition `planned spec file disappeared before implementation`.
- **If the spec meets the standard:** set `{spec_file}` frontmatter status to `ready-for-dev`, then continue to step 3. - **If the spec meets the standard:** set `{spec_file}` frontmatter status to `ready-for-dev`, then continue to step 3.
- **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, set `{spec_file}` frontmatter status to `blocked`, append `## Auto Run Result` with `Status: blocked`, the failing criteria, and evidence gathered, then terminate cleanly. - **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.
## NEXT ## NEXT

View File

@ -11,7 +11,7 @@
## PRECONDITION ## PRECONDITION
Verify `{spec_file}` resolves to a non-empty path and the file exists on disk. If empty or missing, write a best-effort result artifact in `{implementation_artifacts}` with `Status: blocked`, `Blocking condition: missing spec_file before implementation`, and terminate cleanly. Verify `{spec_file}` resolves to a non-empty path and the file exists on disk. If empty or missing, HALT with status `blocked` and blocking condition `missing spec_file before implementation`.
## INSTRUCTIONS ## INSTRUCTIONS
@ -25,7 +25,7 @@ Change `{spec_file}` status to `in-progress` in the frontmatter before starting
If `{spec_file}` has a non-empty `context:` list in its frontmatter, load those files before implementation begins. When handing to a sub-agent, include them in the sub-agent prompt so it has access to the referenced context. If `{spec_file}` has a non-empty `context:` list in its frontmatter, load those files before implementation begins. When handing to a sub-agent, include them in the sub-agent prompt so it has access to the referenced context.
Hand `{spec_file}` to a sub-agent/task and let it implement. If no sub-agents are available, set `{spec_file}` frontmatter status to `blocked`, append `## Auto Run Result` with `Status: blocked`, `Blocking condition: implementation subagent unavailable`, and terminate cleanly. Hand `{spec_file}` to a sub-agent/task and let it implement. If no sub-agents are available, HALT with status `blocked` and blocking condition `implementation subagent unavailable`.
**Path formatting rule:** Any markdown links written into `{spec_file}` must use paths relative to `{spec_file}`'s directory so they are clickable in VS Code. Any file paths displayed in terminal/conversation output must use CWD-relative format with `:line` notation (e.g., `src/path/file.ts:42`) for terminal clickability. No leading `/` in either case. **Path formatting rule:** Any markdown links written into `{spec_file}` must use paths relative to `{spec_file}`'s directory so they are clickable in VS Code. Any file paths displayed in terminal/conversation output must use CWD-relative format with `:line` notation (e.g., `src/path/file.ts:42`) for terminal clickability. No leading `/` in either case.

View File

@ -38,8 +38,8 @@ Launch two subagents without prior session context.
- **patch** — caused by the change; trivially fixable without human input. Just part of the diff. - **patch** — caused by the change; trivially fixable without human input. Just part of the diff.
- **defer** — pre-existing issue not caused by this story, surfaced incidentally by the review. Collect for later focused attention. - **defer** — pre-existing issue not caused by this story, surfaced incidentally by the review. Collect for later focused attention.
- **reject** — noise. Drop silently. When unsure between defer and reject, prefer reject — only defer findings you are confident are real. - **reject** — noise. Drop silently. When unsure between defer and reject, prefer reject — only defer findings you are confident are real.
3. Process findings in cascading order. If intent_gap or bad_spec findings exist, they trigger a loopback — lower findings are moot since code will be re-derived. If neither exists, process patch and defer normally. Increment `{specLoopIteration}` on each loopback. If it exceeds 5, set `{spec_file}` frontmatter status to `blocked`, append `## Auto Run Result` with `Status: blocked`, `Blocking condition: review repair loop exceeded 5 iterations`, and terminate cleanly. 3. Process findings in cascading order. If intent_gap or bad_spec findings exist, they trigger a loopback — lower findings are moot since code will be re-derived. If neither exists, process patch and defer normally. Increment `{specLoopIteration}` on each loopback. If it exceeds 5, HALT with status `blocked` and blocking condition `review repair loop exceeded 5 iterations`.
- **intent_gap** — Root cause is inside `<frozen-after-approval>`. Revert code changes. Set `{spec_file}` frontmatter status to `blocked`, append `## Auto Run Result` with `Status: blocked`, `Blocking condition: intent gap in frozen intent`, and the intent-gap findings, then terminate cleanly. - **intent_gap** — Root cause is inside `<frozen-after-approval>`. Revert code changes. HALT with status `blocked`, blocking condition `intent gap in frozen intent`, and include the intent-gap findings.
- **bad_spec** — Root cause is outside `<frozen-after-approval>`. Before reverting code: extract KEEP instructions for positive preservation (what worked well and must survive re-derivation). Revert code changes. Read the `## Spec Change Log` in `{spec_file}` and strictly respect all logged constraints when amending the non-frozen sections that contain the root cause. Append a new change-log entry recording: the triggering finding, what was amended, the known-bad state avoided, and the KEEP instructions. Read fully and follow `./step-03-implement.md` to re-derive the code, then this step will run again. - **bad_spec** — Root cause is outside `<frozen-after-approval>`. Before reverting code: extract KEEP instructions for positive preservation (what worked well and must survive re-derivation). Revert code changes. Read the `## Spec Change Log` in `{spec_file}` and strictly respect all logged constraints when amending the non-frozen sections that contain the root cause. Append a new change-log entry recording: the triggering finding, what was amended, the known-bad state avoided, and the KEEP instructions. Read fully and follow `./step-03-implement.md` to re-derive the code, then this step will run again.
- **patch** — Auto-fix. These are the only findings that survive loopbacks. - **patch** — Auto-fix. These are the only findings that survive loopbacks.
- **defer** — Append one new entry to `{deferred_work_file}` using this format. Do not modify existing entries or look for duplicates. - **defer** — Append one new entry to `{deferred_work_file}` using this format. Do not modify existing entries or look for duplicates.
@ -64,9 +64,4 @@ Append `## Auto Run Result` to `{spec_file}`. Include:
- Any residual risks - Any residual risks
Workflow complete. Workflow complete.
HALT with status `done`.
## On Complete
Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete`
If the resolved `workflow.on_complete` is non-empty, follow it as the final terminal instruction before exiting.