feat(bmm): draft bmad-dev-auto skill
Introduce a separate machine-first implementation workflow for bmad-auto sessions without layering more automation branches into bmad-quick-dev.
This commit is contained in:
parent
6ac4c26b69
commit
4bf11b6100
|
|
@ -0,0 +1,105 @@
|
||||||
|
---
|
||||||
|
name: bmad-dev-auto
|
||||||
|
description: 'Implements one story or deferred-work bundle unattended for a bmad-auto orchestrator. Use when a machine-run session must execute development work with no human interaction.'
|
||||||
|
---
|
||||||
|
|
||||||
|
# BMad Dev Auto
|
||||||
|
|
||||||
|
**Goal:** turn one orchestrator task into verified code plus on-disk artifacts the orchestrator can inspect.
|
||||||
|
|
||||||
|
This skill is for unattended runs only. It is not a variant of `bmad-quick-dev`; it is a separate machine-first workflow.
|
||||||
|
|
||||||
|
## Contract
|
||||||
|
|
||||||
|
- No greeting.
|
||||||
|
- No questions.
|
||||||
|
- No menus.
|
||||||
|
- No editor.
|
||||||
|
- No commit or push.
|
||||||
|
- `result.json` is the last successful action.
|
||||||
|
- If blocked, write `escalation.json`, write `result.json`, and end the turn.
|
||||||
|
|
||||||
|
## Invocation
|
||||||
|
|
||||||
|
The orchestrator invokes one of:
|
||||||
|
|
||||||
|
- `<story-key>`
|
||||||
|
- `<story-key> --feedback <path>`
|
||||||
|
- `--dw-bundle <path>`
|
||||||
|
- `--dw-bundle <path> --feedback <path>`
|
||||||
|
|
||||||
|
Environment:
|
||||||
|
|
||||||
|
- `BMAD_AUTO_RUN_DIR`
|
||||||
|
- `BMAD_AUTO_TASK_ID`
|
||||||
|
- optional `BMAD_AUTO_SKIP_REVIEW=1`
|
||||||
|
|
||||||
|
Files:
|
||||||
|
|
||||||
|
- result file: `$BMAD_AUTO_RUN_DIR/tasks/$BMAD_AUTO_TASK_ID/result.json`
|
||||||
|
- escalation file: `$BMAD_AUTO_RUN_DIR/tasks/$BMAD_AUTO_TASK_ID/escalation.json`
|
||||||
|
|
||||||
|
## Conventions
|
||||||
|
|
||||||
|
- Bare paths resolve from the skill root.
|
||||||
|
- `{skill-root}` is this installed skill directory.
|
||||||
|
- `{project-root}` is the working directory.
|
||||||
|
- `{skill-name}` is the skill directory basename.
|
||||||
|
- `{workflow.<name>}` comes from the merged `customize.toml` `[workflow]` table.
|
||||||
|
|
||||||
|
## On Activation
|
||||||
|
|
||||||
|
1. Resolve customization:
|
||||||
|
`python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`
|
||||||
|
2. If that fails, merge these in order using BMad structural merge rules:
|
||||||
|
- `{skill-root}/customize.toml`
|
||||||
|
- `{project-root}/_bmad/custom/{skill-name}.toml`
|
||||||
|
- `{project-root}/_bmad/custom/{skill-name}.user.toml`
|
||||||
|
3. Run each `{workflow.activation_steps_prepend}` entry.
|
||||||
|
4. Treat each `{workflow.persistent_facts}` entry as persistent context for the whole run.
|
||||||
|
5. Load config from `{project-root}/_bmad/bmm/config.yaml` and resolve:
|
||||||
|
- `project_name`
|
||||||
|
- `planning_artifacts`
|
||||||
|
- `implementation_artifacts`
|
||||||
|
- `communication_language`
|
||||||
|
- `document_output_language`
|
||||||
|
- `user_skill_level`
|
||||||
|
- `date`
|
||||||
|
- `sprint_status` = `{implementation_artifacts}/sprint-status.yaml`
|
||||||
|
6. Run each `{workflow.activation_steps_append}` entry.
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
|
||||||
|
- Speak tersely. Spend tokens on work, not narration.
|
||||||
|
- Never wait for user input.
|
||||||
|
- Treat the invocation as authoritative input.
|
||||||
|
- Spec target is **1500-4000 tokens**. On real multi-goal scope, split and defer the rest.
|
||||||
|
- Preserve anything inside `<frozen-after-approval>` once the spec is approved.
|
||||||
|
- Use the full `git rev-parse HEAD` hash for `baseline_commit`.
|
||||||
|
|
||||||
|
## Result Schema
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"workflow": "dev-auto",
|
||||||
|
"story_key": "<story key or null>",
|
||||||
|
"spec_file": "<absolute path>",
|
||||||
|
"baseline_commit": "<full hash or NO_VCS>",
|
||||||
|
"status": "in-review|done|blocked",
|
||||||
|
"tasks_total": 0,
|
||||||
|
"tasks_done": 0,
|
||||||
|
"verification": [{"command": "<cmd>", "ok": true}],
|
||||||
|
"escalations": [{"type": "<kind>", "severity": "CRITICAL|PREFERENCE", "detail": "<detail>"}],
|
||||||
|
"dw_ids": ["DW-1"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`status` means:
|
||||||
|
|
||||||
|
- `in-review`: code complete; a separate review run is expected.
|
||||||
|
- `done`: no separate review run is expected.
|
||||||
|
- `blocked`: the task could not continue safely.
|
||||||
|
|
||||||
|
## First Step
|
||||||
|
|
||||||
|
Read fully and follow `./step-01-resolve.md`.
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
# DO NOT EDIT -- overwritten on every update.
|
||||||
|
|
||||||
|
[workflow]
|
||||||
|
|
||||||
|
activation_steps_prepend = []
|
||||||
|
activation_steps_append = []
|
||||||
|
|
||||||
|
persistent_facts = [
|
||||||
|
"file:{project-root}/**/project-context.md",
|
||||||
|
]
|
||||||
|
|
||||||
|
on_complete = ""
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
# Deferred Work Format
|
||||||
|
|
||||||
|
Append-only format for `{implementation_artifacts}/deferred-work.md`.
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
|
||||||
|
- Do not rewrite or delete old entries.
|
||||||
|
- Before appending, scan for an equivalent open item.
|
||||||
|
- If one exists, add `seen-again:` instead of duplicating it.
|
||||||
|
- Number entries `DW-1`, `DW-2`, and so on.
|
||||||
|
|
||||||
|
## Entry
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
### DW-<seq>: <title>
|
||||||
|
|
||||||
|
origin: <workflow + artifact + date>
|
||||||
|
location: <file:line | component | n/a>
|
||||||
|
severity: <critical | high | medium | low>
|
||||||
|
reason: <why it is deferred>
|
||||||
|
status: open
|
||||||
|
```
|
||||||
|
|
||||||
|
When completed, change `status:` to `done <date>` and add:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
resolution: <one line>
|
||||||
|
```
|
||||||
|
|
||||||
|
Optional:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
seen-again: <date and source>
|
||||||
|
decision: <date> <label> -- <detail>
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
---
|
||||||
|
title: '{title}'
|
||||||
|
type: 'feature'
|
||||||
|
created: '{date}'
|
||||||
|
status: 'draft'
|
||||||
|
context: []
|
||||||
|
baseline_commit: ''
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- Target: 1500-4000 tokens in auto mode. Remove comments when filling. -->
|
||||||
|
|
||||||
|
<frozen-after-approval reason="orchestrator-owned intent — do not modify after approval unless a non-frozen spec defect must be corrected">
|
||||||
|
|
||||||
|
## Intent
|
||||||
|
|
||||||
|
**Problem:** ONE_TO_TWO_SENTENCES
|
||||||
|
|
||||||
|
**Approach:** ONE_TO_TWO_SENTENCES
|
||||||
|
|
||||||
|
## Boundaries & Constraints
|
||||||
|
|
||||||
|
**Always:** INVARIANT_RULES
|
||||||
|
|
||||||
|
**Never:** NON_GOALS_AND_FORBIDDEN_APPROACHES
|
||||||
|
|
||||||
|
## I/O & Edge Cases
|
||||||
|
|
||||||
|
| Scenario | Input / State | Expected Behavior | Error Handling |
|
||||||
|
|----------|----------------|-------------------|----------------|
|
||||||
|
| HAPPY_PATH | INPUT | OUTCOME | N/A |
|
||||||
|
|
||||||
|
</frozen-after-approval>
|
||||||
|
|
||||||
|
## Code Map
|
||||||
|
|
||||||
|
- `FILE` -- ROLE
|
||||||
|
|
||||||
|
## Tasks & Acceptance
|
||||||
|
|
||||||
|
**Execution:**
|
||||||
|
- [ ] `FILE` -- ACTION -- RATIONALE
|
||||||
|
|
||||||
|
**Acceptance Criteria:**
|
||||||
|
- Given PRECONDITION, when ACTION, then EXPECTED_RESULT
|
||||||
|
|
||||||
|
## Spec Change Log
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
|
||||||
|
**Commands:**
|
||||||
|
- `COMMAND` -- expected: SUCCESS
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
---
|
||||||
|
---
|
||||||
|
|
||||||
|
# Step 1: Resolve Task
|
||||||
|
|
||||||
|
## Instructions
|
||||||
|
|
||||||
|
1. Parse the invocation into one of:
|
||||||
|
- story mode
|
||||||
|
- story + feedback mode
|
||||||
|
- bundle mode
|
||||||
|
- bundle + feedback mode
|
||||||
|
2. Set:
|
||||||
|
- `{result_file}` = `$BMAD_AUTO_RUN_DIR/tasks/$BMAD_AUTO_TASK_ID/result.json`
|
||||||
|
- `{escalation_file}` = `$BMAD_AUTO_RUN_DIR/tasks/$BMAD_AUTO_TASK_ID/escalation.json`
|
||||||
|
3. If required environment variables are missing, write a `CRITICAL` escalation (`type: missing-env`) and end the run.
|
||||||
|
4. If in bundle mode:
|
||||||
|
- read the bundle file first
|
||||||
|
- set `{bundle_name}`
|
||||||
|
- set `{dw_ids}` from the bundle file
|
||||||
|
- set `{story_key}` = `dw-{bundle_name}`
|
||||||
|
- set `{spec_file}` = `{implementation_artifacts}/spec-dw-{bundle_name}.md`
|
||||||
|
5. Otherwise:
|
||||||
|
- set `{story_key}` from the invocation
|
||||||
|
- derive `{epic_num}` and `{story_num}` from its leading numeric segments
|
||||||
|
- set `{spec_file}` = `{implementation_artifacts}/spec-{story_key}.md`
|
||||||
|
6. If a feedback file was passed, read it before deciding the route.
|
||||||
|
7. Route:
|
||||||
|
- if feedback mode and `{spec_file}` exists: go to step 3
|
||||||
|
- else if `{spec_file}` exists with `status: draft`: go to step 2
|
||||||
|
- else if `{spec_file}` exists with `status: ready-for-dev|in-progress|in-review|done`: go to step 3
|
||||||
|
- else: go to step 2
|
||||||
|
|
||||||
|
## Next
|
||||||
|
|
||||||
|
- Step 2: `./step-02-plan.md`
|
||||||
|
- Step 3: `./step-03-implement.md`
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
---
|
||||||
|
deferred_work_file: '{implementation_artifacts}/deferred-work.md'
|
||||||
|
---
|
||||||
|
|
||||||
|
# Step 2: Plan
|
||||||
|
|
||||||
|
## Instructions
|
||||||
|
|
||||||
|
1. Investigate the codebase and relevant context files.
|
||||||
|
2. Read `./spec-template.md` fully.
|
||||||
|
3. Write `{spec_file}` from the template.
|
||||||
|
4. Self-review the spec:
|
||||||
|
- one goal
|
||||||
|
- actionable tasks
|
||||||
|
- testable acceptance criteria
|
||||||
|
- no placeholders
|
||||||
|
5. If intent is still unclear, write a `CRITICAL` escalation (`type: intent-gap`) and end the run.
|
||||||
|
6. If the scope is truly multi-goal or the spec exceeds 4000 tokens:
|
||||||
|
- keep the main goal in `{spec_file}`
|
||||||
|
- append each deferred secondary goal to `{deferred_work_file}` using `./deferred-work-format.md`
|
||||||
|
- rewrite the spec to match the narrowed scope
|
||||||
|
7. Re-read `{spec_file}` from disk.
|
||||||
|
8. If it is missing or empty, write a `CRITICAL` escalation (`type: spec-write-failure`) and end the run.
|
||||||
|
9. Set the spec frontmatter `status:` to `ready-for-dev`.
|
||||||
|
|
||||||
|
## Next
|
||||||
|
|
||||||
|
Read fully and follow `./step-03-implement.md`.
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
---
|
||||||
|
---
|
||||||
|
|
||||||
|
# Step 3: Implement
|
||||||
|
|
||||||
|
## Instructions
|
||||||
|
|
||||||
|
1. Verify `{spec_file}` exists and is non-empty. If not, write a `CRITICAL` escalation (`type: missing-spec`) and end the run.
|
||||||
|
2. Capture `baseline_commit` into the spec frontmatter:
|
||||||
|
- full `git rev-parse HEAD`
|
||||||
|
- or `NO_VCS` if git is unavailable
|
||||||
|
3. If this is not repair mode against an already-`done` spec, set the spec `status:` to `in-progress`.
|
||||||
|
4. If this is not bundle mode, follow `./sync-sprint-status.md` with `{target_status}` = `in-progress`.
|
||||||
|
5. Load any spec `context:` files.
|
||||||
|
6. Implement the spec directly or via sub-agents.
|
||||||
|
7. Mark every completed task in `## Tasks & Acceptance` as `[x]`.
|
||||||
|
8. If any listed task remains incomplete, finish it before continuing.
|
||||||
|
|
||||||
|
## Next
|
||||||
|
|
||||||
|
Read fully and follow `./step-04-finalize.md`.
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
---
|
||||||
|
deferred_work_file: '{implementation_artifacts}/deferred-work.md'
|
||||||
|
---
|
||||||
|
|
||||||
|
# Step 4: Finalize
|
||||||
|
|
||||||
|
## Instructions
|
||||||
|
|
||||||
|
1. Verify every task in `## Tasks & Acceptance` is checked.
|
||||||
|
2. Run every command in the spec `## Verification` section.
|
||||||
|
3. If a command fails and you cannot fix it without violating the frozen intent, write a `CRITICAL` escalation (`type: verification-failure`) and end the run.
|
||||||
|
4. Set final spec status:
|
||||||
|
- `done` when `BMAD_AUTO_SKIP_REVIEW=1`
|
||||||
|
- `in-review` otherwise
|
||||||
|
5. If not bundle mode, follow `./sync-sprint-status.md` with:
|
||||||
|
- `{target_status}` = `done` when `BMAD_AUTO_SKIP_REVIEW=1`
|
||||||
|
- `{target_status}` = `review` otherwise
|
||||||
|
6. If bundle mode, update every referenced deferred-work entry:
|
||||||
|
- `status: done <date>`
|
||||||
|
- `resolution: <one line>`
|
||||||
|
7. Write `{result_file}` using the schema from `SKILL.md`.
|
||||||
|
8. End the turn with a one-line outcome.
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Sync Sprint Status
|
||||||
|
|
||||||
|
Skip this file if:
|
||||||
|
|
||||||
|
- `{story_key}` is unset
|
||||||
|
- `{story_key}` starts with `dw-`
|
||||||
|
- `{sprint_status}` does not exist
|
||||||
|
|
||||||
|
## Instructions
|
||||||
|
|
||||||
|
1. Load the full `{sprint_status}` file.
|
||||||
|
2. Find `development_status[{story_key}]`.
|
||||||
|
3. If missing, return without writing.
|
||||||
|
4. Never regress status.
|
||||||
|
5. Set the story to `{target_status}`.
|
||||||
|
6. If `{target_status}` is `in-progress`, derive `epic-{N}` from the story key and lift it from `backlog` to `in-progress` when present.
|
||||||
|
7. Refresh `last_updated`.
|
||||||
|
8. Save while preserving comments and structure.
|
||||||
Loading…
Reference in New Issue