Commit Graph

2021 Commits

Author SHA1 Message Date
Alex Verkhovsky 051fdbbf2d fix(forge-idea): decode persona resolver JSON as UTF-8 2026-08-06 08:14:43 -07:00
Alex Verkhovsky ea6a5d900c fix(party-mode): decode subprocess JSON as UTF-8 on Windows (#2687) 2026-08-06 08:11:40 -07:00
Alex Verkhovsky 0601263bb1 test(installer): make directory prompt tests deterministic (#2685)
* test(installer): make directory prompt tests deterministic

* test(installer): cover bare tilde directory input
2026-08-06 07:51:52 -07:00
Alex Verkhovsky 05e295f48e fix(review): clarify weak test evidence (#2683) 2026-08-03 21:48:48 -07:00
Brian 5247108ba3 fix(installer): plain-text directory prompt, retire WDS, position on AiDD (#2680)
* fix(installer): submit the path shown and retire WDS from the picker

Directory prompt

The installation-directory prompt was a clack AutocompletePrompt whose
render() drew only the text line. The candidate list existed but was never
shown, and Enter returns the focused option rather than the typed text.
Focus was sticky: it only reset when the previously focused value left the
list, so a subdirectory selected while narrowing survived deleting back to
the parent. Typing /path/to/workspace could install to
/path/to/workspace/some-child with no sign of it on screen.

Rebuilt on TextPrompt so the input line is the value:

- the candidate list is visible, windowed, with an active-row marker
- arrow keys and Tab write the highlighted candidate onto the input line
- the list is frozen against the last typed text while browsing, so arrows
  walk siblings instead of descending (this also unsticks Tab cycling)
- index -1 is the typed text, so backing out of the list restores it
- Tab completes to real directories only, skipping "Create/use:" entries
- directory() takes optional input/output streams so it is testable

Module registry

- WDS is marked deprecated: hidden from the picker unless already
  installed, shown with a notice when it is, never removed and still
  resolvable from its source so existing installs keep updating
- deprecation notices now reach the CLI paths (--modules, --yes) and
  quick-update, which never render the picker's option hints
- picker order is now bmm, bmb, cis, tea, bmad-loop, gds
- the core row is hidden; it was a locked always-on checkbox. core is
  still added to the result, and the picker no longer requires a
  selection so a core-only install stays possible

* fix(installer): replace the whole line when browsing directories

_clearUserInput() sends readline ctrl+u, which deletes only what is left
of the cursor, and _setUserInput() inserts at the cursor. Browsing after
an arrow-key edit therefore left the surviving tail appended to the
selected candidate: typing a path, pressing left three times, then down
twice submitted ".../workspaceace" instead of ".../workspace/alpha".
validateDirectorySync accepts that path when its parent exists, so the
install went somewhere the user never typed - the same silent-divergence
class this prompt was rebuilt to prevent.

replaceLine() now moves to end of line (ctrl+e) before clearing. This
also fixes the pre-existing instance of the bug on Tab.

Alongside it:

- shift+tab steps back through completions instead of acting as tab
- the "... N more" counter counts only entries below the window, not
  every off-window entry, which overstated it once scrolled
- an empty line resolves the default through expandHome/path.resolve,
  and seeds the candidate list from the same place, so the list always
  describes what Enter would submit
- selectAllModules JSDoc no longer claims core is excluded
- test escape sequences are written as escapes rather than raw bytes,
  and the keystroke driver has wider timing margins for CI

* refactor(installer): make the directory prompt a plain text entry

The candidate list, key hints and completion cycling were noise for the
common case: people run the installer from the directory they want to
install into, or one under it. Enter on an empty line already accepts
that, so the list mostly served to push the actual question off screen.

Removed the list rendering, the hint line, arrow/Tab browsing and the
helpers that fed them (listDirectoryOptions, directoryWindow and the
directory-probing utilities). What remains is a clack TextPrompt with a
placeholder showing the default.

The original defect stays fixed by construction rather than by
bookkeeping: TextPrompt's value is the text on the input line, so there
is no hidden selection that Enter could submit instead. Net effect on
prompts.js versus main is -66 lines.

* docs(installer): shorten module descriptions in the picker

The hint beside a highlighted module ran long enough to wrap, which made
the list harder to scan than the module names alone. Each description is
now a single short phrase:

- bmm  Agile AI driven development
- bmb  Skill, workflow, and agent builder
- cis  Brainstorming, ideation, and creative problem solving
- tea  Enterprise testing BMM add-on
- loop Builds, verifies, and retros a whole epic unattended
- gds  Ideate, design, and build games in any framework

TEA is the only module that depends on BMM, and its description now says
so. The others no longer imply it. "Loop" means nothing to a new user, so
that description leads with what the module does rather than its name,
and gds no longer enumerates engines.

* feat(installer): pre-fill the directory prompt with the current directory

The default was shown as dim placeholder text, so choosing anything near
it meant typing the whole path by hand. It is now the real starting value
on the input line: press Enter to take it, append to install one level
down, or backspace to move up. Clearing the line and pressing Enter still
accepts the default, and the placeholder remains for that case.

* docs: reposition on Agile Ai Driven Development

The tagline was absent from the installer and the README, and the slot
under the wordmark where a tagline belongs was carrying the company line
instead. AiDD is the category BMad Method operates in; the agile part is
what BMad adds to it.

Installer:

- the banner reads tagline, then positioning, then company credit, in
  descending weight
- bmm and cis picker descriptions match, with cis short enough that its
  row no longer wraps and shifts the list as you arrow onto it

README:

- the opening states the phrase, defines AiDD on first use, and drops the
  rhetorical "heard BMad means heavyweight process?" framing while
  keeping what it was defending
- greenfield lean corrected: the opening now states the range, "add BMad
  to an existing codebase" is a CTA above the fold rather than a link at
  line 57, and a bullet names working from verified context on inherited
  code. Everything above the fold previously scaled by change size and
  nothing by codebase maturity, so a brownfield reader had no answer.
- the module table matches the installer descriptions, uses full module
  names instead of letter codes, and adds BMad Loop, which was missing

* docs: carry the module descriptions into the translated READMEs

Game Dev Studio was the last picker row wide enough to wrap an 80-column
terminal, which shifts the list as you arrow onto it. The engine list
stays in the README tables, where there is room for it.

The Chinese and Vietnamese READMEs have their own structure rather than
being a translation of the current English one, so this only touches the
two parts that had gone stale against the installer: the opening
positioning line and the module table. Both tables now match the English
one - installer descriptions, full module names instead of letter codes,
and BMad Loop, which none of the three had.

The translated prose needs a native reviewer before release.
2026-08-03 19:54:31 -05:00
Alex Verkhovsky 2f8b437ea2 docs(review): remove the adversarial-review explanation page (#2679)
The page is no longer needed. Drop it and its localized copies (cs,
fr, vi-vn, zh-cn), and de-link the remaining references in
forge-idea.md and the zh-cn advanced-elicitation/build pages. Drop a
stale line from lens-adversarial.md left over from the prompt slim.

Also drop a renderer test assertion that could never fail: it checked
that a deleted file wasn't in the snapshot, but the file no longer
exists anywhere in src/, so nothing could put it there.
2026-08-03 03:20:29 -07:00
Brian 57e70562e3 feat: bmad-project-context skill — verified kernel + bundle context system (#2674)
* Add bmad-project-context skill; husk document-project and generate-project-context

- New bmad-project-context: one engine, three intents (ingest/query/audit)
  building a verified kernel + bundle context system; interactive default,
  auto/headless mode; works with a BMad install or standalone via bootstrap
- context.py core runtime script (validate/index/map/sweep/resolve/compass/
  sync/bootstrap/config) with 52 tests; config resolution delegates to the
  installed BMad resolver so script and session never disagree
- bmad-document-project and bmad-generate-project-context reduced to
  10-line deprecation shims forwarding to the new skill
- Docs updated: project-context explanation/how-to rewritten, established
  projects guide + FAQ, agents references, workflow map; deprecation notes
  kept for old-name searches
- module-help.csv single PC row; analyst menu DP -> PC
- validate-file-refs: context.yaml is runtime-generated

* refactor: remove map command from context.py — discovery is the model's job

Real-repo testing showed map's descriptor pass grinding through large
asset trees. Discovery is judgment work the model does better with its
own tools; the script keeps only measurement, mutation, and resolution
(validate/index/sweep/resolve/compass/sync/bootstrap/config). SKILL.md
brownfield flow de-prescribed to outcome-driven wording; added a
bounding-question rule for huge external sources.

* feat: closing message when the harness may not load AGENTS.md

43+ harnesses make per-harness load verification impractical. Whenever
AGENTS.md carries the kernel, the run now closes by telling the user:
if your harness doesn't auto-load AGENTS.md, make the context file it
does load pull this one in (e.g. a CLAUDE.md containing @AGENTS.md).
Found in real-repo testing: the kernel sat unloaded under Claude Code
until a CLAUDE.md pointer was hand-made.

* docs: add The Theory of Project Context explanation

Why the skill captures so little: the evidence against generated docs,
the pruning test and what earns a place, the deliberate exclusions with
their reasons, context-as-liability, and an honest comparison with the
two replaced skills.

* fix: address PR review findings

- Force-add eval fixture files the repo gitignore silently dropped
  (pnpm-lock.yaml, _bmad/context.yaml, context/.memlog.md)
- docs/reference/agents.md Analyst row: DP/Document Project -> PC/Project Context
- context.py: cmd_index no longer crashes on an empty index.md (and
  allows overwriting one); inline # comments in frontmatter values are
  only stripped when preceded by whitespace (C#-style values survive);
  cache_lookup tolerates corrupt pointer files; pointer writes are atomic
- triggers.json: positive trigger for the query intent
2026-08-02 23:41:34 -05:00
Alex Verkhovsky cff69a6d54 refactor(review): slim adversarial hunter prompt (#2675)
* refactor(review): slim adversarial hunter prompt across build and review skills

Drop cynical-persona framing. Inline a short review prompt (≥10 findings,
look for missing, empty/zero guards) into blind-hunter layer instructions for
bmad-build, bmad-build-auto, and bmad-code-review. Delete the old
review-prompts/adversarial.md files. Align offline no-subagent dump with the
same child prompt. Update bmad-review's adversarial lens to the same method
while keeping its canonical finding fields.

* test(renderer): stop requiring deleted adversarial.md prompt file

Blind hunter is inlined; assert the inlined prompt text and remaining
file-backed review prompts instead.

* docs: align adversarial review explanation with slim hunter prompt

Document the finding floor and missing-not-only-wrong method instead of
the old cynical persona. Update core-tools lens table and localized pages.
2026-08-02 19:43:11 -07:00
Alex Verkhovsky 770d425985 fix(installer): apply --set core overrides before config collection (#2671)
`--set core.<key>` was applied only as a post-install TOML patch, but core
values are dependency-bearing: module artifact paths are built from
output_folder during config collection, the output directory is created
from those paths, and each module's config.yaml snapshots the core values
at generate time. A patch that lands after all of that leaves the sources
disagreeing.

`--set core.output_folder=generated` produced output_folder: generated in
core config, BMM paths under _bmad-output, and a _bmad-output/ directory
on disk. `--set core.project_name=Foo` left BMM's copy on the default.
The docs present --set core.<key> and the legacy shortcuts as equivalent
and label --set the preferred form, so both were reachable by following
the documented advice.

Seed core config from setOverrides.core alongside the legacy shortcut
flags, so every core key takes effect during collection rather than only
the four that have a dedicated flag. Non-core overrides keep the existing
post-install patch path.
2026-08-02 05:23:16 -07:00
Alex Verkhovsky d25a307e71 docs: remove non-interactive installation pages (#2670) 2026-08-02 04:40:38 -07:00
Alex Verkhovsky 49c608f782 chore(build-auto): remove final_revision from the contract (#2668)
The field recorded a commit id inside a file that had to be committed,
so Finalize took a second commit carrying nothing but one frontmatter
line. Nothing read the field.

Finalize now sets status: done before the run's commit and includes the
spec in it, then verifies the working copy is clean. A story's range end
is the next story's baseline in stories.yaml list order.
2026-08-02 02:23:08 -07:00
Alex Verkhovsky e510393b35 docs: define plain English writing rules (#2667)
* docs: define plain English writing rules

* docs: clarify what readers need from each page
2026-08-01 23:35:44 -07:00
Alex Verkhovsky 9d77b2966a feat(bmm): retro spec-folder epics alongside sprint epics (#2665) 2026-08-01 22:43:56 -07:00
Alex Verkhovsky 3cf69d81b7 fix(bmm): colocate Build story specs (#2666) 2026-08-01 16:38:13 -07:00
Brian cf54f4d76d refactor(bmm): consolidate sprint skills — one owner for the sprint-status artifact (#2659)
* refactor(bmm): move sprint-planning and sprint-status to plan/

They sit at the plan/ship boundary and their outputs are planning
artifacts of the dev cycle; next commit makes sprint-planning the
readiness gate, which is plan-side work.

* refactor(bmm): fold readiness gate into sprint-planning, retire check-implementation-readiness

The old skill was 1,154 lines of legacy numbered-step ceremony whose
document discovery hardcoded filename globs (*prd*, *ux*, *epic*) that
miss what current skills produce (SPEC.md, DESIGN.md) and still treated
retired sharded docs as first-class. Sprint-planning now opens with a
lean readiness gate: generic artifact discovery by content, forward/back
traceability, PASS/CONCERNS/FAIL, stop on FAIL with findings. The IR
trigger on John's and Winston's menus dispatches sprint-planning, so
'check implementation readiness' still works everywhere it used to.

* refactor(bmm): modernize sprint-planning with deterministic script core

SKILL.md drops the legacy XML step dialect for the product-brief style
(~100 lines, uv run, headless contract). New scripts/sprint_plan.py owns
the mechanical work — epic parsing, key derivation, ordering, preserve-
never-downgrade merge, story-file detection, action_items carry-over,
atomic writes, drift checks — with 11 tests wired in as
test:sprint-planning. Judgment stays with the LLM: epic discovery, the
readiness gate, and reconciling script-reported orphans and unparsed
headings. checklist.md retired (the script performs that checklist);
sprint-status-template.yaml is the single source for the status
vocabulary. Output stays byte-compatible with build's sprint sync and
retrospective's tooling.

* refactor(bmm): fold sprint-status into sprint-planning's status view

sprint_plan.py gains a status subcommand: counts (legacy values mapped),
risk flags, open action items, and a priority-ordered next-action
recommendation — the old skill's inference-driven summary, computed
deterministically and covered by 9 new tests. bmad-sprint-status becomes
a v6-shims husk that forwards with status-view intent and a deprecation
notice; its dead data/validate modes had zero callers and are gone. If
a hand-edited status file defeats the script, the skill falls back to
reading it directly and summarizing by best judgment. New explanation
page docs/explanation/sprint-planning.md covers the consolidated skill;
workflow maps and references updated across all languages.

* docs: changelog entries for skill reorg and sprint consolidation

* fix(bmm): harden sprint_plan.py per review; add validate/fix intents with full progressive disclosure

Review fixes (PR #2659 findings, bot + internal review):
- Normalize legacy v6 statuses (drafted/contexted) on every read — merged by
  meaning and reported, never treated as illegal or reset
- dropped_orphans carry their old status; transplant renames via --set
- project_key/tracking_system/story_location preserved from the existing file
  unless overridden; refresh round-trips custom keys and user comments
- Hardened write path: dump-to-bytes, fsync, permission-preserving atomic
  write inside the guarded block, explicit checks (no asserts), atomic restore
- JSON-only argparse (errors and -h emit JSON); unicode-aware slugs with hash
  fallback; fenced code blocks ignored when parsing epics
- Odd retro keys, date-typed stamps, and non-mapping YAML report cleanly
  instead of crashing; unparseable timestamps warn instead of silently
  disabling the staleness check; malformed action items flagged, not dropped
- Dead check subcommand removed; generate --dry-run reports drift/in_sync
- test:sprint-planning wired into quality and CI (was test-only)
- Retro tests use a vendored template fixture (PATH-05); repo-level
  test-template-sync.js keeps it byte-identical to the source; template
  example timestamps and story_location fixed; header block pinned to the
  template by test

New capability:
- validate subcommand + reference: structural validation, never writes
- fix flow: evidence-gathering subagents -> user-confirmed state table ->
  generate --fresh --set writes a pristine file (the one path allowed to
  downgrade); universal script-failure fallback to inference for every intent
- SKILL.md is now a lean router: gate, tracking, status, fix, and validate
  each load as progressive-disclosure references

Docs: explanation page gains Repair section; workflow-map and getting-started
across all five languages mention the status view; headless payload nests
under 'report' to avoid the status key collision; changelog updated.

Test suite grows 20 -> 37; retro suite 91/91; docs build and validators green.

* docs: mention repair in sprint-planning explanation description
2026-08-01 16:21:38 -05:00
Alex Verkhovsky 6245e34db4 feat: unify build skills on shared renderer (#2657) 2026-08-01 11:19:04 -07:00
Alex Verkhovsky a35e4c30d5 refactor(review): sequence verification-gap Step 1 per part (#2663)
Step 1 opened with a whole-change stop ("If the change is non-behavioral,
stop here and output the clean result") and then, three paragraphs later,
told the reviewer to screen each part separately. The two framings
contradicted each other, and the clean-result instruction sat before the
second skip rule was even introduced.

Reorder so the step reads in the order it is executed: screen per part,
skip non-behavioral parts, skip parts with no deterministic outcome, then
output the clean result if every part was skipped. The wording of the
individual rules is unchanged, as are the non-behavioral examples.

This is a clarity change, not a behavior fix. A 12-run A/B against the
previous version — four diff shapes, including one built specifically to
trigger early termination (a non-behavioral rename leading the diff,
followed by a behavioral change with a real gap) — found no difference in
either direction. Reviewers already screened per part regardless of what
the opening sentence said, and the genuine gaps were reported in every
arm. Cost was within noise at +2.3% tokens.

Applied identically to all three copies of the prompt.
2026-08-01 08:11:07 -07:00
Alex Verkhovsky 6cd3b646dd fix(review): stop verification-gap from demanding source-text tests (#2662)
The verification-gap prompt reliably pushed implementers to write tests
that grep source files for strings. Those tests pin wording, break on
rewording, and verify nothing.

The reviewer was right to treat a prompt as the executable artifact —
editing it does change behavior. The mistake was what followed: having
classified it as code, the reviewer reached the "a test counts only if
an assertion observes the changed output" rule and demanded an
assertion, and the only assertion reachable against prose is a match on
the file's own wording. The "Removed verification" finding category then
flagged deleting such a test as a regression, making it self-reinforcing.
Documentation was never affected; the failure was specific to prompts.

Three changes: list source-text assertions among the checks that do not
count, exempt their removal from "Removed verification", and have Step 1
screen each part of the change on its own so parts with no deterministic
outcome are skipped while the rest is reviewed normally. The screen is
per-part rather than whole-change, so a diff touching both a prompt and
a script still reports gaps for the script.

Applied identically to all three copies of the prompt.
2026-08-01 07:28:36 -07:00
Alex Verkhovsky e39cbbbaf5 docs: refocus README on first-use conversion (#2655)
* docs: refocus README on first-use conversion

* docs: fix GitHub Mermaid compatibility

* docs: use static delivery loop diagram

* docs: emphasize scale-adaptive workflow

* docs: reinforce open access commitment

* docs: clarify modular workflow adoption

* docs: address heavyweight process perception

* docs: demonstrate scale-adaptive delivery paths

* docs: align direct-build path with small changes

* docs: move README badge stripe to footer
2026-08-01 03:45:43 -07:00
Brian 57ad793167 refactor(bmm): reorganize skills into agents / plan / ship; retire tech-writer agent (#2658)
* refactor(bmm): move agent skills into agents/

* refactor(bmm): collapse phase folders into planning/ and shipping/

Skills reorganize from numbered pipeline folders (1-analysis,
2-plan-workflows, 3-solutioning, 4-implementation) into two sets:
planning/ and shipping/. Path and phase-label references updated
across marketplace.json, module-help.csv, tests, and bmad-help;
also trues up two marketplace paths that were stale on main
(create-story/dev-story already lived in v6-shims).

* refactor(bmm): shorten skill folders to plan/ and ship/

* refactor(bmm): retire tech-writer agent (Paige on hiatus)

Paige's capabilities were generic LLM defaults with no domain substance;
her one real menu item (DP) dispatches bmad-document-project, which stays
directly invocable and remains on the Analyst menu. Added to removals.txt
so installs clean up, and docs (all languages) carry a hiatus notice —
she returns in the future far more capable.
2026-08-01 01:52:51 -05:00
Alex Verkhovsky 6c36990123 docs: refocus getting started tutorials on activation (#2653)
* docs: add Getting Deeper Django tutorial

* docs: add spec-backed Django tutorial

* docs: replace Getting Started with small exercises

* docs(tutorials): add closing CTA to getting deeper

* docs(tutorials): remove redundant hello world exercise

* docs: rewrite welcome page around conversion proofs
2026-08-01 00:08:52 -05:00
Brian e9f636c1f7 feat(bmm): rework bmad-retrospective as an evidence-based epic review (#2612)
* feat(bmm): rework bmad-retrospective as an evidence-based epic review

Replace the persona-meeting simulation with an evidence engine that mines
what a completed epic actually left behind — spec, full diff, per-story
commits, sprint status, and session logs — instead of simulating a team
that "remembers." Every finding carries a source reference.

- Five-phase flow: Gather -> Analyze -> Decide -> Close. Analyze derives
  aggregate views (architecture delta, duplication, god-class growth,
  pattern divergence, spec reconciliation) and reuses bmad-review for the
  diff-scope code lenses rather than reimplementing them.
- Acceptance verdict (accepted / accepted-with-open-items / rejected); a
  failing epic can never close as silently accepted.
- Team discussion is now opt-in and off by default, delegating to
  bmad-party-mode seeded with the real findings.
- Add deterministic scripts: sprint_status.py (epic detection plus a
  comment-preserving, force-quoting, validate-and-restore sprint-status.yaml
  update) and git_evidence.py (range / commit / size-trajectory
  measurement), with a pytest suite.
- The retrospective document is the working artifact: built early, filled
  per phase, and resumable. Adds a headless mode (-H) with assumption
  capture.
- SKILL.md drops from ~1527 lines to a lean spine plus five references.

* fix(bmm): harden retrospective scripts for orchestrator use

Address review feedback on the evidence-based retrospective (PR #2612) from
CodeRabbit and the bmad-loop maintainer. All changes are additive — no existing
JSON field or CLI argument that a consumer reads is renamed or removed.

- detect-epic: STORY_RE now matches split-story keys (2-6a-...), aligning with
  bmad-loop's sprint-status detection; previously such an epic was invisible and
  a headless run could retro the wrong epic.
- sprint_status/git_evidence: argparse failures now emit JSON on the documented
  stdout contract instead of plain usage text.
- sprint_status: guard non-list action_items (clean JSON error, no traceback);
  _restore reports success/failure so a failed rollback is surfaced, not hidden.
- action_items entries carry a stable id and a ref to the retro document, so an
  orchestrator can dedupe across re-runs and dispatch each sourced finding.
- update echoes the acceptance verdict in its JSON; the retro key value stays
  "done" for existing lifecycle consumers. Retro doc gains machine-readable
  frontmatter, and -H <epic> is documented as the stable automation interface.
- evidence-gathering: derived range now includes the first story commit
  (<first>^..<last>); aggregate-views drops the size/acceleration overclaim.
- Tests: split-story detection, non-list guard, restore reporting, argparse
  JSON, and id/ref/verdict coverage (13 pass).

* docs(bmm): refine retrospective party-mode phrasing

* docs(bmm): document the reworked retrospective

- Add docs/explanation/retrospective.md — a short feature page: what the
  skill does, why to run it after an epic, and what to do with its output
  (retro document, action items, acceptance verdict).
- Update the workflow-map retrospective row to reflect the evidence-based
  review and its actual outputs instead of "Lessons learned."

* fix(bmm): validate git_evidence --range as a strict revision range

An unvalidated --range reached the git argv unchanged: a value starting
with "-" was consumed by git as an option, a single rev logged all
history up to it, an existing path was consumed as a pathspec, and a
file named like a range (a..b) was silently logged as one — each
returning a confident, wrong evidence set with exit 0. Reject anything
that is not an explicit REV..REV form — including empty endpoints
("..", "a..", "..b"), which git silently defaults to HEAD, and
unstripped values — and terminate the git argv with "--" so a
range-shaped name is always parsed as revisions, never as a pathspec.

Drop the root-commit special case from evidence-gathering.md: its
wording steered into a bare-rev invocation now rejected, the scenario
(an epic starting at the repository's first commit) is vanishingly
rare, and an agent that ever meets it can still construct a shape-valid
range itself. Document the exit-code split (2 invalid args, 1 git
failure). Every rejected mode is covered by regression tests; git
error-string assertions are pinned to LC_ALL=C.

* fix(bmm): harden sprint_status.py input validation and atomic writes

Nine findings from the PR #2612 review of the reworked retrospective, all
reproduced against the previous behavior:

- Pin the emitter indentation so a round-trip stops de-indenting
  pre-existing, untouched action_items; the sprint-status template now
  survives an update byte-identical apart from last_updated.
- Keep malformed input on the documented JSON-to-stdout contract instead
  of a traceback: shape-check the root document and development_status on
  both subcommands, widen the file open from FileNotFoundError to
  OSError, and report invalid UTF-8 as a JSON error. A non-mapping
  development_status previously reported ok:true while doing nothing.
- Validate comment preservation against the whole file's comment lines
  rather than only the leading block matched by substring, so a lost
  mid-file comment fails the write and restores.
- Write atomically through a temp file, fsync and os.replace, resolving
  symlinks and carrying the target's mode across. The rollback goes
  through the same path: a truncating rewrite that died halfway used to
  destroy the bytes it was restoring.
- Stop inserting an empty development_status mapping, and report
  retro_key_found: null when --set-retro-done was not passed, reserving
  true/false for "flag passed, key present/absent".
- Include restored:true on every update failure that precedes the write.
- Make _slugify Unicode-aware with a content-hash fallback, so non-Latin
  action text no longer collapses to the literal "item".
- Reject an --add-action item whose action is empty or not a string.
- Validate --date against MM-DD-YYYY HH:MM and normalize it, since
  strptime otherwise admits unpadded spellings.

Each fix is pinned by a subprocess-level regression test; the suite goes
from 18 to 49 tests.

* feat(bmm): add action-item status updates to sprint_status.py

The update subcommand could only append, and retro-document.md forbids
hand-editing sprint-status.yaml, so nothing anywhere could move an action
item off open. bmad-sprint-status renders every open and in-progress item
on every call, so retrospectives accumulated permanently-open noise.

Add --set-action-status, taking a JSON array of transitions for items
already in the file. Each entry selects one item by id, or by epic plus
exact action text for legacy entries written before ids existed, and gives
it one of open, in-progress, done. Selectors resolve against action_items
as loaded and strictly before the --add-action append, so an item added in
the same run is not addressable in that run. Validation is all-or-nothing
and entirely pre-write: a selector matching nothing, matching more than
one item, colliding with another entry, or carrying a status outside the
vocabulary aborts the whole invocation with restored: true and the file
byte-identical. After the write the file is re-parsed and every targeted
item is confirmed to carry its new status. Success reports the new
action_items_updated count.

Rewrite the contradicting paragraph in retro-document.md so the flag is
the one sanctioned path to change a status: offer the transitions when
the Phase 4 follow-through has evidence an item landed, apply only what
the user confirmed, and never touch prior statuses in a headless run.

* fix(bmm): measure renames, merges, and binary churn in git_evidence

Five ways the measurement was quietly wrong:

- Renames emitted an unopenable "src/{a => b}" pseudo-path and split one
  file's churn across up to three keys; non-ASCII paths arrived octal
  escaped. Both passes now run with core.quotePath=false and
  --no-renames, so a rename is an honest delete + add and a path is a
  real string that opens.
- Merge commits emit no numstat rows, so cross-story conflict-resolution
  churn vanished with nothing saying it had been skipped. The listing
  pass keeps full topology (per-story attribution is unchanged); a
  second pass measures merges alone under -m --first-parent
  --min-parents=2 and reports merge_files, merge_count and
  merges_measured. Merge churn is never folded into files: a merge's
  first-parent diff restates the churn of the commits it merged in.
- A commit naming two stories attributed to whichever id was passed
  first. Every matching id is now collected, so a seam commit counts for
  both stories. commits[].story becomes commits[].stories.
- A git failure with empty stderr reported "error": "". It now falls
  back to the exit code.
- One binary revision of a path nulled its added/deleted/net, dropping
  real measured text churn from the ranking. The text sums survive and
  binary_revisions reports the exposure beside them.

log.diffMerges is pinned to separate on the command line, because a user
config of off makes the merge pass emit no rows at all. Git output is
decoded with surrogateescape rather than replace, so two distinct
non-UTF-8 paths cannot collapse into one key.

evidence-gathering.md documents the changed output. 19 subprocess-level
tests over real git fixture repos cover every case above; the suite goes
81 -> 100.

* feat(bmm): add a pending-stories gate and align the retrospective docs

`detect-epic` now also reports `pending_stories` — the selected epic's
story keys that are not `done`, scoped to that epic alone — and SKILL.md
branches on it before Phase 1: interactively the user is shown the list
and may decline, headless the run proceeds and records the list as an
assumption. An epic supplied on the invocation skips detection, so the
instructions say plainly that the check did not run rather than implying
it did.

Both scripts are built with `add_help=False`. `-h`/`--help` previously
printed argparse's usage text on stdout and exited 0, breaking the
JSON-only stdout contract the scripts sell to their machine consumer;
help is now an ordinary unrecognized argument routed through the
existing JSON error path. SKILL.md also gained the branch for a
`detect-epic` that exits non-zero, which is the normal path for a
stories-mode project with no sprint-status.yaml.

The references are brought back into agreement with what the scripts do
after the last three batches: the close-out invocation quotes its values
and pins the `--date` format that now hard-fails a non-conforming value;
the result JSON documents `retro_key_found: null` and which failures
carry `restored`; the retro key is stated to read `done` even for a
rejected epic, so a verdict-aware gate must read the document
frontmatter; Phase 3 gains an inline fallback when bmad-party-mode is
absent; Phase 4 specifies the previous-retro follow-through record the
close-out consumes; and the god-class view is rewritten for the current
git_evidence keys.

Suite goes from 100 to 111 tests.

* chore(bmm): align retrospective script conventions and test harness

Adopt the invocation convention the quick-dev and dev-auto skills settled
on, and make the git_evidence test fixtures independent of the machine
they run on.

All five documented invocations become `uv run --no-cache`: the shared
cache may be unwritable in a sandbox and may serve a stale build. Both
scripts drop their shebangs entirely — they are only ever launched via
`uv run`, so a shebang and executable bit are a false affordance; the
PEP 723 blocks stay, since that is what uv reads. The encoding audit
that change implies found one implicit site left: `_load_yaml` now pins
the ruamel emitter's encoding, which is what encodes the bytes
`_dump_bytes` writes to the user's file.

`_git` and `_git_unchecked` passed an env of only the four GIT_* identity
vars, so PATH and HOME were wiped and git resolved through os.defpath —
the fixtures ran a different binary than the script under test, and
failed outright wherever git lives only in /opt/homebrew, /usr/local or
a nix store. Both now share a `_git_env` that inherits the environment,
strips ambient GIT_* vars that would redirect or reconfigure the fixture,
and pins identity, both gitconfig sources, gitattributes and the locale.

`_run` parsed stdout bare, so a crash surfaced as JSONDecodeError with
the real traceback hidden in the discarded stderr; it now routes through
the `_json` guard the rest of the file already used. Both test files gain
the repo's established runner footer and the PEP 723 header that makes it
self-bootstrap under `uv run <file>`.

No test's assertions change; the suite holds at 111 passing, and passes
under a gitconfig setting commit.gpgsign, core.autocrlf, core.hooksPath
and init.defaultBranch against it.

* feat(bmm): aim detect-epic at a supplied epic and reject unfinished ones

Unattended retros need the unfinished-story gate on the orchestrator path
and a hard machine verdict when delivery is incomplete.

detect-epic gains optional --epic N so -H <epic> can request the same
pending_stories list auto-detect already returns for its picked epic.
Non-positive values fail as JSON (exit 1). The skill now always runs
detect-epic for a supplied epic with that flag, and the acceptance
rubric forces rejected when pending_stories is non-empty — headless
included; interactive humans may still override.

Suite 111 → 115.

* fix(bmm): harden retrospective script contracts after re-review

- reject three-dot --range values in git_evidence.py: A...B passed the
  guard and silently measured a symmetric difference
- move the directory fsync in _atomic_write past the failure path so a
  post-rename fsync error can no longer report "restored": true about a
  write that landed
- validate --verdict against the frontmatter vocabulary and spell
  accepted-with-open-items one way across every machine-read surface
- emit story_count from detect-epic so a typo'd epic number is
  distinguishable from a finished epic, and teach the SKILL gate to
  treat 0 as suspect
- align the dev agent's ER menu description with the reworked skill

* fix(bmm): reject typed retrospective statuses

* docs: fix retrospective sidebar order

* ci(bmm): run retrospective Python tests

* fix(bmm): harden retrospective script execution

Reject non-positive epic numbers before update processing.
Keep explicit repositories authoritative when invoked from Git hooks.

* docs(bmm): rewrite retrospective skill prose in plain language

Remove invented metaphor and jargon from the skill's prompt surface
(SKILL.md and references): witnesses/interrogates, testimony, seams,
close-out, mining, and similar phrasing are replaced with plain
equivalents. Rename Phase 5 "Close" to "Finalize" and the "Honest
degradation" section to "Missing evidence", syncing cross-references.

Industry-standard terms (god-class, churn) and BMAD vocabulary
(declared/profiled, party mode) are kept. No operational rule,
script contract, or verdict vocabulary changes.

* docs(bmm): refine retrospective prose

---------

Co-authored-by: Alex Verkhovsky <alexey.verkhovsky@gmail.com>
2026-07-31 19:35:25 -07:00
Alex Verkhovsky 116491165d docs: move roadmap to end of sidebar (#2654) 2026-07-30 17:18:51 -07:00
Alex Verkhovsky 9b672e1e6b Allow configuring the Build spec editor handoff (#2652)
* fix: respect preferred app for Build review specs

* fix: restore Build VS Code handoff default

* fix: allow disabling Build spec opener

* docs: document Build editor opener options

* fix: use established Build path placeholders

* fix: address Build opener review findings

* docs: tighten Build opener explanation

* docs: simplify Build review handoff wording
2026-07-29 23:04:22 -07:00
Alex Verkhovsky 022bcbc66d Rename Quick Dev to Build (#2651)
* feat(bmm): rename quick dev to build

* fix: address build rename review findings

* fix: clarify deprecated build shims

* fix: offer legacy customization migration
2026-07-29 19:40:05 -07:00
Alex Verkhovsky 417814431d fix(review): preserve deterministic test-only coverage (#2647)
* fix(review): preserve deterministic coverage checks

* fix(review): evaluate test-only changes before stopping
2026-07-29 10:30:35 -07:00
Alex Verkhovsky bf74de621b fix(review): focus verification gaps on behavior (#2646)
* fix(review): bound verification gaps at inference

* fix(review): generalize verification boundary
2026-07-29 05:06:21 -07:00
Alex Verkhovsky f814c12cff fix(code-review): make no-spec mode an explicit supported path (#2645)
* fix(code-review): make no-spec mode an explicit supported path

Replace ambiguous "If yes / If no" language in step-01 spec-context
selection. Honor explicit no-spec declarations without asking, keep
known specs on full mode, and otherwise offer path vs continue-without.

* fix(code-review): clear spec_file when entering no-spec mode

Keep frontmatter consistent when an explicit no-spec declaration
overrides a Tier 1/2 path so later steps do not treat a stale path
as intentional.
2026-07-29 04:51:13 -07:00
Alex Verkhovsky 1a8fea5bd0 fix(docs): resolve deployed validation findings (#2644) 2026-07-29 01:26:46 -07:00
Alex Verkhovsky 43b54b8067 fix(review): dispatch reviewers by prompt file (#2642)
* fix(review): dispatch reviewers by prompt file

* fix(review): load review content from parent message only

Align phase-four reviewer prompt files with file-dispatch: drop the
{review_content} fill-in slot and take the review target exclusively
from the calling prompt.

* fix(review): keep no-subagent fallback prompts self-contained

When subagents are unavailable, write full instruction body plus
REVIEW TARGET under implementation_artifacts, not a path-only pointer.

* fix(review): keep layer recipes plain multi-line prompts

Drop blockquote wrapping so diffs stay intact, leave parent policy in
the review step, and keep customize instructions as the layer recipe
(default subagent prompt or a custom bash/LLM override).
2026-07-28 22:34:30 -07:00
Alex Verkhovsky 029ba287bc docs: make Quick Dev the canonical implementation workflow (#2643)
Rewrite published documentation and maintained translations around variable
planning depth with one Phase 4 implementation loop. Update diagrams and AI
indexes, and reject obsolete workflow terminology in deployable output.
2026-07-28 22:30:22 -07:00
Alex Verkhovsky e7af627e2e feat(skills): deprecate create-story and dev-story (#2641)
* feat(skills): deprecate create-story and dev-story

* feat(skills): add story workflow deprecation notices

* docs(shims): restore forwarding column heading
2026-07-28 19:56:33 -07:00
Alex Verkhovsky 116d52f5e0 feat: promote quick-dev to the official Phase 4 loop (#2637)
* feat(bmm): promote quick-dev to the official Phase 4 loop

- module-help.csv: bmad-quick-dev becomes the required Phase 4 item
  (sprint-planning -> quick-dev -> code-review); the deprecated
  create-story/dev-story rows leave the catalog; code-review and
  qa-generate-e2e-tests chain after quick-dev.
- Dev agent menu drops its DS/CS entries.
- Docs and skill recommendations point at bmad-quick-dev instead of the
  legacy split (architecture, ux, sprint-status, sprint-planning,
  retrospective, named-agents, project-context,
  expand-bmad-for-your-org, commands, workflow-map, getting-started).
  The legacy skills themselves are untouched; deprecating them in place
  is a follow-up PR.
- Quick-dev's user-facing descriptions (commands, workflow-map,
  getting-started, help catalog, dev menu) drop the interactive-session
  phrasing ("canonical implementation loop") for plain documentation
  wording.
- bmad-retrospective: story-record scan also matches
  spec-{epic}-{story}-*.md and quick-dev's section names, so retros see
  quick-dev output.
- bmad-quick-dev: preserve an existing baseline_commit on resumed runs
  instead of overwriting it with current HEAD.

* fix(bmm): address quick-dev review findings
2026-07-28 19:41:29 -07:00
Alex Verkhovsky cfee292715 fix(dev-auto): move deferred findings into the spec (#2640)
Record deferred review findings only in spec frontmatter and remove the
deferred-work output. Make updates safe for legacy specs and YAML-special
content, strengthen contract coverage, and synchronize the reference docs.
2026-07-28 18:42:42 -07:00
Alex Verkhovsky c2530ea53f feat: add inspectable workflow snapshots (#2601)
Render complete dev-auto workflows into root-scoped immutable snapshots
using shared declarative rendering and strict TOML configuration layers.

Keep generated render state out of installer module discovery and custom
file preservation, preserve quick-dev behavior, and provide deterministic
Python version failures for standalone resolver use.
2026-07-28 16:54:22 -07:00
Alex Verkhovsky ca0f3b11fb fix(review): restore direct phase-four reviewer prompts (#2638)
* fix(review): restore direct phase-four reviewer prompts

* test(review): remove prompt content assertions

* fix(review): restore one-shot worktree discovery
2026-07-28 15:17:36 -07:00
Alex Verkhovsky 7376a4a0da refactor(quick-dev,dev-auto): minimal handoff, drop Code Map nudge (#2635)
Walk back two bits of overprompting from #2629:

- The `implementation_handoff` guardrail block was premature mitigation to
  speculative failure modes (don't commit, don't revert unrelated changes,
  don't edit the spec). Collapse the default to what it should have always
  been: read the spec fully, load its `context:`, implement, report back.
  The key stays customizable — that seam exists to run implementation on a
  different model or an external tool via bash — only the default shrinks.
- Revert the Code Map spec-template enrichment. Granular entries were always
  permitted; step-02 already instructs planning to populate the Code Map, so
  the template comment/example nudge was redundant and half-relegitimized a
  root cause (#2629) that the natural experiment had already disproved.

Both skills' handoffs are now identical again.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-27 10:25:35 -07:00
Alex Verkhovsky 83f81c8120 feat(quick-dev): nail down implementation handoff to keep dispatch thin (#2629)
quick-dev's step-03 handed the spec to a coding subagent with loose prose,
so the main session improvised a fat dispatch prompt each run — re-narrating
the spec and re-expanding investigation detail at instruction weight. The
review layers were already nailed down in customize.toml; the coding subagent
was not. Give it the same treatment dev-auto got in #2561:

- Add a customize.toml `implementation_handoff` whose prompt is just "read the
  spec fully and implement it" plus guardrails and a report-back format.
- Rewrite step-03 to inject that handoff verbatim and forbid parent-authored
  goal restatements, file lists, investigation detail, or house-style rules.
- Route investigation into the spec Code Map at planning time (step-02) and
  enrich the Code Map template guidance, so the thin handoff points at a rich
  spec instead of the dispatch prompt backfilling it.

Apply the same step-02 and Code Map template changes to dev-auto for parity.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-27 09:22:39 -07:00
Brian bb45db4aa4 feat(core): consolidate research trio into bmad-deep-recon (#2611)
* feat(bmm): consolidate research trio into bmad-deep-recon

Replace bmad-market-research, bmad-domain-research, and bmad-technical-research
(5,136 lines of near-duplicate legacy step files) with one modern skill,
bmad-deep-recon (~650 lines):

- Research-master-orchestrator persona; conclusions never rest on training
  data alone; lead-following rounds with coverage/novelty-exhaustion stops
- Six type packs as ~25-line policy+craft cards (market, domain, technical,
  competitive, user-voice, academic-lit) + select decision shape layering a
  weighted-matrix method over any type
- Three acquisition modes: Generate (subagent fan-out), Delegate (engine
  registry: CLI/MCP, engine-first strategy), Import (provenance-tracked)
- Claims-ledger verification (normal/high/max) with independence rules and
  optional red-team pass; cited synthesis with staleness map
- Effort presets (quick/standard/deep) over four knobs (subagents,
  sources/round, depth, validation); precedence request > knob > preset
- Plan gate with surface discovery (MCPs/CLIs/engines), routing table, and
  time estimate; use_workflows and subagent_models config
- Create/Refresh/Deepen intents, memlog run-folder workspace, headless JSON
- v6 shims forward the three old IDs with type pre-set; analyst menu,
  catalog, marketplace, docs and translation mirrors updated

* feat(bmm): runtime output_format for bmad-deep-recon (v7 artifact protocol)

Replace the output_formats array with output_format = auto|html|md|both
(default auto): interactive runs render the HTML briefing, headless or
skill-invoked runs present the canonical markdown only. research.md always
exists in the workspace as the machine-readable report; the briefing is its
regenerable face. First instance of the v7 artifact protocol (memlog = truth,
md = distillation under contract, html = face).

* feat(core): move bmad-deep-recon to core-skills; address review findings

Move: research is not code-project-specific — home it in core-skills
(brainstorming precedent) so CIS and core-only installs get it. Skill ID
unchanged; standalone marketplace plugin added; catalogs moved to Core;
{planning_artifacts} falls back to {output_folder} on core-only installs.
v6 shims stay in bmm-skills (the legacy trio were bmm skills).

Review fixes (CodeRabbit):
- Engine briefs are now file-based: invoke templates substitute
  {brief_file} (a skill-generated path), never inline brief text — quotes
  and shell metacharacters in researched content can't shape a command.
- Refresh/Deepen preserve verification statuses for out-of-scope claims.
- HTML briefing: http(s)-only source links, escape source-derived text.
- user-voice pack: redact usernames/handles/emails from verbatim quotes;
  communities complement surveys (triangulate) rather than beat them.
- engine.md: explicit single-writer rule — digests return to the lead,
  which alone writes research.md in plan order.

* feat(core): deep-recon v2 — draft/process/run, faster defaults, research firewall

Rework after first real-run feedback (slow, token-heavy, locally biased
report, end-pass verification degraded quality, digests stranded in
subagent contexts):

- Three modes replace the acquisition-mode machinery: Draft (build a
  deep-research prompt the user runs in their own subscribed tool),
  Process (file a finished report into imports/, extract to digests/,
  distill research.md summary + metadata so downstream never reprocesses),
  Run (native fan-out, first-class). Bare research asks get the choice up
  front with the trade stated honestly.
- Engine/Delegate registry cut: the Draft->Process round-trip is the
  integration with dedicated deep-research tools; engine.md -> run.md.
- Files-first: digests hit {doc_workspace}/digests/ on landing, sections
  commit per dimension, synthesis reads files never conversation memory,
  dead runs resume from disk.
- Research firewall: persistent_facts default now empty, assistants get
  only their brief, project context frames questions but is inadmissible
  as evidence.
- Verification at landing, not end-of-run: normal = spot-check
  load-bearing claims only; red_team default off; heavy passes behind
  high/max. Presets rescaled faster (standard 3 subagents/8 sources/
  depth 2).
- Multi-agent research lessons folded into run.md and the plan gate:
  decomposition topology (breadth/depth/straightforward), per-assistant
  tool-call budgets, query craft with OODA pause, shared source-quality
  card, stop-and-write valve, mechanical citation check at finalize.
- Ripple: v6 shims, catalogs, marketplace, docs one-liners (all five
  languages), template gains source: provenance field.

* feat(core): deep-recon quality pass — carve SKILL.md, recon_kit scripts, single-source verification

- SKILL.md 3989→2091 tokens: Draft/Process/Refresh+Deepen/Finalize carved to
  references/{draft,process,lifecycle,finalize}.md; Run effort knobs + plan
  gate moved into run.md; Overview and pack prose trimmed
- verification.md: red-team pass is the single adversarial mechanism (max
  runs it at full breadth — no double-spawn); level semantics single-sourced
- scripts/recon_kit.py + tests: citations cross-check, memlog claim tally
  (ref=/status= convention, last wins), staleness date math from per-class
  windows, deterministic run-folder slugs, escaped source-appendix HTML
- Draft wired with preferred/banned source policies and an open-floor opening
- external_sources examples (Tavily/Sonar/xAI X-Search MCPs); source-quality
  card: answer engines are aggregators — chase their citations

* docs: Deep Recon explanation page + integration

- new docs/explanation/deep-recon.md: three modes, mode-choice guidance,
  research types, native-run internals diagram, firewall/verification, refresh
- analysis-phase.md research section rewritten for bmad-deep-recon
- core-tools.md: deep-recon in thinking-skills table, full catalog entry,
  migration note for the merged market/domain/technical trio
- workflow-map.md + getting-started.md link the new page
- vi-vn developer guide: last stale old-skill flow mention updated
2026-07-22 21:49:24 -05:00
Brian 8b4da79161 refactor(core): group v6 shims and merge editorial review into bmad-review as lenses (#2608)
* refactor: group v6 deprecation shims into v6-shims folders

Move the nine backward-compatibility forwarders into dedicated v6-shims/
folders so the deprecation set is visible in one place and can later be
made an install-time include/exclude option before removal at the v7 cut.

core-skills/v6-shims/: the five review and editorial husks
bmm-skills/v6-shims/: the four PRD and architecture husks

Grouping only — no content changes. The installer discovers skills by a
recursive walk and installs each under its own name, so installed paths
and skill IDs are unchanged. Verified by diffing a full headless install
against main: identical .claude/skills listing and file content, and an
identical _bmad tree. The only delta is the path column in
skill-manifest.csv, which now records the new source location.

External module repos (gds, loop, tea, bmb, os-utils) and enterprise
users still invoke these IDs, so they continue to ship by default.

* refactor(core): merge editorial review into bmad-review as lenses

All reviews are reviews. bmad-editorial-review's two passes become two
more bmad-review lenses, leaving one lens runtime instead of two skills
with overlapping trigger descriptions — "review this document" matched
both before, so which one ran was close to arbitrary.

Lenses now declare what they apply to. applies_to is "code", "docs", or
"any", and is the first filter on a default review; `when` still refines
it in prose. adversarial stays "any" — it is a stance, not a subject-
matter method, and is the lens a code/doc skill split could not have
placed. edge-case-hunter's `when` was "always", which is why it would
have fired on prose; it now gates on having a behavioral surface.

A lens may also declare `after`, naming a lens it builds on: prose runs
on top of the structure findings, as it always has. The runner announces
the plan, runs the independent lenses (in parallel via subagents when
available), then the dependent ones on their results.

Lens wording is unchanged. The three code lens files are byte-identical;
the editorial passes moved verbatim into references/lens-structure.md,
references/lens-prose.md, and references/editorial-common.md, which
carries what both share — the content-sacrosanct rule, style guide
handling, reader calibration, and the findings table. That material used
to load unconditionally; as lenses it loads just-in-time, so a code
review no longer pays for it.

bmad-editorial-review becomes the sixth v6 shim, forwarding with the
structure and prose lenses named. It keeps its customize.toml so existing
team and user overrides still resolve, and forwards them as pre-resolved
values. The four other husks now name bmad-review and their lens
explicitly. Each still pins its own legacy output contract.

bmm's four document skills point doc_standards at the merged skill with
named lenses. Docs updated across all five locales.

Core is 7 skills. A headless install produces the same 47-skill set as
main, with all six shims resolving.

* fix(core): honor forwarded customization and de-hardcode the lens set

Follow-up to the editorial/review merge, from review of #2608.

Contract fixes:
- bmad-review gains a Forwarded activation clause matching bmad-prd and
  bmad-architecture, so the bmad-editorial-review shim's pre-resolved fields
  are honored instead of being silently overwritten by the skill's own
  customize.toml. Existing bmad-editorial-review overrides resolve again.
- The announce step is skipped when a caller pinned an exact output contract,
  and a forwarder's contract now governs everything emitted rather than the
  findings block alone. The edge-case (raw JSON) and verification-gap (one
  exact line) forwarders no longer get a prose line prepended.

Lens set is no longer hardcoded:
- The description and body intro present the shipped lenses as examples and
  point at whatever {workflow.lenses} resolves to. Docs carry a matching note
  in all five locales.

Also:
- Document the `lenses=` directive form in Inputs and in the four bmm
  doc_standards comments that use it.
- module-help.csv review row rewritten to the house "Use to..." convention,
  naming the reviewable content types and the situations that should trigger
  a suggestion.
- Shim customize.toml trimmed to a lean legacy-key surface with empty
  defaults, so unset keys fall through to bmad-review and project-context.md
  is no longer loaded twice.
- Redundant `when` clauses dropped where applies_to already encodes the rule.
- Core skill count corrected to seven/four and the edge-case applies_to cell
  fixed to match its actual value, across all five locales.
2026-07-19 18:40:47 -05:00
Brian c23f23400d feat: streamline core to an 8-skill set with merged review and editorial skills (#2603)
* feat: streamline core to a 5-skill kernel with standalone skill modules

Core installs 14 -> 5 catalog-visible skills; atoms exit to standalone
modules; installer gains real dependency resolution; zero npm deps.

- Merge bmad-editorial-review-prose/-structure into bmad-editorial-review
  (structure models JIT-loaded, new customize.toml)
- Merge bmad-review-adversarial-general/-edge-case-hunter/-verification-gap
  into bmad-review as selectable lenses; hidden husk-forwarders remain at
  the old IDs (no catalog rows) so gds/loop/os-utils keep working
- Move bmad-brainstorming, bmad-party-mode, bmad-forge-idea out of core to
  src/standalone-skills/ as single-skill modules; add bmad-analysis bundle
  module (curated dependency list over the atoms)
- Move bmad-spec into bmm (2-plan-workflows)
- Modernize bmad-advanced-elicitation: uv run, customize.toml, methods
  pick offloaded to scripts/pick_methods.py (with tests)
- Delete bmad-index-docs, bmad-shard-doc (removes the tree's only external
  npm dependency), and the four deprecation shims (bmad-create-prd,
  bmad-edit-prd, bmad-validate-prd, bmad-create-architecture); all added
  to removals.txt
- Installer: activate the dependencies field (recursive union into
  selectedModules, cycle-guarded, warn on unknown), config-driven picker
  visibility; core stays force-installed
- bmm module.yaml declares deps on the three atoms
- Docs updated across all locales; new reference/standalone-skills.md;
  shard-doc how-tos removed

* Restore original critical wording lost in the review/editorial merges

The merges into bmad-review and bmad-editorial-review were meant to keep
the source skills' critical wording behind progressive disclosure, not
paraphrase it away. Restore what was lost:

- lens-adversarial: clueless-weasel framing, extreme-skepticism wording,
  the at-least-ten-issues quota, and zero-findings-is-suspicious (the
  merge had inverted this to zero-is-valid)
- bmad-review SKILL: zero-findings stance is now per-lens
- lens-edge-case: mandatory exact-order step enforcement
- lens-verification-gap: exact 'No verification gaps found.' clean line
- editorial-review: full Human/LLM reader principles restored to new
  references/reader-principles.md; structure-pass HIGH-VALUE DENSITY
  role, front-load-value, anti-patterns, pacing check, and length_target
  assessment; prose-pass role sentence, analyze-style-first step, and
  merge-overlapping-fixes rule; output summary block and min-3-words HALT

* feat(installer): promote bmad-analysis bundle to src/bmad-analysis-skills

Move the bmad-analysis bundle module out of src/standalone-skills/ into its
own src/bmad-analysis-skills root, teach the installer to resolve it there
(getModulePath, official-modules listing, isBuiltInModule helper), and
update the marketplace manifest and standalone-skills docs to match.

* refactor(bmad-review): rename edge-case lens to edge-case-hunter

Rename the lens code and reference file (lens-edge-case.md ->
lens-edge-case-hunter.md), add explicit when = "always" to the shipped
lenses, and tighten the lens-selection wording in SKILL.md.

* feat(bmad-editorial-review): configurable style guide + analysis-driven rework

Apply the workflow-builder analysis recommendations:

- Make the baseline style guide configurable: style_guide in customize.toml
  now IS the baseline (default "Microsoft Writing Style Guide") instead of
  an empty override slot; SKILL.md no longer hardcodes the guide.
- Inline reader-principles.md into SKILL.md and delete the reference (it
  loaded on every run and was half-duplicated inline).
- Complete the customization surface: activation_steps_prepend/append,
  persistent_facts (project-context glob), on_complete, and a
  review_output_path scalar split out of output_preferences; add a
  file:-load fallback convention.
- Ground word metrics: new scripts/word_metrics.py (stdlib, PEP 723, tests)
  emits total/per-section word counts so impact estimates and the reduction
  summary use exact numbers.
- Cross-pass dedup: prose pass skips CUT-tagged passages and re-attaches
  fixes in MERGE'd ones; output ranks by impact with a long-tail rollup.
- Polish: HALT threshold replaced with plain outcome, duplicate LLM-reader
  bullets merged, all-caps lowered, literal Overview heading added.

* fix(installer): stop cache-refresh git commands from escaping to the parent repo

Two compounding bugs let a pre-commit test run shallow-fetch and hard-reset
the developer's own repository:

1. Git spawns in custom-module-manager and external-manager inherited the
   hook environment. Git exports GIT_DIR (absolute, in worktree checkouts)
   into pre-commit hooks; a child git then targets the hook's repo regardless
   of cwd, and treats its cwd — the module cache dir — as the work tree. The
   cache refresh's 'git fetch --depth 1' + 'git reset --hard origin/main'
   therefore shallowed the shared .bare and moved the checked-out branch.
   New git-env.js strips repo-targeting GIT_* vars from every git spawn in
   both managers, including calls that previously inherited process.env
   implicitly.

2. Test suite 51 (quickUpdate dependency expansion) ran the real
   CustomModuleManager lookup, which scans ~/.bmad/cache/custom-modules and
   network-refreshes every cached clone — real user state. The suite now
   stubs findModuleSourceByCode.

Verified by rerunning the suite with GIT_DIR pointed at the repo and a PATH
shim blocking fetch/reset/clone: 432 passing, zero blocked calls.

* De-scope standalone-skills mechanism: atoms return to core, shims reinstated

Shrink the PR to its heart — the skill merges — and defer the module
mechanics to a follow-up where all skills become module-driven:

- bmad-brainstorming, bmad-party-mode, bmad-forge-idea move back to
  src/core-skills/ as ordinary core skills with their catalog rows
  restored; src/standalone-skills/ and the bmad-analysis bundle module
  are removed
- Installer reverted to main: standalone discovery, hidden-module
  filtering, dependency resolution, manifest changes (test suites 49-51
  removed with the code); the cache-refresh git fix is retained
- The four bmm deprecation shims (create/edit/validate-prd,
  create-architecture) are reinstated so enterprise installs that
  invoke the old IDs or carry _bmad/custom overrides keep working;
  descriptions trimmed to the short husk style; their removals.txt
  entries dropped (removal rides the v7 cut as their frontmatter
  promises)
- marketplace.json keeps the five plugin entries with atom paths
  pointing at src/core-skills/
- Docs (en/cs/fr/vi/zh) reframe the three skills as core thinking
  skills; standalone-skills.md reference page removed

* Fix all findings from the max-effort adversarial review

Correctness:
- Finish the edge-case -> edge-case-hunter lens rename at every caller:
  the forwarder husk, the code-review/dev-auto/quick-dev review layers,
  the renderer test assertion, and the stale example path in
  bmad-review/SKILL.md
- marketplace.json: ship the five core kernel skills with
  bmad-method-lifecycle so its skills' bmad-review/bmad-editorial-review/
  bmad-help/bmad-advanced-elicitation invocations resolve in a
  marketplace install
- pick_methods.py / word_metrics.py: force UTF-8 stdout (Windows locale
  code pages crashed on the catalog's arrows and CJK headings)
- word_metrics.py: pair fences CommonMark-style so 4-backtick fences can
  embed 3-backtick examples without corrupting sections; count CJK
  characters as words
- pick_methods.py: validate --extra entries are JSON objects (was an
  uncaught AttributeError); read catalogs with utf-8-sig (BOM'd CSVs
  silently blanked every num)
- bmad-spec: activation now resolves {output_folder} (which the
  Workspace uses) instead of the unused {planning_artifacts}; drop the
  stale core-only-installs comment
- Editorial husks: pin the legacy output contracts (three-column table /
  Document Summary report and exact empty-state lines) like the review
  husks do
- PRD shims: advertise the real bmad-prd customize keys
  (validation_checklist_template, prd_output_path, run_folder_pattern,
  finalize_reviewers) instead of three that don't exist
- bmad-prd: add the forwarded-activation clause its shims rely on
  (ported from bmad-architecture)
- Locale workflow-maps (fr/cs/vi/zh): add the bmad-spec Phase-2 row the
  English map gained, which every locale's core-tools note points at
- git-env.js: also strip GIT_CONFIG_PARAMETERS and the
  GIT_CONFIG_COUNT/KEY_n/VALUE_n family; pass gitEnv() to the three npm
  install spawns whose transitive git calls inherited hook vars

Consistency:
- brain.py --extra overlay now replaces-by-name like pick_methods.py
  (same customize.toml additional_* semantics across sibling skills),
  with a regression test

* Fix prettier formatting in marketplace.json

* Apply valid CodeRabbit findings

- brain.py: catch malformed --extra overlays (bad JSON, non-array root,
  non-object entries) into the clean error path instead of a raw
  traceback, with a regression test; read catalogs and overlays with
  utf-8-sig; normalize ALL CSV fields (required ones were unstripped and
  could arrive as None from short rows)
- brain-selector: clamp the random-technique count to what the pool can
  supply so the Total badge matches the actual draw (template +
  regenerated assets/brain-selector.html)
- bmad-editorial-review: word_metrics command now uses the explicit
  {skill-root}/ prefix
- resolve_party.py / resolve_personas.py: custom member overrides now
  start from the installed entry, so omitted fields (icon, title,
  description, module, team) survive; non-string member tokens land in
  unresolved instead of raising TypeError; party's member loop gains the
  isinstance guards its personas twin already had
- bmad-brainstorming: fix the SKILL.md claim that headless is the only
  context for self-generated ideas (autonomous mode is interactive);
  autonomous mode honors user-supplied techniques before self-selecting
- Docs: drop duplicate 'only' in the spec template; align zh-cn
  forge-idea's bmad-review description with the English wording

* Create only the output folder at install time

bmm no longer pre-creates planning_artifacts, implementation_artifacts,
and project_knowledge — the last of which put an empty docs/ at every
project root. Skills create those lazily on first write. core now
declares {output_folder} in its directories block, which was previously
created only as a side effect of the artifact folders nesting under it.
2026-07-18 23:49:22 -05:00
N0wah 5c9a1c2a22 fix(bmm): suppress epic/story comments and AI slop in generated code (#2544)
Add code comment quality constraints to bmad-agent-dev principles
and bmad-dev-story persistent_facts to prevent injection of epic/story
references and verbose AI-generated noise in produced code.

Fixes #2538

Co-authored-by: Brian <bmadcode@gmail.com>
2026-07-18 20:06:35 -05:00
Alex Verkhovsky 717479bc3f fix(dev-auto): temporarily revert skill-entry renderer (#2598)
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.
2026-07-15 13:19:03 -07:00
Alex Verkhovsky 1cd4a7f5c0 fix(skills): HALT renderers on missing config keys and bad overrides (#2588)
Two silent-corruption paths in the bmad-quick-dev/bmad-dev-auto
template renderers now HALT instead:

- A {{.var}} referenced by the skill's .md sources but absent from the
  merged central config previously rendered as an empty string with
  exit 0 (missingkey=zero), baking a corrupted workflow (e.g. missing
  planning_artifacts yields "List files in ``") with no failure signal.
  render.py now collects the referenced names before rendering and
  HALTs naming the missing key(s) and the referencing file(s). The
  dedicated implementation_artifacts guard stays: it runs before the
  derive step and also catches present-but-empty values.

- An optional customization layer (_bmad/custom/<skill>.toml, its
  .user.toml, or the optional central-config layers) that exists but
  fails to parse or read previously warned on stderr and continued
  with {} — silently discarding the user's overrides; unattended
  dev-auto runs never see stderr. Missing stays fine (layers are
  optional); unparseable or unreadable now HALTs.

Both render.py copies change in lockstep (parity test); regression
tests added to both renderer suites.
2026-07-14 09:26:17 -07:00
Alex Verkhovsky 64157d394c feat(dev-auto): render templates via stdlib Python at skill entry (#2587)
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.
2026-07-14 02:35:00 -07:00
Alex Verkhovsky 8ea1b7673b fix(dev-auto): score follow-up review recommendation; route patches to implementer (#2580)
* fix(dev-auto): score follow-up review from patched-finding severity

The old rule asked for a significance judgment of the pass's own
review-driven changes, which recommended another pass nearly every
time and never converged. Replace it with arithmetic over the triage
log, counting only findings triaged patch: recommend a follow-up for
a patched high finding, or when 3 x medium + 1 x low reaches 5.
Deferred and rejected findings never count. The flag stays a plain
boolean suggestion; the orchestrator owns the re-review decision.

Fixes #2576

* feat(dev-auto,quick-dev): route review patches to implementer, re-verify

When the step-03 implementation subagent can be re-engaged with its
context intact, step-04 sends it the patch findings instead of fixing
them in the main session; falls back to fixing directly where the
platform cannot keep a subagent around. Either way, the spec's
verification re-runs after patches land — previously patches applied
after step-03's verification shipped unchecked.

* fix(dev-auto,quick-dev): restate synchronous invocation at spawn sites

The SKILL-level ban on backgrounding subagents loses to harness bias
in long sessions once the preamble ages out of attention. Restate it
where reviewer subagents are launched in step-04, and mark the other
spawn sites (epic-context compile, planning exploration) synchronous.

Fixes #2570
2026-07-12 21:00:38 -07:00
Leon b3d79436f8 docs(zh-cn): add missing translations for forge-idea, web-bundles, and dev-auto (#2579)
* docs(zh-cn): add missing translations for forge-idea, web-bundles, and dev-auto

Complete the remaining five zh-cn documentation pages on origin/main.
Also fix Starlight sidebar autogenerate config so docs:build passes.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(docs): revert sidebar autogenerate to Starlight 0.40 items format

Starlight 0.40 (Astro 6) requires autogenerate inside items[], not at
group level. The previous fix passed locally with stale deps but failed CI.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: leon <leon.liang@hairobotics.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-12 00:46:01 -05:00
Alex Verkhovsky 49069b8b52 feat(quick-dev): render templates via stdlib Python at skill entry (#2281)
* feat(quick-dev): render templates via stdlib Python at skill entry

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>

* refactor(quick-dev): drop render.py YAML fallback and smart defaults

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>

* fix(quick-dev): normalize render.py paths to forward slashes

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>

* fix(quick-dev): preserve source line endings in render.py

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>

* fix(quick-dev): delete stale .md renders before rebuilding

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>

* fix(quick-dev): scope render/ whitelist to bmad-quick-dev

The previous INSTALL_ONLY_PATHS entry 'render/' was a blanket prefix
that let every {project-root}/_bmad/render/... reference in any skill
slip past validation. Narrow to 'render/bmad-quick-dev/' so only this
skill's render buffer is whitelisted. Future skills adopting the
stdout-dispatch renderer pattern add their own entries explicitly.

Part of plan-quick-dev-python-config-hardening.md (F6).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(quick-dev): add renderer smoke test with TOML override

New test/test-quick-dev-renderer.js spins up a temp project with
base _bmad/config.toml and a _bmad/custom/config.user.toml override,
runs render.py, and asserts the override wins in rendered workflow.md
and that sprint_status is rooted at an absolute path in the temp
project. Registered as test:renderer in package.json and chained
into the npm test script.

Part of plan-quick-dev-python-config-hardening.md (F7).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(quick-dev): HALT cleanly when base config.toml is unparseable

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).

* fix(quick-dev): resolve render.py via {skill-root} in skill entry shim

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.

* refactor(quick-dev): resolve [workflow] customization in render.py

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>

* fix(quick-dev): harden render.py invocation in the SKILL.md shim

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>

* chore(quick-dev): drop the render.py success stderr line

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>

* fix(quick-dev): drop the activation gate sentence from the rendered workflow

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.

* feat(quick-dev): materialize review layers into invocation blocks

Reconcile #2550 with render-time [workflow] resolution. Main made review
layers configurable as [[workflow.review_layers]] arrays of tables and
had the LLM resolve them during activation; this branch resolves the
[workflow] block in render.py instead, so activation-time resolution no
longer exists and the layer refs must be materialized at render time.

Rather than inlining the layer tables as data plus interpretation rules,
render.py now knows this skill's customization schema outright and
renders review_layers/oneshot_review_layers as direct invocation blocks:
disabled layers (empty instruction) drop out, each active layer becomes
a #### section holding its instruction verbatim, zero active layers
renders the HALT instruction, and runtime placeholders like
{diff_output} pass through. The only judgment left to the LLM is the
optional `when` condition, which renders as a run-time guard line.
The step-04/step-oneshot review intros collapse to a single execute-in-
parallel imperative. Smoke test covers default rendering, replace-by-id,
disable-by-empty-instruction, when-guards, and the all-disabled HALT.

* fix(quick-dev): invoke render.py via uv run per house standard

The SKILL.md shim launched render.py with bare `python3`, which the rest
of BMAD is migrating away from: the customize-bmad docs and the
installer's uv-check standardize on `uv run` (uv provisions a suitable
3.11+ interpreter on demand). Bare `python3` is also fragile on Windows,
where python.org installs expose `python`/`py` rather than `python3`.

Make `uv run` the primary invocation and demote `python3` to the
documented fallback, spelling out `python`/`py -3` for Windows and the
3.11+ tomllib requirement. render.py itself is unchanged; the renderer
test drives it directly and is unaffected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(quick-dev): HALT cleanly on missing or malformed config

render.py derived sprint_status/deferred_work_file from an unconditional
vars_["implementation_artifacts"] subscript, so a config lacking that key
raised a raw KeyError instead of the stdout HALT the rest of the script
uses on bad input. flatten_central_config likewise called .get("bmm") on
merged["modules"] without checking it was a table, so a non-table
[modules] crashed with an AttributeError.

Guard both: HALT with a clear stdout directive when implementation_artifacts
is missing or blank, and coerce a non-dict modules to {} before indexing.
Add renderer regression tests asserting each path exits without a Python
traceback.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* refactor(quick-dev): resolve config at compile time, drop the runtime re-read

The activation "Load Config" step told the LLM to open {{.main_config}}
and re-resolve project_name, communication_language, sprint_status, etc.
at run time -- but render.py already bakes those from the full four-layer
config merge. main_config pointed at only the base _bmad/config.toml, so
on installs with override layers (config.user.toml / custom/*) the runtime
re-read saw stale values that could contradict the baked {{.var}} in the
same rendered file. It also handed resolution back to the LLM: the drift
this skill's renderer exists to remove.

Delete the ceremony and wire each value where it is actually used:

- Every value the step resolved is already inlined at its point of use
  (planning/implementation_artifacts, sprint_status, communication_language)
  or loaded via persistent_facts (project-context.md), so the central
  block was pure redundancy.
- Fold document_output_language into the per-step language rule, adopting
  the house-canonical form ("Speak in X. Write any file output in Y.")
  already used by bmad-checkpoint-preview.
- Move the {date} = current-datetime definition to step-02, where the
  spec template's {date} field is filled.
- Drop the user greeting (user_name) and user_skill_level tailoring:
  quick-dev is not a conversational skill and neither was load-bearing.
- Remove main_config from render.py; it had no remaining consumer.

Renderer tests repointed at the files that now carry these values, plus
coverage for document_output_language baking and main_config removal.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs(quick-dev): reference variables by bare name, not placeholder curlies

Curlies mean "expand this to the value"; a bare backticked name means
"this is the variable/field I'm talking about". Several step files wrapped
a variable in curlies where they were only naming, assigning, passing, or
testing it -- so the notation implied an expansion that never happens:

- step-01: identify `epic_num`/`story_num`, set/leave `story_key` unset
- step-02: test `preserved_intent`; and resolve the template's `date` field
  (was `{date}`, which read as "expand date here" rather than naming it)
- step-03/step-05/step-oneshot: pass `target_status` to sync-sprint-status,
  set `title`
- sync-sprint-status: the `target_status` parameter, `story_key` precondition,
  and both `target_status` conditionals

Value tokens that are genuinely materialized in place -- `{spec_file}` paths,
`development_status[{story_key}]`, "set ... to `{target_status}`" -- stay
curly. Also reword step-02's frozen-block instruction from the ambiguous
"substitute it for the `<frozen-after-approval>` block" to "replace the
`<frozen-after-approval>` block in the spec you just filled out with
`preserved_intent`" so it's clear the replacement happens in the artifact.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* refactor(quick-dev): require uv, drop the python3 interpreter fallback

The SKILL.md shim tried `uv run render.py` and, if uv was missing, retried
with a bare `python3`/`py -3` interpreter. Nothing else in the codebase
does that interpreter fallback: the uv-based skills (bmad-prd, bmad-ux,
bmad-architecture, bmad-product-brief) fall back to reading customize.toml
and using defaults -- graceful feature degradation, never a different
runner -- and the legacy skills just call python3 outright. uv is the
established house runner (memlog.py, resolve_customization.py, lint_spine.py
all invoke it).

That graceful-degrade path does not exist here: render.py is the entry
dispatch that produces the workflow.md the LLM then follows, so there is
nothing to fall back to. The only honest outcomes are "uv runs it" or
"HALT". Make uv the floor and drop the fallback.

Pin the interpreter the house way -- a PEP 723 `requires-python = ">=3.11"`
block, matching memlog.py/lint_spine.py -- so `uv run` provisions a 3.11+
interpreter and the tomllib requirement is guaranteed rather than hoped for.
This replaces the prose "needs 3.11+" hedge the shim used to carry.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-07 19:31:55 -07:00
Dov Benyomin Sohacheski 5f3ebc91ed feat: add Antigravity CLI (AGY) as supported installer platform (#2551)
* feat: add Antigravity CLI (AGY) as supported installer platform

Distinct from the Antigravity IDE entry: the CLI reads workspace skills
from the shared .agents/skills standard and its own global dir. Closes #2440.

* test: assert Antigravity CLI global_target_dir differs from the IDE
2026-07-06 17:33:20 -05:00
Alex Verkhovsky 14bb68f401 perf(dev-auto): make review-layer fan-out atomic (#2565)
The review step said only to "execute all remaining layers in parallel
wherever their execution methods allow", which permits an orchestrator to
spawn one reviewer, react to its output, then spawn the next. Observed in a
run where four reviewers launched ~2m14s apart end to end — pure wall-clock
waste with no quality benefit.

Require every reviewer spawn to be issued contiguously before reading,
waiting on, or reacting to any reviewer output; collection and triage only
begin once all reviewers are launched. No change to reasoning structure or
review discipline.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 10:58:41 -07:00