The gate ported from #2398 defended against runtime customization
indirection: agents guessed resolver outputs instead of executing them,
silently skipping append steps. render.py inlines the prepend/append
entries into the rendered workflow.md, so there is nothing left to
short-circuit, and each inlined list already carries its own execute-
in-order imperative. In the default install both lists render as
_None._ and the gate is pure noise.
The "rendered N files" progress line was pure diagnostic noise. The shim
already tells the LLM to ignore stderr and follow the stdout instruction, so
on success render.py now prints only the "read and follow ..." line.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The shim called bare `python`, which can resolve to Python 2 or be absent;
render.py needs 3.11+ for tomllib. Spell out python3 and the version
requirement. Also make the exit code authoritative: on a non-zero exit
(including an uncaught crash that writes only to stderr), do not proceed --
report what was printed and stop.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
render.py now merges the three customize layers (customize.toml ->
custom/bmad-quick-dev.toml -> .user.toml) with the same structural rules as
resolve_customization.py and inlines the resolved [workflow] values, so no
{workflow.*} placeholder survives. workflow.md drops its Step 1 runtime
resolver + manual-merge fallback; step-05 and step-oneshot drop their runtime
workflow.on_complete calls. The shared resolve_customization.py and every
other skill are untouched. Smoke test extended with a [workflow] override
fixture covering inlining, array append, and no-leak assertions.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The bare `python render.py` shim assumes the agent's working directory is
the skill directory, but agents run from the project root, so the script
is not found. Reference it as `{skill-root}/render.py` — BMAD's standard
token for a skill's installed directory, already used by every other
skill's resolve_customization.py invocation — and add the one-line
`{skill-root}` explainer so the model resolves it from an instruction
rather than guessing. Interpreter stays `python`; the python vs python3
choice is a separate cross-platform concern.
Load the four config layers through a load_toml helper that marks the
base _bmad/config.toml as required. A missing, unparseable, or unreadable
base now prints a HALT directive to stdout and exits, instead of being
silently skipped and then crashing downstream with a KeyError when a
derived value (e.g. implementation_artifacts) is absent. Optional layers
still warn on stderr and fall back to empty. Merge semantics are
unchanged (dict-aware deep merge, override wins for lists and scalars).
render.py rebuilds from scratch per the docstring, but
makedirs(exist_ok=True) only overwrites files that still exist in
the source — stale outputs from renamed/deleted source files linger
in _bmad/render/bmad-quick-dev/ forever. Remove every .md in the
render dir before the render loop; keep the dir itself and any
non-.md files.
Part of plan-quick-dev-python-config-hardening.md (F5).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Python text-mode open() with the platform default performs universal-
newline translation: on Windows, LF source files get written as CRLF,
producing spurious diffs when rendered output is compared against
source. Pass newline="" on both the source read and the rendered
write so line endings pass through verbatim.
Part of plan-quick-dev-python-config-hardening.md (F4).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
On Windows, os.path.join returns backslash-separated paths that can
misrender as escape sequences when later concatenated into POSIX
shell strings or regexes. Normalize the project root to forward
slashes after find_project_root, and use posixpath.join for every
path that gets baked into rendered .md files or joined into config
values. os.makedirs and os.listdir accept forward-slash paths on
Windows, so their call sites stay as-is.
Part of plan-quick-dev-python-config-hardening.md (F3).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Single happy path: central _bmad/config.toml with four-layer merge,
Python 3.11+ required (no ImportError guard), HALT if config missing.
Deletes load_flat_yaml, the YAML fallback branch, the setdefault block
for planning_artifacts/implementation_artifacts/communication_language,
and the tomllib ImportError fallback.
Part of plan-quick-dev-python-config-hardening.md (F0).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Move compile-time variable substitution out of the LLM and into a
deterministic Python step. SKILL.md becomes a two-line stdout-dispatch
shim that runs render.py and follows the instruction it prints. The
renderer reads BMad configuration from the central four-layer TOML
surface introduced in #2285 (_bmad/config.toml plus config.user.toml
and the two _bmad/custom/ overrides), with a fallback to the legacy
per-module _bmad/bmm/config.yaml for pre-#2285 installs.
Compile-time refs ({{.var}}) get substituted at render time. LLM-runtime
refs ({var}) pass through untouched.
Renderer (render.py)
- Python 3 stdlib only (tomllib, already bundled since 3.11). UTF-8 I/O.
Every invocation rebuilds from scratch — no hash, no cache.
- find_project_root walks up from cwd; HALT to stdout if no _bmad/
is found anywhere on the path.
- load_central_config deep-merges the four TOML layers in priority
order (base-team → base-user → custom-team → custom-user) so user
overrides in _bmad/custom/config.user.toml win over installer-
regenerated base values. flatten_central_config lifts scalar keys
from [core] and [modules.bmm] into the renderer's flat namespace;
module keys beat core on collision (matches the installer's own
core-key-stripping behavior).
- When _bmad/config.toml is absent, falls through to the legacy
flat-YAML parser for _bmad/bmm/config.yaml — the renderer keeps
working across the #2285 transition.
- {{.var}} substitution; unresolved refs emit empty string (Go
missingkey=zero semantics).
- Smart defaults for planning_artifacts / implementation_artifacts /
communication_language applied after config load. Derives
sprint_status / deferred_work_file from implementation_artifacts.
{{.main_config}} points at whichever surface was actually read.
- Renders every .md in the skill dir except SKILL.md to
{project-root}/_bmad/render/bmad-quick-dev/.
- On success, stderr summary plus a single stdout line:
"read and follow {workflow_md}". On failure, stdout HALT directive —
per the Anthropic skills spec, script stdout is the defined agent-
communication channel.
Skill entry (SKILL.md)
- Two-line shim: run python render.py, follow stdout. No template
tokens in SKILL.md itself.
Template conversions
- workflow.md, step-01..05, step-oneshot, sync-sprint-status: convert
every compile-time {var} reference to {{.var}}. Runtime refs
preserved.
- spec-template.md untouched (single-curly comment hint stays as
documentation).
Skill-prose cleanups bundled in
- Remove dead step-file frontmatter: empty-string variable declarations
(spec_file, story_key, diff_output, review_mode) in quick-dev step-01
and code-review step-01; empty --- --- blocks in step-03 and step-05;
the specLoopIteration counter init moved from step-04 frontmatter into
the step body where first-entry vs loopback semantics are explicit.
- Unify the language rule across all six quick-dev step files plus
workflow.md.
Tooling
- tools/validate-skills.js: add TPL-01 rule. Files whose name contains
"template" must not contain compile-time {{.var}} substitutions.
Template files seed durable, version-controlled artifacts that
execute on other machines; baking a value at render time would
freeze a machine-local path into every downstream artifact.
- tools/validate-file-refs.js: add render/ to INSTALL_ONLY_PATHS so
the validator recognizes the runtime-generated buffer.
- tools/skill-validator.md: document TPL-01; deterministic rule count
bumped from 14 to 15.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The Blind Hunter subagent intentionally has no tool access, but the
review steps never said how {diff_output} should be delivered. Orchestrators
typically wrote the diff to a temp file and asked the agent to read it,
which silently fails (0 tool calls), and the 10-finding requirement then
pushes the agent to hallucinate findings against code it never saw.
State explicitly that the diff is passed inline in the subagent prompt,
in both bmad-code-review step 2 and bmad-quick-dev step 4.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* fix(skills): strengthen activation guardrails for all workflow skills
Add explicit "Activation is complete" boundary markers that require
confirming activation_steps_prepend and activation_steps_append were
fully executed before beginning the main workflow.
Previously, the guardrail was either missing (bmad-product-brief,
bmad-prd, bmad-investigate) or too weak ("Begin the workflow below").
LLM agents would short-circuit complex activation sequences (INCLUDE →
READ → RUN → CHECK → FILTER → CD) by guessing variables instead of
executing steps in order, causing append steps and on_complete hooks
to be silently skipped.
The new guardrail explicitly names both prepend and append steps,
requiring confirmation before proceeding. This prevents agents from
starting the main workflow in parallel with activation.
23 skills updated: bmad-product-brief, bmad-prd, bmad-prfaq,
bmad-investigate, bmad-create-story, bmad-dev-story,
bmad-quick-dev, bmad-code-review, bmad-correct-course,
bmad-sprint-planning, bmad-sprint-status, bmad-retrospective,
bmad-qa-generate-e2e-tests, bmad-checkpoint-preview,
bmad-check-implementation-readiness, bmad-create-architecture,
bmad-create-epics-and-stories, bmad-generate-project-context,
bmad-create-ux-design, bmad-document-project, bmad-market-research,
bmad-technical-research, bmad-domain-research.
* fix(skills): extend activation gate to agent + new skills, refine placement
- bmad-product-brief / bmad-prd: pull activation_steps_append out of
the numbered list so the sentinel reads as a paragraph break, not
as the next list item.
- bmad-investigate: move the sentinel above Step 7 (routing) — Step 7
is workflow routing, not activation; the gate must fire first.
- bmad-agent-{analyst,tech-writer,pm,ux-designer,architect,dev}: add
the same gate between Step 7 (append) and Step 8 (menu dispatch).
Persona skills had the same short-circuit risk but no sentinel.
- bmad-ux, bmad-spec: new skills introduced on main after this branch
forked; apply the same gate so the pattern stays consistent.
- removals.txt: register bmad-create-ux-design as renamed to bmad-ux.
---------
Co-authored-by: Brian Madison <bmadcode@gmail.com>
* feat: extend customize.toml to all 6 developer-execution workflows (#2303)
Add uniform customization support to dev-story, code-review,
sprint-planning, sprint-status, quick-dev, and checkpoint-preview,
matching the same 4 extension points (activation_steps_prepend,
activation_steps_append, persistent_facts, on_complete) already
available on 17 BMM workflows from PR #2287.
- Create customize.toml for each workflow
- Add 6-step activation block to SKILL.md (merge workflow.md
content in, delete workflow.md per PR #2287 pattern)
- Wire on_complete at terminal steps (inline <action> for XML
workflows, ## On Complete section for step-file workflows)
- Fix pre-existing step number reference in dev-story (Step 6 → 9)
* fix: correct goto step="6" → step="9" in dev-story
The XML goto at line 203 still pointed to step 6 ("Author
comprehensive tests") instead of step 9 ("Story completion and mark
for review"), which is the actual completion gate. This was the
same class of pre-existing bug fixed in the text (M-1) but
missed in the XML action.
---------
Co-authored-by: Brian <bmadcode@gmail.com>
* feat(quick-dev): sync sprint-status.yaml on epic-story implementation
When quick-dev infers the intent is an epic story, resolve the full
sprint-status key during step-01's previous-story-continuity sub-step,
then sync sprint-status.yaml at the two workflow boundaries code-review
already owns the trailing half of:
- step-03 start: flip the story to in-progress and lift the parent
epic out of backlog if needed.
- step-05 end: flip the story to review. Code-review keeps ownership
of review -> done.
Resolution uses exact numeric-segment equality on the {epic}-{story}
prefix (never string-prefix match), so 1-1 no longer collides with
1-10. Both sync blocks are idempotent so step-04 loopbacks do not
clobber human edits or bump last_updated without cause. Skips silently
when sprint-status.yaml is missing or the intent is not an epic story.
* feat(quick-dev): add sprint-status sync to one-shot route
Epic stories do get implemented via one-shot in practice. Add the same
in-progress / review sync pair that step-03 and step-05 already have,
with identical idempotency guards and skip-on-missing behavior.
* refactor(quick-dev): extract sprint-status sync into shared file
Replace inline sync blocks in step-03, step-05, and step-oneshot with
one-line callouts to sync-sprint-status.md. The shared file owns all
edge-case handling (idempotency, epic lift, missing file/key) and is
parameterized by {target_status}. Any future route picks it up with a
single Follow line.
* fix(quick-dev): resolve story_key on early-exit resume paths
Extract story-key resolution into a shared subsection referenced by
all early-exit paths and INSTRUCTIONS, ensuring sprint-status sync
works for resumed epic stories.
* refactor(quick-dev): tighten story-key resolution prompt
Remove mechanical details the LLM can infer; keep only the
collision-prevention constraint.
Prevent review subagents from being downgraded to cheaper models.
Rare findings from the Acceptance Auditor tend to be high-severity,
and research shows smaller models have worse recall on rare-event
detection.
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(quick-dev): add epic context compilation to step-01
Fork step-01 context loading: epic stories get a sub-agent that
compiles planning docs into a cached epic-{N}-context.md, while
freeform intents keep the lightweight directory-listing path.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(quick-dev): tighten epic context loading per PR review
- Validate cached epic-<N>-context.md is non-empty and starts with the
expected header before loading; treat invalid cache as missing.
- Replace inline {N} placeholders with <N> so the skill validator does
not flag them as unresolved workflow variables.
- Replace ambiguous "fall back to path B" with an explicit instruction
to scan/load planning artifacts using path B's procedure, with a note
not to re-evaluate path B's gating clause.
Addresses CodeRabbit and Augment review comments on PR #2218.
* refactor(quick-dev): tighten compile-epic-context prompt
- Restructure with Task/Steps opening and Exact Output Format section.
- Switch Stories template to bullet form for clarity.
- Add "no hallucination" and explicit "omit empty sections except Goal
and Stories" rules.
- Use <N> instead of {N} in the filename for consistency with step-01.
* refactor(quick-dev): restructure epic-story context loading
Reshape path A of step-01 into five explicit numbered steps and add an
inline-compilation fallback for runtimes that cannot spawn sub-agents
(Copilot, Codex, local Ollama, older Claude).
- Pull cache validity, compilation, verification, and continuity into
separate numbered steps instead of nested paragraphs.
- Define "valid cached context" upfront: non-empty and starts with
`# Epic <N> Context:`.
- Add inline-compilation fallback: runtimes without sub-agent support
read compile-epic-context.md and follow it directly.
- Make previous-story continuity run regardless of which context source
succeeded (cache hit, fresh compilation, or path-B raw fallback).
* fix(quick-dev): address review findings on epic context compilation
- Add freshness check to cached epic-N-context.md (invalidate when any
planning artifact is newer)
- Remove the silent fall-back-to-raw-planning-docs path on compile
failure; HALT and report instead
- Add explicit "ambiguous → freeform" tiebreakers for both the path A
header and the epic-number identification step
- Drop "verbatim" from compile-epic-context.md format header to resolve
the verbatim-vs-omit-empty contradiction
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(quick-dev): improve checkpoint 1 UX with clickable link, external editing note, and change detection
Display spec file path as clickable CWD-relative link alongside the
summary. Inform users they can open the spec in another session with
any tool before approving. On approval, re-read the spec from disk
and acknowledge any external edits before proceeding.
* fix(quick-dev): tighten checkpoint 1 [A] flow wording
- Remove stray 'and options' from the editing-note intro so the note's
position relative to the [A]/[E] menu is unambiguous.
- Restructure the [A] bullet into explicit missing/exists branches so
the missing-file HALT cannot fall through to status updates and
recreate a deleted spec.
Addresses augmentcode review comments on PR #2217.
* docs(quick-dev): rewrite checkpoint 1 editing-note
- Drop boilerplate opener about the spec being a regular file.
- Enumerate concrete options: editor, in-session Q&A, or bmad-advanced-elicitation / bmad-party-mode / bmad-code-review skills.
- Flag that skills should ideally run in another session to avoid context bloat.
- Change "add this note" to "display this note" for precision.
* refactor(quick-dev): eliminate spec-wip.md singleton
Write directly to spec-{slug}.md with status: draft instead of using
a shared spec-wip.md file. Use draft status for resume detection in
step-01. Removes wipFile variable from all step frontmatter and
workflow initialization.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(quick-dev): address PR review findings
- step-02: preserve Intent block on draft resume instead of regenerating from template (F1)
- step-01: resume existing draft on slug collision rather than creating -2 duplicate (F3)
- step-01: recognize `done` status and ingest as context instead of silently re-implementing (F4)
- step-oneshot: remove unused spec_file frontmatter declaration (F6)
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When quick-dev infers the intent is an epic story, it now scans for
completed specs from the same epic and loads the most recent one to
extract Code Map, Design Notes, Spec Change Log, and task list as
continuity context for planning.
Teach quick-dev step-01 what BMAD phase 1-3 planning artifacts are (PRD,
architecture, UX, epics, product brief) so it can selectively load relevant
docs instead of guessing from code alone. Remove hard cap of 3 on spec
context field, replacing with judgment guidance. Instruct step-03 to
explicitly pass context files to the implementation sub-agent.
* feat(quick-dev): generate spec trace file for one-shot route
One-shot changes now leave a lightweight spec file with frontmatter,
intent summary, and suggested review order — eliminating numbering
gaps when quick-dev is used as the primary dev loop.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor(quick-dev): reference spec template instead of inlining structure
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor(quick-dev): deduplicate slug derivation and clarify title variable
Extract shared slug derivation logic above the route fork in step-01 so
both one-shot and plan-code-review routes use a single instruction block.
Add explicit title variable assignment in step-oneshot before it is
referenced in the Generate Spec Trace section.
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The frontmatter `title` field is the single source of truth.
The duplicate `# {title}` H1 heading was redundant and has been removed.
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Short-circuit evaluation in step-01: explicit argument → conversation
context → full artifact scan. Stops prompting as soon as intent is
unambiguous. All existing scan behaviors preserved in tier 3.
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds a Self-Check subsection at the end of step-03 that forces the
implementing agent to verify all tasks are complete and mark checkboxes
before handing off to the review step.
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(quick-dev): use absolute paths in code -r invocations
Agent CWD may differ from the project root in worktree setups,
causing relative paths to silently fail. Resolve paths via
git rev-parse --show-toplevel before invoking code -r.
* fix(quick-dev): add CWD fallback when git rev-parse fails
Adds graceful fallback to current working directory when
git rev-parse --show-toplevel fails (VCS unavailable).
* fix(quick-dev): make file path references clickable
Spec-file links use paths relative to the spec file's
directory (clickable in VS Code). Terminal output paths
use CWD-relative format for terminal clickability.
* fix(quick-dev): add :line suffix to step-oneshot path example
Aligns the file path example in step-oneshot.md with the clickable
`:line` format already enforced in step-03-implement.md and
step-05-present.md.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Switch skill discovery gate from requiring bmad-skill-manifest.yaml with
type: skill to detecting any directory with a valid SKILL.md (frontmatter
name + description, name matches directory name). Delete 34 stub manifests
that carried no data beyond type: skill. Agent manifests (9) are retained
for persona metadata consumed by agent-manifest.csv.
Step-02 now displays the finalized spec file path as a CWD-relative
clickable link after approval. Step-05 clarifies the dual convention:
project-root-relative paths (leading /) for spec-file content, CWD-relative
paths (no leading /) for terminal/conversation output. One-shot review
order explicitly uses CWD-relative path:line format.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor: consolidate agents into phase-based skill directories
Remove separate agent/workflow/skill directories (src/bmm/agents,
src/bmm/workflows, src/core/skills, src/utility/agent-components) and
reorganize all content into phase-based structures under src/bmm-skills
(1-analysis, 2-plan-workflows, 3-solutioning, 4-implementation) and
src/core-skills. Eliminates the agent/skill distinction by treating
agents as skills within their workflow phase.
* fix: update broken file references to use new bmm-skills paths
* docs: update all references for unified bmad-quick-dev workflow
Remove all references to the old separate bmad-quick-spec and
bmad-quick-dev-new-preview workflows. The new bmad-quick-dev is a
unified workflow that handles intent clarification, planning,
implementation, review, and presentation in a single run.
Updated files across English docs, Chinese translations, source
skill manifests, website diagram, and build tooling.