Merge 9b7db3cc9e into 6ac4c26b69
This commit is contained in:
commit
ecf6e7d909
|
|
@ -21,6 +21,12 @@ If you need an explicit user instruction to run them, ask once now for the whole
|
||||||
|
|
||||||
## On Activation
|
## On Activation
|
||||||
|
|
||||||
|
### Step 0: Automation Check
|
||||||
|
|
||||||
|
Run: `echo "${BMAD_AUTO_MODE:-}"`
|
||||||
|
|
||||||
|
If the output is `1`, set `{auto_mode}` = true and read `./automation-mode.md` fully — treat its rules as persistent facts that override conversational behavior for the entire run (skip the greeting in Step 5, never halt for input). Otherwise set `{auto_mode}` = false and ignore that file. The `automation-mode.md` file exists only to support the `bmad-auto` orchestrator and is never read in a normal interactive run.
|
||||||
|
|
||||||
### Step 1: Resolve the Workflow Block
|
### Step 1: Resolve the Workflow Block
|
||||||
|
|
||||||
Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`
|
Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`
|
||||||
|
|
@ -77,7 +83,7 @@ This uses **step-file architecture** for disciplined execution:
|
||||||
|
|
||||||
1. **READ COMPLETELY**: Read the entire step file before acting
|
1. **READ COMPLETELY**: Read the entire step file before acting
|
||||||
2. **FOLLOW SEQUENCE**: Execute sections in order
|
2. **FOLLOW SEQUENCE**: Execute sections in order
|
||||||
3. **WAIT FOR INPUT**: Halt at checkpoints and wait for human
|
3. **WAIT FOR INPUT**: Halt at checkpoints and wait for human — unless `{auto_mode}`, where each halt resolves via the rules in `automation-mode.md`
|
||||||
4. **LOAD NEXT**: When directed, read fully and follow the next step file
|
4. **LOAD NEXT**: When directed, read fully and follow the next step file
|
||||||
|
|
||||||
### Critical Rules (NO EXCEPTIONS)
|
### Critical Rules (NO EXCEPTIONS)
|
||||||
|
|
@ -86,7 +92,7 @@ This uses **step-file architecture** for disciplined execution:
|
||||||
- **ALWAYS** read entire step file before execution
|
- **ALWAYS** read entire step file before execution
|
||||||
- **NEVER** skip steps or optimize the sequence
|
- **NEVER** skip steps or optimize the sequence
|
||||||
- **ALWAYS** follow the exact instructions in the step file
|
- **ALWAYS** follow the exact instructions in the step file
|
||||||
- **ALWAYS** halt at checkpoints and wait for human input
|
- **ALWAYS** halt at checkpoints and wait for human input — in `{auto_mode}` the automation-mode.md rules ARE the human input; apply them instead of waiting
|
||||||
|
|
||||||
## FIRST STEP
|
## FIRST STEP
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
# Automation Mode
|
||||||
|
|
||||||
|
You are running unattended inside a `bmad-auto` orchestrator session: a fresh
|
||||||
|
review context with no human watching. A deterministic program spawned you to
|
||||||
|
review one story's changes against its spec, will verify your artifacts on
|
||||||
|
disk (spec status, sprint status, test runs), and will kill this session after
|
||||||
|
your final turn. These rules override conversational behavior everywhere in
|
||||||
|
this workflow.
|
||||||
|
|
||||||
|
## Identity & I/O contract
|
||||||
|
|
||||||
|
- `$BMAD_AUTO_RUN_DIR` and `$BMAD_AUTO_TASK_ID` are set in your environment.
|
||||||
|
- Your **result file** is `$BMAD_AUTO_RUN_DIR/tasks/$BMAD_AUTO_TASK_ID/result.json`.
|
||||||
|
Writing it is the LAST action of the workflow (step-04 automation branch).
|
||||||
|
Schema:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"workflow": "code-review",
|
||||||
|
"clean": <true only when zero actionable findings remain AND you set the spec status to "done" on disk — see rule 8>,
|
||||||
|
"patched": <count of patch findings applied this session>,
|
||||||
|
"deferred": <count of defer findings appended to deferred-work>,
|
||||||
|
"dismissed": <count dismissed as noise — recorded to the Review Ledger, not dropped>,
|
||||||
|
"escalations": [{"type": "<kind>", "severity": "CRITICAL|PREFERENCE",
|
||||||
|
"detail": "<one or two sentences>"}]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- `CRITICAL` escalations pause the whole run for a human (correctness or
|
||||||
|
security decisions you cannot safely make). `PREFERENCE` is logged and the
|
||||||
|
run continues — prefer it when the work can proceed.
|
||||||
|
|
||||||
|
## Behavior rules
|
||||||
|
|
||||||
|
1. **Never HALT for input. Never ask the user anything.** No greeting, no
|
||||||
|
menus, no "what next" offers.
|
||||||
|
2. **The invocation argument IS the review target**: the path to a spec file.
|
||||||
|
Set `{spec_file}` to it, read `baseline_commit` from its frontmatter, set
|
||||||
|
`{review_mode}` = `"full"`, and resolve `{story_key}` from the spec's
|
||||||
|
filename/frontmatter against `{sprint_status}` (exact numeric match on the
|
||||||
|
first two segments). Skip the rest of the step-01 cascade and the step-01
|
||||||
|
CHECKPOINT.
|
||||||
|
- **Sweep bundles**: a spec filename matching `spec-dw-*` is a deferred-work
|
||||||
|
bundle from a sweep run — it has no sprint-status entry. Set `{story_key}`
|
||||||
|
= null and review as usual against the spec.
|
||||||
|
3. **Diff source**: all changes — tracked and untracked — since
|
||||||
|
`baseline_commit`. If the diff is empty, write result.json with
|
||||||
|
`clean: false` and a `CRITICAL` escalation (`type: empty-diff`) and end
|
||||||
|
your turn.
|
||||||
|
4. **Oversized diff (>3000 lines)**: do not ask about chunking. Review the
|
||||||
|
full diff, and record a `PREFERENCE` escalation (`type: oversized-diff`)
|
||||||
|
noting the line count.
|
||||||
|
5. **Triage** (step-03): apply the automation rule — a `decision_needed`
|
||||||
|
finding whose fix is actually unambiguous becomes `patch`; anything
|
||||||
|
genuinely needing human judgment becomes `defer` with reason
|
||||||
|
"auto-mode: needs human decision" AND an entry in `escalations`
|
||||||
|
(`CRITICAL` if it concerns correctness or security of the new code,
|
||||||
|
`PREFERENCE` otherwise).
|
||||||
|
6. **Spec defects** (step-03): when a finding's root cause is an error in the
|
||||||
|
spec itself — the code faithfully implements something the spec got wrong —
|
||||||
|
never patch around it silently. Root cause inside `<frozen-after-approval>`:
|
||||||
|
escalate `CRITICAL` (`type: spec-defect`) — the frozen intent is human-owned.
|
||||||
|
Root cause outside the frozen block: patch the code to the evidently correct
|
||||||
|
behavior, append an entry to the spec's `## Spec Change Log` recording the
|
||||||
|
finding, the amendment, and the known-bad state avoided, and record a
|
||||||
|
`PREFERENCE` escalation so a human can revisit the call.
|
||||||
|
7. **Act** (step-04): write findings to the spec file as usual; apply EVERY
|
||||||
|
`patch` finding without asking; append `defer` findings to the
|
||||||
|
deferred-work file following the format in `./deferred-work-format.md`;
|
||||||
|
skip the "Next steps" menu entirely. Skip the `## On Complete` step /
|
||||||
|
`workflow.on_complete` customization — result.json is the LAST action;
|
||||||
|
the orchestrator owns commit and everything after it.
|
||||||
|
8. **Status updates** (step-04 section 6) run exactly as written: spec
|
||||||
|
status (frontmatter `status:`) and sprint-status sync.
|
||||||
|
`clean: true` in result.json must mean you set the spec to `done` —
|
||||||
|
never claim clean without the status updates on disk.
|
||||||
|
When `{story_key}` is null (sweep bundle): skip the sprint-status sync
|
||||||
|
only; the spec frontmatter update stays mandatory. New `defer` findings
|
||||||
|
still append DW entries to the deferred-work file — the running sweep
|
||||||
|
ignores entries created after its triage; a later sweep picks them up.
|
||||||
|
9. **Never commit, never push.** The orchestrator commits after verifying.
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
# Deferred Work Format
|
||||||
|
|
||||||
|
Canonical entry format for `{implementation_artifacts}/deferred-work.md`.
|
||||||
|
Used (in `bmad-auto` automation mode) by bmad-quick-dev (multi-goal splits,
|
||||||
|
token splits, review defers) and bmad-code-review (defer findings). This copy
|
||||||
|
lives in the bmad-code-review skill; bmad-quick-dev ships a sibling copy of the
|
||||||
|
same entry format (its surrounding prose differs slightly) — keep the format
|
||||||
|
itself in sync across the two when it changes. The file is append-only — never
|
||||||
|
rewrite or delete existing entries. (One exception: freeform pre-DW-format
|
||||||
|
content from older projects is rewritten wholesale into canonical entries by a
|
||||||
|
`bmad-auto sweep` migration run — an orchestrator-side process external to this
|
||||||
|
skill; the TUI displays such legacy items read-only until that happens.)
|
||||||
|
|
||||||
|
## Before appending: dedupe check
|
||||||
|
|
||||||
|
Scan the existing file for an entry describing the same issue or goal (same
|
||||||
|
location and same substance, even if worded differently). If one exists, do
|
||||||
|
NOT append a duplicate — add a `seen-again:` line to the existing entry
|
||||||
|
instead:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
seen-again: 2026-06-12 (code review of spec-3-3-export.md)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Entry format
|
||||||
|
|
||||||
|
Number entries sequentially (`DW-1`, `DW-2`, …) by scanning the file for the
|
||||||
|
highest existing number. One entry per deferred item:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
### DW-<seq>: <one-line title>
|
||||||
|
|
||||||
|
origin: <workflow + artifact + date, e.g. "bmad-quick-dev split of spec-3-2-digest.md, 2026-06-12">
|
||||||
|
location: <file:line or component, or "n/a" for deferred goals>
|
||||||
|
severity: <critical | high | medium | low — how much it matters if never done>
|
||||||
|
reason: <why this was deferred rather than done now, one or two sentences>
|
||||||
|
status: open
|
||||||
|
```
|
||||||
|
|
||||||
|
`severity:` is optional — entries written before this field existed have none
|
||||||
|
and that is fine; readers must treat a missing or unrecognized value as
|
||||||
|
"unspecified". Use `critical` for correctness/security issues, `high` for
|
||||||
|
likely user-visible problems, `medium` for quality and robustness gaps, `low`
|
||||||
|
for polish and nice-to-haves.
|
||||||
|
|
||||||
|
When a deferred item is later completed, set its `status:` to `done` with the
|
||||||
|
date (e.g. `status: done 2026-06-20`) — do not delete the entry.
|
||||||
|
|
||||||
|
## Sweep annotations
|
||||||
|
|
||||||
|
`bmad-auto sweep` runs (the orchestrator and its bundle dev sessions) add two
|
||||||
|
optional field lines to existing entries — both directly after `status:`:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
resolution: <one line: what was built or why the entry was closed>
|
||||||
|
decision: <date> <chosen option label> — <detail>
|
||||||
|
```
|
||||||
|
|
||||||
|
- `resolution:` accompanies every sweep close (`status: done <date>`). Bundle
|
||||||
|
dev sessions write it when finishing a bundle's entries; the orchestrator
|
||||||
|
writes it when closing entries triage proved already resolved.
|
||||||
|
- `decision:` records a human's sweep-time choice on an entry. It does not by
|
||||||
|
itself change `status:` — a `keep-open` decision leaves the entry open.
|
||||||
|
|
@ -12,6 +12,7 @@ story_key: '' # set at runtime when discovered from sprint status
|
||||||
- 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}`
|
||||||
- The prompt that triggered this workflow IS the intent — not a hint.
|
- The prompt that triggered this workflow IS the intent — not a hint.
|
||||||
- Do not modify any files. This step is read-only.
|
- Do not modify any files. This step is read-only.
|
||||||
|
- If `{auto_mode}`: do NOT HALT or ask anywhere in this step (`../automation-mode.md` rule 1). The invocation argument is the spec file — apply rule 2 (target/baseline/story-key; this skips the instruction-1 cascade and instruction 2's ask), rule 3 (diff source), and rule 4 (no chunk question); skip instruction 4's spec-context question, instruction 6's question, and the CHECKPOINT — go straight to NEXT.
|
||||||
|
|
||||||
## INSTRUCTIONS
|
## INSTRUCTIONS
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,21 @@ failed_layers: '' # set at runtime: comma-separated list of layers that failed o
|
||||||
|
|
||||||
## INSTRUCTIONS
|
## INSTRUCTIONS
|
||||||
|
|
||||||
|
0. **Static prefilter** (`{auto_mode}` only — skip entirely in interactive runs). Before any LLM review, run the project's deterministic
|
||||||
|
checks — they are free, precise findings the hunters should not have to
|
||||||
|
rediscover. Resolve the command list in this order, first match wins:
|
||||||
|
1. `[verify] commands` in `{project-root}/.automator/policy.toml` (if the file exists)
|
||||||
|
2. the `## Verification` commands in `{spec_file}` (if `{review_mode}` = `"full"`)
|
||||||
|
3. none found — skip this instruction silently.
|
||||||
|
|
||||||
|
Record each failing command as a finding with `source: static` (title = the
|
||||||
|
command, detail = the failure output tail). Summarize failures in one line
|
||||||
|
each and pass them to the Edge Case Hunter and Acceptance Auditor as
|
||||||
|
`also_consider` input. Do NOT pass them to the Blind Hunter — it stays blind.
|
||||||
|
|
||||||
1. If `{review_mode}` = `"no-spec"`, note to the user: "Acceptance Auditor skipped — no spec file provided."
|
1. If `{review_mode}` = `"no-spec"`, note to the user: "Acceptance Auditor skipped — no spec file provided."
|
||||||
|
|
||||||
2. Launch parallel subagents without conversation context. If subagents are not available, generate prompt files in `{implementation_artifacts}` — one per reviewer role below — and HALT. Ask the user to run each in a separate session (ideally a different LLM) and paste back the findings. When findings are pasted, resume from this point and proceed to step 3.
|
2. Launch parallel subagents without conversation context. If subagents are not available: in `{auto_mode}` do NOT HALT (`../automation-mode.md` rule 1) — run each reviewer role below inline, one after another in this same session, keeping each role's input scoped as specified (the Blind Hunter still gets only the diff), then proceed to step 3. Otherwise (interactive), generate prompt files in `{implementation_artifacts}` — one per reviewer role below — and HALT. Ask the user to run each in a separate session (ideally a different LLM) and paste back the findings. When findings are pasted, resume from this point and proceed to step 3.
|
||||||
|
|
||||||
- **Blind Hunter** — receives inline `{diff_output}` only. No spec, no context docs, no project access. Invoke via the `bmad-review-adversarial-general` skill.
|
- **Blind Hunter** — receives inline `{diff_output}` only. No spec, no context docs, no project access. Invoke via the `bmad-review-adversarial-general` skill.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
Convert all to a unified list where each finding has:
|
Convert all to a unified list where each finding has:
|
||||||
- `id` -- sequential integer
|
- `id` -- sequential integer
|
||||||
- `source` -- `blind`, `edge`, `auditor`, or merged sources (e.g., `blind+edge`)
|
- `source` -- `blind`, `edge`, `auditor`, `static` (auto-mode prefilter), or merged sources (e.g., `blind+edge`)
|
||||||
- `title` -- one-line summary
|
- `title` -- one-line summary
|
||||||
- `detail` -- full description
|
- `detail` -- full description
|
||||||
- `location` -- file and line reference (if available)
|
- `location` -- file and line reference (if available)
|
||||||
|
|
@ -29,7 +29,24 @@
|
||||||
- Append any unique detail, reasoning, or location references from the other finding(s) into the surviving `detail` field.
|
- Append any unique detail, reasoning, or location references from the other finding(s) into the surviving `detail` field.
|
||||||
- Set `source` to the merged sources (e.g., `blind+edge`).
|
- Set `source` to the merged sources (e.g., `blind+edge`).
|
||||||
|
|
||||||
3. **Classify** each finding into exactly one bucket:
|
**Prior-cycle ledger check** (`{auto_mode}` only): if `{spec_file}` contains `#### Review Ledger`
|
||||||
|
entries from earlier review cycles, treat them as already adjudicated. A new
|
||||||
|
finding matching a previously dismissed entry (same location, same substance)
|
||||||
|
is `dismiss` with reason "previously dismissed — see ledger" unless it brings
|
||||||
|
genuinely new evidence. A finding matching a previously patched entry must be
|
||||||
|
checked against the current code before re-raising — the patch may already
|
||||||
|
cover it.
|
||||||
|
|
||||||
|
3. **Verify against the code** (`{auto_mode}` only). For each surviving finding (except `static`
|
||||||
|
ones — those are tool output), check it against the actual code before
|
||||||
|
classifying. You have project access; the hunters that produced these
|
||||||
|
findings mostly did not. A finding contradicted by the surrounding code —
|
||||||
|
the case is already guarded, the function behaves differently than the
|
||||||
|
finding assumes, the "missing" handling exists elsewhere — becomes `dismiss`
|
||||||
|
with the contradiction recorded as its reason. Do not classify a finding you
|
||||||
|
have not verified.
|
||||||
|
|
||||||
|
4. **Classify** each finding into exactly one bucket:
|
||||||
- **decision_needed** -- There is an ambiguous choice that requires human input. The code cannot be correctly patched without knowing the user's intent. Only possible if `{review_mode}` = `"full"`.
|
- **decision_needed** -- There is an ambiguous choice that requires human input. The code cannot be correctly patched without knowing the user's intent. Only possible if `{review_mode}` = `"full"`.
|
||||||
- **patch** -- Code issue that is fixable without human input. The correct fix is unambiguous.
|
- **patch** -- Code issue that is fixable without human input. The correct fix is unambiguous.
|
||||||
- **defer** -- Pre-existing issue not caused by the current change. Real but not actionable now.
|
- **defer** -- Pre-existing issue not caused by the current change. Real but not actionable now.
|
||||||
|
|
@ -37,11 +54,13 @@
|
||||||
|
|
||||||
If `{review_mode}` = `"no-spec"` and a finding would otherwise be `decision_needed`, reclassify it as `patch` (if the fix is unambiguous) or `defer` (if not).
|
If `{review_mode}` = `"no-spec"` and a finding would otherwise be `decision_needed`, reclassify it as `patch` (if the fix is unambiguous) or `defer` (if not).
|
||||||
|
|
||||||
4. **Drop** all `dismiss` findings. Record the dismiss count for the summary.
|
If `{auto_mode}` and a finding would otherwise be `decision_needed`: reclassify as `patch` only when the fix is genuinely unambiguous; otherwise reclassify as `defer` with reason "auto-mode: needs human decision" AND record it in the result escalations — severity `CRITICAL` if it concerns correctness or security of the new code, else `PREFERENCE` (see `../automation-mode.md` rule 5).
|
||||||
|
|
||||||
5. If `{failed_layers}` is non-empty, report which layers failed before announcing results. If zero findings remain after dropping dismissed AND `{failed_layers}` is non-empty, warn the user that the review may be incomplete rather than announcing a clean review.
|
5. **Drop** all `dismiss` findings. Record the dismiss count for the summary. (`{auto_mode}`: do NOT drop — set each dismissed finding aside, keeping its title, location, and one-line dismissal reason; step-04 writes them to the Review Ledger so later cycles do not re-litigate them.)
|
||||||
|
|
||||||
6. If zero findings remain after triage (all rejected or none raised): state "✅ Clean review — all layers passed." (Step 3 already warned if any review layers failed via `{failed_layers}`.)
|
6. If `{failed_layers}` is non-empty, report which layers failed before announcing results. If zero findings remain after dropping dismissed AND `{failed_layers}` is non-empty, warn the user that the review may be incomplete rather than announcing a clean review.
|
||||||
|
|
||||||
|
7. If zero findings remain after triage (all rejected or none raised): state "✅ Clean review — all layers passed." (Step 3 already warned if any review layers failed via `{failed_layers}`.)
|
||||||
|
|
||||||
|
|
||||||
## NEXT
|
## NEXT
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,23 @@ deferred_work_file: '{implementation_artifacts}/deferred-work.md'
|
||||||
- When `{spec_file}` is set, always write findings to the story file before offering action choices.
|
- When `{spec_file}` is set, always write findings to the story file before offering action choices.
|
||||||
- `decision-needed` findings must be resolved before handling `patch` findings.
|
- `decision-needed` findings must be resolved before handling `patch` findings.
|
||||||
|
|
||||||
|
## AUTOMATION MODE
|
||||||
|
|
||||||
|
If `{auto_mode}`, run this step with these substitutions (see `../automation-mode.md`):
|
||||||
|
|
||||||
|
- Sections 1, 2, 3, and 6 run as written (no waiting after section 3).
|
||||||
|
- Section 4: no `decision-needed` findings should remain (step-03's automation rule reclassified them). If any do, treat each as `defer` with reason "auto-mode: needs human decision" and record an escalation.
|
||||||
|
- Section 5: do not present the menu — **Apply every patch**, then check off the patch items in the story file.
|
||||||
|
- Section 7: skip entirely.
|
||||||
|
- After section 6, write `$BMAD_AUTO_RUN_DIR/tasks/$BMAD_AUTO_TASK_ID/result.json` per the schema in `../automation-mode.md` (`clean` is true only when `{new_status}` = `done` was set on disk), state the outcome in one line, and end your turn.
|
||||||
|
|
||||||
## INSTRUCTIONS
|
## INSTRUCTIONS
|
||||||
|
|
||||||
### 1. Clean review shortcut
|
### 1. Clean review shortcut
|
||||||
|
|
||||||
If zero findings remain after triage (all dismissed or none raised): state that and proceed to section 6 (Sprint Status Update).
|
If no **actionable** findings remain after triage — no `decision-needed`, `patch`, or `defer` findings (every finding was dismissed, or none were raised): state that and proceed to section 6 (Sprint Status Update). Set-aside dismissed findings do not count as "remaining".
|
||||||
|
|
||||||
|
**If `{auto_mode}`:** when any findings were dismissed, do NOT skip straight to section 6 — first perform section 2's Review Ledger append (the `#### Review Ledger ({date})` subsection) so the next cycle's reviewers do not re-litigate them, then proceed to section 6.
|
||||||
|
|
||||||
### 2. Write findings to the story file
|
### 2. Write findings to the story file
|
||||||
|
|
||||||
|
|
@ -31,6 +43,8 @@ If `{spec_file}` exists and contains a Tasks/Subtasks section, append a `### Rev
|
||||||
|
|
||||||
Also append each `defer` finding to `{deferred_work_file}` under a heading `## Deferred from: code review ({date})`. If `{spec_file}` is set, include its basename in the heading (e.g., `code review of story-3.3 (2026-03-18)`). One bullet per finding with description.
|
Also append each `defer` finding to `{deferred_work_file}` under a heading `## Deferred from: code review ({date})`. If `{spec_file}` is set, include its basename in the heading (e.g., `code review of story-3.3 (2026-03-18)`). One bullet per finding with description.
|
||||||
|
|
||||||
|
**If `{auto_mode}`:** instead of the heading-based append above, append each `defer` finding to `{deferred_work_file}` as a `DW-<seq>` entry following the format and dedupe rule in `../deferred-work-format.md` (this skill's own copy). Use `origin: code review of <spec basename>, {date}`, and set the entry's `severity:` from the finding's own severity. Then append a `#### Review Ledger ({date})` subsection to `{spec_file}` recording every triaged finding on one line each — `<verdict>: <title> [<location>] — <one-line reason>` — including the dismissed ones set aside in step-03. The ledger is append-only across review cycles; it is what stops the next cycle's fresh reviewers from re-litigating findings that were already adjudicated.
|
||||||
|
|
||||||
### 3. Present summary
|
### 3. Present summary
|
||||||
|
|
||||||
Announce what was written:
|
Announce what was written:
|
||||||
|
|
@ -86,8 +100,8 @@ Skip this section if `{spec_file}` is not set.
|
||||||
|
|
||||||
#### Determine new status based on review outcome
|
#### Determine new status based on review outcome
|
||||||
|
|
||||||
- If all `decision-needed` and `patch` findings were resolved (fixed or dismissed) AND no unresolved HIGH/MEDIUM issues remain: set `{new_status}` = `done`. Update the story file Status section to `done`.
|
- If all `decision-needed` and `patch` findings were resolved (fixed or dismissed) AND no unresolved HIGH/MEDIUM issues remain: set `{new_status}` = `done`. Update the spec's YAML frontmatter `status:` field to `done`.
|
||||||
- If `patch` findings were left as action items, or unresolved issues remain: set `{new_status}` = `in-progress`. Update the story file Status section to `in-progress`.
|
- If `patch` findings were left as action items, or unresolved issues remain: set `{new_status}` = `in-progress`. Update the spec's YAML frontmatter `status:` field to `in-progress`.
|
||||||
|
|
||||||
Save the story file.
|
Save the story file.
|
||||||
|
|
||||||
|
|
@ -127,6 +141,8 @@ Present the user with follow-up options:
|
||||||
|
|
||||||
## On Complete
|
## On Complete
|
||||||
|
|
||||||
|
**If `{auto_mode}`:** skip this section entirely — result.json (written after section 6) is the LAST action of the run (see `../automation-mode.md`); the orchestrator owns commit and everything after it.
|
||||||
|
|
||||||
Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.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.
|
If the resolved `workflow.on_complete` is non-empty, follow it as the final terminal instruction before exiting.
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ A specification should target a **single user-facing goal** within **900–1600
|
||||||
- Don't split: "add validation and display errors" / "support drag-and-drop AND paste AND retry"
|
- Don't split: "add validation and display errors" / "support drag-and-drop AND paste AND retry"
|
||||||
- **900–1600 tokens**: Optimal range for LLM consumption. Below 900 risks ambiguity; above 1600 risks context-rot in implementation agents.
|
- **900–1600 tokens**: Optimal range for LLM consumption. Below 900 risks ambiguity; above 1600 risks context-rot in implementation agents.
|
||||||
- **Neither limit is a gate.** Both are proposals with user override.
|
- **Neither limit is a gate.** Both are proposals with user override.
|
||||||
|
- (`{auto_mode}`: the target is **1,500–4,000 tokens** instead — see the scope override in `./automation-mode.md`.)
|
||||||
|
|
||||||
## Conventions
|
## Conventions
|
||||||
|
|
||||||
|
|
@ -40,6 +41,12 @@ A specification should target a **single user-facing goal** within **900–1600
|
||||||
|
|
||||||
## On Activation
|
## On Activation
|
||||||
|
|
||||||
|
### Step 0: Automation Check
|
||||||
|
|
||||||
|
Run: `echo "${BMAD_AUTO_MODE:-}"`
|
||||||
|
|
||||||
|
If the output is `1`, set `{auto_mode}` = true and read `./automation-mode.md` fully — treat its rules as persistent facts that override conversational behavior for the entire run (skip the greeting in Step 5, never halt for input). Otherwise set `{auto_mode}` = false and ignore that file. The automation files (`automation-mode.md`, `step-auto-finalize.md`, `deferred-work-format.md`) exist only to support the `bmad-auto` orchestrator and are never read in a normal interactive run.
|
||||||
|
|
||||||
### Step 1: Resolve the Workflow Block
|
### Step 1: Resolve the Workflow Block
|
||||||
|
|
||||||
Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`
|
Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`
|
||||||
|
|
@ -98,7 +105,7 @@ This uses **step-file architecture** for disciplined execution:
|
||||||
|
|
||||||
1. **READ COMPLETELY**: Read the entire step file before acting
|
1. **READ COMPLETELY**: Read the entire step file before acting
|
||||||
2. **FOLLOW SEQUENCE**: Execute sections in order
|
2. **FOLLOW SEQUENCE**: Execute sections in order
|
||||||
3. **WAIT FOR INPUT**: Halt at checkpoints and wait for human
|
3. **WAIT FOR INPUT**: Halt at checkpoints and wait for human — unless `{auto_mode}`, where each halt resolves via the decision table in `automation-mode.md`
|
||||||
4. **LOAD NEXT**: When directed, read fully and follow the next step file
|
4. **LOAD NEXT**: When directed, read fully and follow the next step file
|
||||||
|
|
||||||
### Critical Rules (NO EXCEPTIONS)
|
### Critical Rules (NO EXCEPTIONS)
|
||||||
|
|
@ -107,7 +114,7 @@ This uses **step-file architecture** for disciplined execution:
|
||||||
- **ALWAYS** read entire step file before execution
|
- **ALWAYS** read entire step file before execution
|
||||||
- **NEVER** skip steps or optimize the sequence
|
- **NEVER** skip steps or optimize the sequence
|
||||||
- **ALWAYS** follow the exact instructions in the step file
|
- **ALWAYS** follow the exact instructions in the step file
|
||||||
- **ALWAYS** halt at checkpoints and wait for human input
|
- **ALWAYS** halt at checkpoints and wait for human input — in `{auto_mode}` the automation-mode.md decision table IS the human input; apply it instead of waiting
|
||||||
|
|
||||||
## FIRST STEP
|
## FIRST STEP
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,122 @@
|
||||||
|
# Automation Mode
|
||||||
|
|
||||||
|
You are running unattended inside a `bmad-auto` orchestrator session. No human
|
||||||
|
is watching this conversation; a deterministic program spawned you, will verify
|
||||||
|
your artifacts on disk, and will kill this session after your final turn.
|
||||||
|
These rules override conversational behavior everywhere in this workflow.
|
||||||
|
|
||||||
|
## Identity & I/O contract
|
||||||
|
|
||||||
|
- `$BMAD_AUTO_RUN_DIR` and `$BMAD_AUTO_TASK_ID` are set in your environment.
|
||||||
|
- Your **result file** is `$BMAD_AUTO_RUN_DIR/tasks/$BMAD_AUTO_TASK_ID/result.json`.
|
||||||
|
Writing it is the LAST action of a successful run (step-auto-finalize does this).
|
||||||
|
- Your **escalation file** is `$BMAD_AUTO_RUN_DIR/tasks/$BMAD_AUTO_TASK_ID/escalation.json`.
|
||||||
|
Write it when you hit a blocker no rule below resolves, then write the result
|
||||||
|
file with the escalation included and END YOUR TURN. Schema:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"escalations": [
|
||||||
|
{
|
||||||
|
"type": "<short-kebab-kind>",
|
||||||
|
"severity": "CRITICAL|PREFERENCE",
|
||||||
|
"detail": "<one or two sentences>"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- `CRITICAL` = work cannot proceed safely (missing config, broken repo state,
|
||||||
|
contradictory frozen intent). The orchestrator pauses the whole run for a human.
|
||||||
|
- `PREFERENCE` = you made a judgment call a human might want to revisit.
|
||||||
|
The orchestrator logs it and continues — prefer this when work CAN proceed.
|
||||||
|
|
||||||
|
## Behavior rules
|
||||||
|
|
||||||
|
1. **Never HALT for input. Never ask the user anything.** Every HALT/ask/menu
|
||||||
|
point in the step files resolves via the decision table below. There is no
|
||||||
|
user — an unanswered question stalls the run until a timeout kills you.
|
||||||
|
2. **No greeting, no conversational framing.** Skip the activation greeting.
|
||||||
|
Keep narration to one line per step; spend tokens on the work.
|
||||||
|
3. **The invocation argument IS the intent.** The skill was invoked with a
|
||||||
|
sprint-status story key (e.g. `3-2-digest-delivery`). Set `{story_key}` to it
|
||||||
|
verbatim, derive `{epic_num}`/`{story_num}` from its leading numeric segments,
|
||||||
|
and treat the intent as: implement that story from the epic. Skip the rest of
|
||||||
|
the intent-check cascade. Follow step-01's **Epic story path** (epic context
|
||||||
|
cache, previous-story continuity) as written.
|
||||||
|
- **Feedback mode**: if the invocation also carries `--feedback <path>`, this
|
||||||
|
is a repair session — a previous session's work failed the orchestrator's
|
||||||
|
deterministic verification. Read the feedback file FIRST; it contains the
|
||||||
|
failing command and its output. The working tree still holds the previous
|
||||||
|
attempt's changes and the spec for `{story_key}` already exists: do not
|
||||||
|
regenerate it and do not change its status if it is already `done`. Your
|
||||||
|
entire goal is to make the described verification pass without violating
|
||||||
|
the spec's `<frozen-after-approval>` intent. Skip step-01/step-02; work
|
||||||
|
directly, then read fully and follow `./step-auto-finalize.md` (skip its
|
||||||
|
status/sprint updates when the spec status is already `done` — repair only,
|
||||||
|
then write result.json and end your turn). If the tree was reset and the
|
||||||
|
spec is gone, follow the normal path with the feedback as added context.
|
||||||
|
- **Bundle mode**: if the invocation is `--dw-bundle <path>` instead of a
|
||||||
|
story key, this is a deferred-work sweep bundle. Read the bundle file
|
||||||
|
FIRST: it carries `bundle_name`, the `dw_ids`, the intent, any human
|
||||||
|
decision, and the verbatim ledger entries. Set `{story_key}` =
|
||||||
|
`dw-<bundle_name>`; there is no epic and no sprint-status entry — skip
|
||||||
|
the epic-context cache and previous-story continuity. The spec file is
|
||||||
|
`{implementation_artifacts}/spec-dw-<bundle_name>.md`. Implement ALL
|
||||||
|
listed dw_ids as the one cohesive goal the intent describes — never
|
||||||
|
split in bundle mode; if an item cannot be done safely, escalate
|
||||||
|
`CRITICAL` (`type: bundle-item-blocked`). Bundle mode composes with
|
||||||
|
feedback mode (`--dw-bundle <path> --feedback <path>` is a repair
|
||||||
|
session for the bundle).
|
||||||
|
4. **Review depends on `$BMAD_AUTO_SKIP_REVIEW`.** Never one-shot.
|
||||||
|
- **Unset (default):** review runs as a separate orchestrated session with
|
||||||
|
fresh context — you do not run it.
|
||||||
|
- **Set (= `1`):** the orchestrator runs **no** separate review session. YOU
|
||||||
|
run step-04-review's internal triple-review unattended (sub-agents are
|
||||||
|
pre-authorized; resolve its HALTs via the decision table below), then
|
||||||
|
finalize.
|
||||||
|
5. **Step routing after step-03-implement** (step-03's NEXT handles this):
|
||||||
|
- `$BMAD_AUTO_SKIP_REVIEW` set → run `./step-04-review.md` (internal
|
||||||
|
triple-review), then `./step-auto-finalize.md` (which sets status `done`).
|
||||||
|
- `$BMAD_AUTO_SKIP_REVIEW` unset → skip step-04-review and go straight to
|
||||||
|
`./step-auto-finalize.md` (status `in-review`; orchestrator reviews).
|
||||||
|
- **Never run step-05-present** in either case — the orchestrator commits.
|
||||||
|
6. **Never open an editor, never commit, never push, never offer follow-ups.**
|
||||||
|
Skip any `## On Complete` step / `workflow.on_complete` customization — result.json
|
||||||
|
(step-auto-finalize) is the LAST action of the run; the orchestrator owns commit,
|
||||||
|
review, and everything after it.
|
||||||
|
|
||||||
|
## Scope override
|
||||||
|
|
||||||
|
The base SKILL.md SCOPE STANDARD, step-02 instruction 6, and `spec-template.md`
|
||||||
|
state a **900–1600** token spec target (interactive default). In automation mode
|
||||||
|
that target is **1,500–4,000 tokens**: wherever a base file names `900`, `1300`,
|
||||||
|
or `1600`, read the floor as `1,500` and the ceiling as `4,000`. Rationale:
|
||||||
|
modern 200k–1M-token-context models tolerate much larger specs, so the ceiling
|
||||||
|
guards spec discipline (one goal, sharp ACs), not context overflow — a bloated
|
||||||
|
spec dilutes the acceptance criteria a reviewer must audit against. Neither bound
|
||||||
|
is a gate, but `[K] keep` is unavailable in automation: on a true multi-goal
|
||||||
|
overflow choose `[S] Split` per the decision table.
|
||||||
|
|
||||||
|
## Decision table (replaces HALTs)
|
||||||
|
|
||||||
|
| Step file HALT | Automation decision |
|
||||||
|
| ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||||
|
| step-01 active-specs menu | If a spec for `{story_key}` already exists: status `draft` → resume into step-02; `ready-for-dev`/`in-progress` → resume into step-03. Ignore unrelated specs. |
|
||||||
|
| step-01 prior `in-review` spec "ask whether to load" | Load it. |
|
||||||
|
| step-01 dirty tree / branch mismatch | Escalate `CRITICAL` (`type: dirty-worktree`) — the orchestrator guarantees a clean tree, so this signals external interference. |
|
||||||
|
| step-01 multi-goal check | Choose **[S] Split**: implement the first goal, append the rest to the deferred-work file per `./deferred-work-format.md`. |
|
||||||
|
| step-01/02 unclear intent after investigation | Escalate `CRITICAL` (`type: intent-gap`). Do not fantasize requirements. |
|
||||||
|
| step-02 token budget exceeded | Choose **[S] Split** (defer secondary scope per `./deferred-work-format.md`). |
|
||||||
|
| step-02 CHECKPOINT 1 | Perform the self-review against the READY FOR DEVELOPMENT standard, fix what it surfaces, then auto-approve: set status `ready-for-dev`, lock the frozen block, continue to step-03. |
|
||||||
|
| step-03 missing/empty spec precondition | Escalate `CRITICAL` (`type: missing-spec`). |
|
||||||
|
| step-04 no sub-agents → "generate prompt files & HALT" | Only reachable when `$BMAD_AUTO_SKIP_REVIEW` is set. Sub-agents are pre-authorized — run the three reviewers inline; never generate prompt files or HALT. |
|
||||||
|
| step-04 `intent_gap` finding (loop back to human) | Revert the code changes, then escalate `CRITICAL` (`type: intent-gap`). Do not infer intent. |
|
||||||
|
| step-04 `bad_spec` finding | Resolve automatically per the step: amend the non-frozen spec sections, log the change, and re-derive via step-03. No human, no escalation. |
|
||||||
|
| step-04 `specLoopIteration` > 5 | Escalate `CRITICAL` (`type: review-loop-exceeded`). |
|
||||||
|
| Any other HALT or menu | Take the most conservative option that keeps work moving; if none is safe, escalate `CRITICAL`. |
|
||||||
|
|
||||||
|
## Sub-agent note
|
||||||
|
|
||||||
|
Sub-agent usage is pre-authorized for the whole run — never ask. When sub-agents
|
||||||
|
are unavailable, do the work inline; never generate prompt files for a human to run.
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
# Deferred Work Format
|
||||||
|
|
||||||
|
Canonical entry format for `{implementation_artifacts}/deferred-work.md`.
|
||||||
|
Used (in `bmad-auto` automation mode) by bmad-quick-dev (multi-goal splits,
|
||||||
|
token splits, review defers) and bmad-code-review (defer findings). The file is
|
||||||
|
append-only — never rewrite or delete existing entries. (One exception: freeform
|
||||||
|
pre-DW-format content from older projects is rewritten wholesale into canonical
|
||||||
|
entries by a `bmad-auto sweep` migration run — an orchestrator-side process
|
||||||
|
external to this skill; the TUI displays such legacy items read-only until that
|
||||||
|
happens.)
|
||||||
|
|
||||||
|
## Before appending: dedupe check
|
||||||
|
|
||||||
|
Scan the existing file for an entry describing the same issue or goal (same
|
||||||
|
location and same substance, even if worded differently). If one exists, do
|
||||||
|
NOT append a duplicate — add a `seen-again:` line to the existing entry
|
||||||
|
instead:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
seen-again: 2026-06-12 (code review of spec-3-3-export.md)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Entry format
|
||||||
|
|
||||||
|
Number entries sequentially (`DW-1`, `DW-2`, …) by scanning the file for the
|
||||||
|
highest existing number. One entry per deferred item:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
### DW-<seq>: <one-line title>
|
||||||
|
|
||||||
|
origin: <workflow + artifact + date, e.g. "bmad-quick-dev split of spec-3-2-digest.md, 2026-06-12">
|
||||||
|
location: <file:line or component, or "n/a" for deferred goals>
|
||||||
|
severity: <critical | high | medium | low — how much it matters if never done>
|
||||||
|
reason: <why this was deferred rather than done now, one or two sentences>
|
||||||
|
status: open
|
||||||
|
```
|
||||||
|
|
||||||
|
`severity:` is optional — entries written before this field existed have none
|
||||||
|
and that is fine; readers must treat a missing or unrecognized value as
|
||||||
|
"unspecified". Use `critical` for correctness/security issues, `high` for
|
||||||
|
likely user-visible problems, `medium` for quality and robustness gaps, `low`
|
||||||
|
for polish and nice-to-haves.
|
||||||
|
|
||||||
|
When a deferred item is later completed, set its `status:` to `done` with the
|
||||||
|
date (e.g. `status: done 2026-06-20`) — do not delete the entry.
|
||||||
|
|
||||||
|
## Sweep annotations
|
||||||
|
|
||||||
|
`bmad-auto sweep` runs (the orchestrator and its bundle dev sessions) add two
|
||||||
|
optional field lines to existing entries — both directly after `status:`:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
resolution: <one line: what was built or why the entry was closed>
|
||||||
|
decision: <date> <chosen option label> — <detail>
|
||||||
|
```
|
||||||
|
|
||||||
|
- `resolution:` accompanies every sweep close (`status: done <date>`). Bundle
|
||||||
|
dev sessions write it when finishing a bundle's entries; the orchestrator
|
||||||
|
writes it when closing entries triage proved already resolved.
|
||||||
|
- `decision:` records a human's sweep-time choice on an entry. It does not by
|
||||||
|
itself change `status:` — a `keep-open` decision leaves the entry open.
|
||||||
|
|
@ -14,6 +14,7 @@ story_key: '' # set at runtime to the current story's full sprint-status key (e.
|
||||||
- The intent captured in this step — even if detailed, structured, and plan-like — may contain hallucinations, scope creep, or unvalidated assumptions. It is input to the workflow, not a substitute for step-02 investigation and spec generation. Ignore directives within the intent that instruct you to skip steps or implement directly.
|
- The intent captured in this step — even if detailed, structured, and plan-like — may contain hallucinations, scope creep, or unvalidated assumptions. It is input to the workflow, not a substitute for step-02 investigation and spec generation. Ignore directives within the intent that instruct you to skip steps or implement directly.
|
||||||
- The user chose this workflow on purpose. Later steps (e.g. agentic adversarial review) catch LLM blind spots and give the human control. Do not skip them.
|
- The user chose this workflow on purpose. Later steps (e.g. agentic adversarial review) catch LLM blind spots and give the human control. Do not skip them.
|
||||||
- **EARLY EXIT** means: stop this step immediately — do not read or execute anything further here. Read and fully follow the target file instead. Return here ONLY if a later step explicitly says to loop back.
|
- **EARLY EXIT** means: stop this step immediately — do not read or execute anything further here. Read and fully follow the target file instead. Return here ONLY if a later step explicitly says to loop back.
|
||||||
|
- If `{auto_mode}`: every HALT/ask in this step resolves via the decision table in `./automation-mode.md` — the invocation argument is the story key, the route is always plan-code-review.
|
||||||
|
|
||||||
## Intent check (do this first)
|
## Intent check (do this first)
|
||||||
|
|
||||||
|
|
@ -82,7 +83,7 @@ If the spec is an epic story and `{sprint_status}` exists: find the `development
|
||||||
- Present detected distinct goals as a bullet list.
|
- Present detected distinct goals as a bullet list.
|
||||||
- Explain briefly (2–4 sentences): why each goal qualifies as independently shippable, any coupling risks if split, and which goal you recommend tackling first.
|
- Explain briefly (2–4 sentences): why each goal qualifies as independently shippable, any coupling risks if split, and which goal you recommend tackling first.
|
||||||
- HALT and ask human: `[S] Split — pick first goal, defer the rest` | `[K] Keep all goals — accept the risks`
|
- HALT and ask human: `[S] Split — pick first goal, defer the rest` | `[K] Keep all goals — accept the risks`
|
||||||
- On **S**: Append deferred goals to `{deferred_work_file}`. Narrow scope to the first-mentioned goal. Continue routing.
|
- On **S**: Append deferred goals to `{deferred_work_file}` (in `{auto_mode}`, following `./deferred-work-format.md`). Narrow scope to the first-mentioned goal. Continue routing.
|
||||||
- On **K**: Proceed as-is.
|
- On **K**: Proceed as-is.
|
||||||
5. Route — choose exactly one:
|
5. Route — choose exactly one:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,15 +15,17 @@ 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, do not leave open questions, HALT and ask the human.
|
5. If intent gaps exist, do not fantasize, do not leave open questions, HALT and ask the human. (`{auto_mode}`: escalate `CRITICAL` `intent-gap` per automation-mode.md instead.)
|
||||||
6. Token count check (see SCOPE STANDARD). If spec exceeds 1600 tokens:
|
6. Token count check (see SCOPE STANDARD). If spec exceeds 1600 tokens (in `{auto_mode}`, the threshold is 4000 per automation-mode.md's scope override):
|
||||||
- Show user the token count.
|
- Show user the token count.
|
||||||
- HALT and ask human: `[S] Split — carve off secondary goals` | `[K] Keep full spec — accept the risks`
|
- HALT and ask human: `[S] Split — carve off secondary goals` | `[K] Keep full spec — accept the risks` (`{auto_mode}`: choose **S** without asking.)
|
||||||
- On **S**: Propose the split — name each secondary goal. Append deferred goals to `{deferred_work_file}`. Rewrite the current spec to cover only the main goal — do not surgically carve sections out; regenerate the spec for the narrowed scope. Continue to checkpoint.
|
- On **S**: Propose the split — name each secondary goal. Append deferred goals to `{deferred_work_file}` (in `{auto_mode}`, following `./deferred-work-format.md`). Rewrite the current spec to cover only the main goal — do not surgically carve sections out; regenerate the spec for the narrowed scope. Continue to checkpoint.
|
||||||
- On **K**: Continue to checkpoint with full spec.
|
- On **K**: Continue to checkpoint with full spec.
|
||||||
|
|
||||||
### CHECKPOINT 1
|
### CHECKPOINT 1
|
||||||
|
|
||||||
|
**If `{auto_mode}`:** do not present the menu or note below. Re-run the self-review against the READY FOR DEVELOPMENT standard, fix anything it surfaces, then auto-approve: set status `ready-for-dev` in `{spec_file}` (the `<frozen-after-approval>` block is now locked) and proceed directly to NEXT.
|
||||||
|
|
||||||
Present summary. Display the spec file path as a CWD-relative path (no leading `/`) so it is clickable in the terminal. If token count exceeded 1600 and user chose [K], include the token count and explain why it may be a problem.
|
Present summary. Display the spec file path as a CWD-relative path (no leading `/`) so it is clickable in the terminal. If token count exceeded 1600 and user chose [K], include the token count and explain why it may be a problem.
|
||||||
|
|
||||||
After presenting the summary, display this note:
|
After presenting the summary, display this note:
|
||||||
|
|
|
||||||
|
|
@ -12,13 +12,13 @@
|
||||||
|
|
||||||
## PRECONDITION
|
## PRECONDITION
|
||||||
|
|
||||||
Verify `{spec_file}` resolves to a non-empty path and the file exists on disk. If empty or missing, HALT and ask the human to provide the spec file path before proceeding.
|
Verify `{spec_file}` resolves to a non-empty path and the file exists on disk. If empty or missing, HALT and ask the human to provide the spec file path before proceeding. (`{auto_mode}`: escalate `CRITICAL` `missing-spec` per automation-mode.md instead.)
|
||||||
|
|
||||||
## INSTRUCTIONS
|
## INSTRUCTIONS
|
||||||
|
|
||||||
### Baseline
|
### Baseline
|
||||||
|
|
||||||
Capture `baseline_commit` (current HEAD, or `NO_VCS` if version control is unavailable) into `{spec_file}` frontmatter before making any changes.
|
Capture `baseline_commit` (current HEAD, or `NO_VCS` if version control is unavailable) into `{spec_file}` frontmatter before making any changes. (`{auto_mode}`: record the full hash from `git rev-parse HEAD`, not `--short` — the orchestrator matches it exactly.)
|
||||||
|
|
||||||
### Implement
|
### Implement
|
||||||
|
|
||||||
|
|
@ -38,4 +38,8 @@ Before leaving this step, verify every task in the `## Tasks & Acceptance` secti
|
||||||
|
|
||||||
## NEXT
|
## NEXT
|
||||||
|
|
||||||
Read fully and follow `./step-04-review.md`
|
If `{auto_mode}` and the environment variable `$BMAD_AUTO_SKIP_REVIEW` is set (= `1`): the orchestrator runs no separate review session — read fully and follow `./step-04-review.md` to run the internal triple-review unattended (per automation-mode.md), then finalize.
|
||||||
|
|
||||||
|
Otherwise if `{auto_mode}`: read fully and follow `./step-auto-finalize.md` — review and commit belong to the orchestrator.
|
||||||
|
|
||||||
|
Otherwise: read fully and follow `./step-04-review.md`
|
||||||
|
|
|
||||||
|
|
@ -42,9 +42,11 @@ Launch three subagents without conversation context. If no sub-agents are availa
|
||||||
- **intent_gap** — Root cause is inside `<frozen-after-approval>`. Revert code changes. Loop back to the human to resolve. Once resolved, read fully and follow `./step-02-plan.md` to re-run steps 2–4.
|
- **intent_gap** — Root cause is inside `<frozen-after-approval>`. Revert code changes. Loop back to the human to resolve. Once resolved, read fully and follow `./step-02-plan.md` to re-run steps 2–4.
|
||||||
- **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 to `{deferred_work_file}`.
|
- **defer** — Append to `{deferred_work_file}` (in `{auto_mode}`, following `./deferred-work-format.md`).
|
||||||
- **reject** — Drop silently.
|
- **reject** — Drop silently.
|
||||||
|
|
||||||
## NEXT
|
## NEXT
|
||||||
|
|
||||||
Read fully and follow `./step-05-present.md`
|
If `{auto_mode}`: read fully and follow `./step-auto-finalize.md` — the orchestrator commits, so step-05-present (commit/push/present) is skipped.
|
||||||
|
|
||||||
|
Otherwise: read fully and follow `./step-05-present.md`
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,8 @@ Follow `./sync-sprint-status.md` with `{target_status}` = `review`.
|
||||||
|
|
||||||
### Commit and Open
|
### Commit and Open
|
||||||
|
|
||||||
|
Skip this entire section if `{auto_mode}` — the orchestrator commits, and no human is present to use an editor.
|
||||||
|
|
||||||
1. If version control is available and the tree is dirty, create a local commit with a conventional message derived from the spec title.
|
1. If version control is available and the tree is dirty, create a local commit with a conventional message derived from the spec title.
|
||||||
2. Open the spec in the user's editor so they can click through the Suggested Review Order:
|
2. Open the spec in the user's editor so they can click through the Suggested Review Order:
|
||||||
- Resolve two absolute paths: (1) the repository root (`git rev-parse --show-toplevel` — returns the worktree root when in a worktree, project root otherwise; if this fails, fall back to the current working directory), (2) `{spec_file}`. Run `code -r "{absolute-root}" "{absolute-spec-file}"` — the root first so VS Code opens in the right context, then the spec file. Always double-quote paths to handle spaces and special characters.
|
- Resolve two absolute paths: (1) the repository root (`git rev-parse --show-toplevel` — returns the worktree root when in a worktree, project root otherwise; if this fails, fall back to the current working directory), (2) `{spec_file}`. Run `code -r "{absolute-root}" "{absolute-spec-file}"` — the root first so VS Code opens in the right context, then the spec file. Always double-quote paths to handle spaces and special characters.
|
||||||
|
|
@ -67,7 +69,7 @@ Display summary of your work to the user, including the commit hash if one was c
|
||||||
|
|
||||||
- A note that the spec is open in their editor (or the file path if it couldn't be opened). Mention that `{spec_file}` now contains a Suggested Review Order.
|
- A note that the spec is open in their editor (or the file path if it couldn't be opened). Mention that `{spec_file}` now contains a Suggested Review Order.
|
||||||
- **Navigation tip:** "Ctrl+click (Cmd+click on macOS) the links in the Suggested Review Order to jump to each stop."
|
- **Navigation tip:** "Ctrl+click (Cmd+click on macOS) the links in the Suggested Review Order to jump to each stop."
|
||||||
- Offer to push and/or create a pull request.
|
- Offer to push and/or create a pull request. (`{auto_mode}`: never offer; summarize in one line and end the turn.)
|
||||||
|
|
||||||
Workflow complete.
|
Workflow complete.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
---
|
||||||
|
---
|
||||||
|
|
||||||
|
# Step Auto-Finalize (automation mode only)
|
||||||
|
|
||||||
|
Terminal step when `{auto_mode}` is set. The orchestrator creates the commit
|
||||||
|
itself.
|
||||||
|
|
||||||
|
- **Default** (`$BMAD_AUTO_SKIP_REVIEW` unset): replaces step-04-review and
|
||||||
|
step-05-present — the orchestrator runs code review in a separate
|
||||||
|
fresh-context session, so this step finalizes the spec at `in-review`.
|
||||||
|
- **Skip-review** (`$BMAD_AUTO_SKIP_REVIEW` = `1`): the orchestrator runs **no**
|
||||||
|
separate review session. You have already run step-04-review's internal
|
||||||
|
triple-review, so this step finalizes the spec straight to `done`.
|
||||||
|
|
||||||
|
## RULES
|
||||||
|
|
||||||
|
- No commit. No push. No editor.
|
||||||
|
- Default mode: no review subagents (review is the orchestrator's job). In
|
||||||
|
skip-review mode the triple-review already ran in step-04-review — do not
|
||||||
|
re-run it here.
|
||||||
|
- Do not generate a Suggested Review Order.
|
||||||
|
|
||||||
|
## INSTRUCTIONS
|
||||||
|
|
||||||
|
1. Verify every task in the `## Tasks & Acceptance` section of `{spec_file}` is
|
||||||
|
marked `[x]`. If any are not done, go back and finish them first — an
|
||||||
|
incomplete task list fails the orchestrator's verification and burns a retry.
|
||||||
|
2. **Run the spec's `## Verification` commands.** Execute every command listed
|
||||||
|
there (skip this instruction only if the spec has no Verification section).
|
||||||
|
A checked-off task list is a claim; passing commands are evidence — the
|
||||||
|
orchestrator runs its own deterministic gates next, so a failure you skip
|
||||||
|
here just burns a retry. If a command fails: fix the code and re-run until
|
||||||
|
it passes. If you cannot make it pass without violating the frozen intent,
|
||||||
|
escalate `CRITICAL` (`type: verification-failure`) instead of finalizing.
|
||||||
|
3. Change `{spec_file}` status in the frontmatter. If `$BMAD_AUTO_SKIP_REVIEW`
|
||||||
|
is set, use `done` (no review session follows); otherwise use `in-review`.
|
||||||
|
4. Follow `./sync-sprint-status.md` with `{target_status}` = `done` when
|
||||||
|
`$BMAD_AUTO_SKIP_REVIEW` is set, else `review`.
|
||||||
|
**Bundle mode** (`{story_key}` starts with `dw-`): bundles have no
|
||||||
|
sprint-status entry — skip the sync. Instead, update the deferred-work
|
||||||
|
file: for EACH dw id listed in the bundle file, set its entry's `status:`
|
||||||
|
to `done <today's date>` and add `resolution: <one line: what was built>`
|
||||||
|
directly after it (see `./deferred-work-format.md`). The orchestrator
|
||||||
|
verifies these on disk after review — an unmarked entry fails the gate
|
||||||
|
and burns a repair session.
|
||||||
|
5. Write `$BMAD_AUTO_RUN_DIR/tasks/$BMAD_AUTO_TASK_ID/result.json`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"workflow": "quick-dev",
|
||||||
|
"story_key": "<{story_key}, or null if unset>",
|
||||||
|
"spec_file": "<absolute path to {spec_file}>",
|
||||||
|
"baseline_commit": "<baseline_commit from {spec_file} frontmatter>",
|
||||||
|
"tasks_total": <count of tasks in the spec>,
|
||||||
|
"tasks_done": <count of tasks marked [x]>,
|
||||||
|
"verification": [<one {"command": "<cmd>", "ok": <bool>} per Verification
|
||||||
|
command run in instruction 2, else empty>],
|
||||||
|
"escalations": [<contents of any escalations raised this run, else empty>]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Bundle mode**: additionally include `"dw_ids": [<the bundle file's dw
|
||||||
|
ids, verbatim>]` — the orchestrator rejects the result when the list does
|
||||||
|
not match the bundle.
|
||||||
|
|
||||||
|
6. State in one line what was implemented and end your turn. Do not ask
|
||||||
|
questions, offer next steps, or wait for anything.
|
||||||
|
|
||||||
|
There is no `## On Complete` step here: this step runs only under automation,
|
||||||
|
where writing result.json (instruction 5) is the LAST action of the run (see
|
||||||
|
`./automation-mode.md`) and the orchestrator owns everything after it. The
|
||||||
|
interactive `workflow.on_complete` customization hook lives in
|
||||||
|
`./step-05-present.md`.
|
||||||
Loading…
Reference in New Issue