Reinstates the bmad-dev-auto template renderer temporarily reverted in
#2598, hardened. SKILL.md becomes a thin dispatch stub (uv run
render.py) and the workflow/step files are rendered at skill entry with
central-config values, the resolved [workflow] customization block, and
absolute sibling cross-references baked in — no runtime config loading
or resolve_customization.py call remains.
Fail-early contract: anything the renderer can detect wrong HALTs on
stdout with an error informative enough for the presiding inference to
act on — missing, empty, or non-string config keys referenced by the
sources; unknown or malformed [workflow] values (including non-scalar
layer fields); unreadable or non-UTF-8 sources; and failed publish
swaps. A publish swap lost to a concurrent renderer that already
published byte-identical content remains a success (rendering is
deterministic), and the last-good render is preserved for the next run
on any other swap failure.
Both render.py copies (dev-auto, quick-dev) change in lockstep; a drift
test pins them byte-for-byte modulo skill names. New
test/test-dev-auto-renderer.js covers rendering, overrides, review-layer
materialization, every HALT path, and injected-rename publish failures;
the quick-dev suite gains the no-op re-render and dispatch-line pins.
Back out the dev-auto render.py workflow entry change from #2587,
including the follow-up renderer-only fix on top of it, so the skill
returns to the pre-renderer SKILL.md flow while the longer fixes are
worked separately.
Propagate bmad-quick-dev's render.py pattern (#2281) to bmad-dev-auto.
SKILL.md becomes the two-line stdout-dispatch shim that runs render.py
via uv and follows the instruction it prints; the old SKILL.md body
moves to workflow.md, rendered to _bmad/render/bmad-dev-auto/ with all
compile-time values baked in.
- render.py is a copy of quick-dev's, differing only in skill-name
references; a test guards against the two copies drifting apart.
- Compile-time config refs ({communication_language},
{planning_artifacts}, {implementation_artifacts},
{deferred_work_file}, {document_output_language}) become {{.var}}
substitutions resolved from the central four-layer TOML config.
Runtime refs ({spec_file}, {diff_output}, ...) pass through.
- [workflow] customization resolves at render time: on_complete inlines
into the HALT On Complete section, implementation_handoff into
step-03, and review_layers materialize as invocation blocks in
step-04 — the runtime resolve_customization.py calls and the
activation-time workflow-block resolution step are gone, along with
the Load Config activation step (values are baked at point of use;
the language rule moves into each step's RULES).
- Step files now reference workflow.md instead of SKILL.md; step-02
resolves the spec template's date field; step-04 defines {date} for
the triage-log header.
- tools/validate-file-refs.js whitelists render/bmad-dev-auto/;
test:renderer now also runs the new test/test-dev-auto-renderer.js.
- docs: the dev-auto reference's Context Inputs now names the central
_bmad/config.toml surface instead of _bmad/bmm/config.yaml.
bmad-spec gains an optional, interactive-only Story Breakdown step that
derives stories.yaml from the memlog: a fixed-name sibling of SPEC.md
listing stories as a simple sequence (list order = execution order),
each with id, title, description, and orchestration fields
spec_checkpoint, done_checkpoint, and invoke_dev_with. Field definitions and validity rules live in
assets/stories-schema.md. Ids are pinned only once a story's spec file
exists; un-started stories may be renumbered on re-derive. stories.yaml
never carries status.
bmad-dev-auto becomes dispatchable per stories.yaml entry: invoked with a
spec folder and story id, it reads only that entry's title and
description, derives the slug, and creates or resumes the story spec at
stories/<id>-<slug>.md just in time. All HALT write-back lands at that
id-keyed path (skeletal spec for pre-planning halts). An
invocation-prompt directive halts ready-for-dev after planning;
re-dispatching the same folder+id resumes via existing status routing.
Planning accumulates context from all prior story records in the
folder. Reference docs updated to cover both halves.
The intent_gap branch reverted code changes before halting, destroying
information: the attempted diff shows the human exactly which reading
the agent implemented, which is concrete evidence for repairing the
intent — and occasionally the guessed reading is simply right.
Save the attempt as a patch file in {implementation_artifacts} before
reverting, reference it from the triage log, and include its path in
the halt output. Restart stays default-clean (blocked keeps discard
semantics; the tree is reverted as before); if the human decides the
attempted reading was correct, git apply + status in-review resumes
review on it instead of paying for a full re-run.
Also unify the blocking-condition vocabulary: 'intent gaps' (step-02)
and 'intent gap in intent contract' (step-04) both become 'intent gap'
— one condition, one meaning; the artifact shows which phase raised it.
Document the artifact, the recovery affordance, and the unified
condition in the integration reference (docs/reference/dev-auto.md).
Capture the post-commit HEAD as `final_revision` alongside the existing
`baseline_revision`, so the orchestrator running immediately after a
dev-auto session can derive the session's commit range
(`baseline_revision..final_revision`) without inferring it from git state.
The artifacts directory is gitignored, so the spec frontmatter is the only
link from the out-of-tree spec to the in-tree commits. A single endpoint
suffices: `git log baseline..final` regenerates the commit list on demand,
and equal values mean no commits were made. Degrades to `NO_VCS` when
version control is unavailable.
Also documents both revision fields in docs/reference/dev-auto.md.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>