* chore: default persistent_facts to an empty array
Every customize.toml shipped with a skill seeded persistent_facts with
file:{project-root}/**/project-context.md. That made project-context an
opt-out default rather than an opt-in customization. Ship the arrays empty
so nothing is loaded unless the user adds it.
* docs: correct the persistent_facts default in comments and docs
Comments and docs still described project-context.md as loading by default.
They were wrong twice over: the array now ships empty, and bmad-project-context
no longer produces a project-context.md at all — it writes a verified block into
AGENTS.md and treats project-context.md as a legacy artifact.
Replace those claims with the actual model: repo-wide context belongs in
AGENTS.md, which every skill already sees; persistent_facts carries context only
one skill needs, loaded on demand instead of as constant memory. Each site shows
the file: entry users can add to opt back in.
The change's narrative (commit messages, stated description) is staged by the
main session as a file and handed to the edge case hunter alone, which reads
it only after path tracing completes, then tries to falsify each claim against
the traced code. Findings carry kind "claim". Other layers never receive the
narrative, keeping their reviews unanchored.
Parents were announcing several layers then emitting one Agent
call and ending the turn. Restating parallelism does not fix
that. Require skip announcement, then every launch before any
result, and try to run them simultaneously.
* fix(bmad-code-review): keep review layers inside their output contract
A layer running as a Claude Code subagent can see host tools the method never
asked for. One of them, ReportFindings, instructs the caller to send findings
to the host UI and NOT print them as text — which is the exact channel the
parent reads, so a layer that reaches for it returns nothing and reads as a
clean lens. Layers are now told to return findings as text in their final
message, not to route them through any host findings-reporting tool, and not
to spawn subagents of their own.
* fix(skills): keep review layers inside their output contract
Propagate the a5af8c5c closer to bmad-build, bmad-build-auto,
acceptance-auditor, and bmad-review lens spawns so a host
findings tool cannot swallow a layer's final message.
* feat(installer): ask about shims during Quick Update
Quick Update returned before the shim prompt, so anyone who only ever
runs it carried their compatibility shims forward release after release
without once being offered the chance to drop them.
Quick Update now asks, defaulting to keeping the shims so pressing enter
never removes a skill in active use. It stays quiet for an installation
that already dropped its shims rather than re-asking every update. The
prompt carries the recommendation to remove them and names the one case
that justifies keeping them: a customized shim not yet migrated.
Whenever an install retains shims, it now lists every one of them and
what it forwards to. That notice is emitted where the policy is resolved
rather than at the prompt, so it also reaches the paths that never
prompt: --yes, --shims, and scripted quick updates.
* fix(installer): never prompt for shims without a TTY, and report removal
Two gaps in the Quick Update shim prompt.
The prompt could be reached by a scripted run. `--action quick-update`
is a documented scripting flag and is not tied to `--yes`, so a headless
invocation on an install that still had shims fell through to a confirm.
clack's confirm never resolves without a TTY: the process drained its
event loop and exited silently, mid-install, with status 0. It now keeps
the standing answer whenever stdin is not a TTY, leaving --shims and
--no-shims as the way to change it from a script.
Removing shims was also completely silent. Source filtering just skips
the directories, and the IDE cleanup that deletes the stale skill dirs
suppresses its logging on purpose, so nothing anywhere told the user
that a skill they may still invoke had just gone. Any run that removes
shims now lists them and says how to put them back, mirroring the
retained notice. Between the two, every run that has shims either way
reports which way it went, on interactive and headless paths alike.
* feat(installer): carry the shim outcome into the final summary
Both shim notices print before the install tasks start, so a long run
buries them well above the fold. The summary box already repeats the uv
warning for exactly this reason; the shim outcome now rides along the
same way, as a single line next to the preserved/backed-up file counts.
Retained reads "Deprecated shim skills retained: N (re-run to remove
them)" in yellow, removed reads "Deprecated shim skills removed: N" in
green, and an install with no shims either way adds no line at all.
* fix(installer): say what an empty module selection installs
The official module picker allows an empty selection on purpose: core is
always installed and is not a row in the list, so selecting nothing is a
valid core-only install. The prompt did not say so, and collapsed to a
bare "0 items selected", which reads as though the install is about to
do nothing.
autocompleteMultiselect takes an optional emptyLabel, shown while
selecting as "Nothing selected: installs core only" and on submit as
"0 items selected (core only)". Pickers that pass no emptyLabel are
unchanged. Also fixes the count to say "1 item" rather than "1 items".
* refactor(installer): trim explanatory comments to what the code cannot say
Cuts 35 comment lines added across this branch down to seven, keeping
only the non-obvious constraints: clack's confirm hanging without a TTY,
core not being a row in the module picker, and why the shim notices are
emitted where they are.
* fix(installer): report shims removed after they are retired from source
Removal reporting was derived from the shims the incoming release ships,
so a shim retired from source fell out of the report entirely: it was
absent from discovery, yet the update cleanup still deleted its installed
target using the previous manifest. The v7 cut is exactly that case, and
it would have removed every shim in silence.
Removal is now derived from what is installed, read back from
skill-manifest.csv, and the retained/removed split moves into
selectShimOutcome. This also covers the mixed run where one shim is
retired while the rest stay enabled: both notices fire, and the summary
carries both counts. The recovery line no longer offers --shims when the
release cannot reinstall them.
Raised by greptile and coderabbit on #2746.
* docs(build): add four review lenses to the Build diagram
Keep the unpublished Excalidraw source under website/diagrams/ and
refresh the published PNG so the Build page shows Blind Hunter, Edge
Case Hunter, Acceptance Criteria Audit, and Verification Gap.
* docs(build): move acceptance check off the review-lens box
Show Fits AC? as a gate between Implement and Review. Leave Blind Hunter,
Edge Case Hunter, and Verification Gap as the only review lenses.
step-oneshot and code-review step-02 told the orchestrator to launch
review subagents together, "then wait for all results" — spawn-then-wait
phrasing that reads as an invitation to detach the reviewer and improvise
the wait. Runs that drew that reading lost the in-call result delivery:
the orchestrator waited blind, and some relaunched a reviewer that was
still working, paying for the review twice.
bmad-build step-04 and bmad-build-auto already pin the contract: blocking
calls awaited in this turn, never backgrounded or detached. Port that
clause to the two remaining weak sites so every review dispatch in the
ship skills states the same contract.
* feat(project-context): adopt handwritten instructions via a ledger
A non-empty instruction file without a managed block now routes to a
new adopt intent — the migration form of refresh — never to setup.
Every existing instruction enters a retention ledger (retain, rewrite,
relocate, automate, delete) presented in full before anything is
written; a deletion needs one of four grounds, and one without hard
grounds is held for line-item approval that block approval never
grants.
Best practices replace the derivability test with a retrieval-cost
test, admit compact architecture and toolchain pins, and gate nested
AGENTS.md files on loading verified for every harness in use, falling
back to path-qualified root lines. The explanation and how-to docs
follow the same reframing.
* fix(project-context): scope splice preservation to the block itself
Step 5's byte-identical clause read as forbidding any change outside
the markers, which contradicted the ledger's approved rewrites,
relocations, and deletions of handwritten instructions there. The
splice still touches nothing outside the markers; outside text changes
only through a settled ledger entry or a proposed fix the user has
seen.
Also from review: the how-to routing sentence now distinguishes adopt
from refresh, template section 4 includes pyproject.toml, and the
theory doc qualifies the source-recovery claim to implementation
behavior.
* docs(project-context): plain-language pass on how-to and explanation
The reader-facing pages had absorbed the skill's internal vocabulary
— the disposition taxonomy, approval tiers, harness loading mechanics
— and metaphors that mean nothing to a casual reader. Replace them
with the user-level promise: you see what happens to every existing
instruction before anything is written, and nothing is deleted
without your sign-off. The theory page keeps its technical depth by
design.
* docs(project-context): drop behavior sentence from skill description
The description is a routing trigger; the adopt verb already carries
the cue, and the preservation behavior is documented where it runs.
* refactor(project-context): move intent-conflict rule from Args to detection
The Args line declares the interface; the guard against silently
obeying a supplied intent that contradicts the detected state belongs
in step 4, where detection happens.
* docs(project-context): trim Args platitude, mark conflict case as example
* docs(project-context): replace canonical/toolchain-pin jargon with plain terms
Right commands to use, required tool versions, cross-component rules
- same meaning, readable by anyone.
* docs(project-context): plain-language the cross-component admission rule
* docs(project-context): rewrite the adopted-content budget paragraph readably
* fix(build): gate one-shot patches on evidence, widen defer
The one-shot Classify contract routed findings by two criteria the model
cannot check: patch was gated on ease alone, so it filtered nothing, and
defer was scoped to provenance, so a true finding that was not
pre-existing had no home but reject. Anything true, cheap, and unwanted
therefore landed as shipped code.
Gate patch on evidence instead: the finding must show a defect that
actually occurs, missing coverage for a specific case, or a broken gate
or convention, and the remedy must be the smallest one -- no new public
surface, no guards for undemonstrated states. Widen defer to any real
finding not being fixed now, improvement ideas included, so worth
judgments reach the human as backlog lines instead of diff.
Reject keeps its wording and now works by elimination: non-substance
only. No criterion in the contract asks the model whether a change is
worth making.
* fix(build): make patch classification take precedence
Require findings that satisfy the evidence and remedy bounds to be
patched before defer is considered. This keeps specific missing coverage
from varying between immediate remediation and backlog work.
* fix(build): make one-shot triage routing exhaustive
Define patch, HALT, defer, and reject as an ordered partition. Keep
pre-existing and improvement findings out of the implementation while
escalating demonstrated change-caused findings that lack a safe trivial
fix.
* fix(review): gate routing on explicit review requests
bmad-review's description matched any review-like phrasing, so coding
agents entered the review workflow for requests that never asked for
one — install commands, git operations, summary requests, build
handovers, and questions, including a question about the review skill
itself. A week of Codex session logs showed every invocation but one
was unintentional.
Rewrite the description around an explicit ask:
- Trigger only when the user asks to review a diff, a pull request,
or an artifact — code or documents — and actually says "review".
- Acting on feedback from an earlier review is a change, not a review.
- Never volunteer, including on the agent's own just-made edits.
Validated with a 32-case routing eval, each case judged in an
isolated context, on two agent platforms; ten cases come from the
real over-trigger transcripts. The final wording scores 30/30 on
both platforms; an earlier draft's 29/30 drove the artifact clause
to name code explicitly.
* fix(review): count forwarded skill directives as review asks
Review-bot finding, confirmed by an isolated routing probe: with the
gate reading "when, and only when, the user asks", a literal reader
refuses the documented skill:bmad-review directive form that bmad-prd
and bmad-retrospective use to forward reviews.
Equate the directive with the ask instead of adding a second gate:
an explicit skill:bmad-review directive from another skill counts as
that ask.
The forwarded-directive scenario joins the routing eval as a scored
case; the full 33-case run scores 31/31 (two unscored probes), with
no previously excluded case loosened.
The previous description matched any code change, so coding agents
entered the build workflow for requests that never asked for it —
including git operations that only record existing content (#2708).
Rewrite the description around who owns the edits:
- Auto-trigger when the user hands over an outcome and leaves the
edits to the agent; a bare story or issue link counts.
- Always trigger on an explicit BMAD request, with no size floor.
- Never volunteer for user-directed interactive edits or for
version-control operations that record existing work.
Validated with a 26-case routing eval, each case judged in an
isolated context, on two agent platforms; both score 25/25 on the
final wording.
Fixes#2708
* chore(skills): rewrite skill descriptions in plain language
Skill descriptions carried jargon and metaphor ("SPEC kernel",
"spine of invariants", "PRFAQ gauntlet", "dies cheaply") that bled
into interactive sessions, help output, and generated artifacts.
Rewrite the description layer in plain language, grounded in what
each skill's body actually does:
- SKILL.md frontmatter descriptions across bmm and core skills
- module-help.csv descriptions for bmm and core, restoring missing
punctuation, filling the empty create-epics-and-stories entry, and
spelling out CC/CR menu codes
- bmm module.yaml module description casing
- prfaq bmad-manifest.json capability description
"Use when the user says ..." trigger phrases are kept verbatim, and
agent persona descriptors in module.yaml are untouched.
* style(skills): drop trailing periods from skill descriptions
Trailing periods on the description one-liners were inconsistent —
most SKILL.md files had them, a handful did not. Review flagged the
mismatch on the changed lines; resolve it the other way: no
description ends with a period. Internal sentence punctuation is
unchanged.
* feat: add ZCode as supported installer platform
ZCode keeps a private skills tree (workspace `.zcode/skills`, global
`~/.zcode/skills`) distinct from the cross-tool `.agents/skills`
standard, so it needs its own platform entry. The installer is
config-driven from platform-codes.yaml, so adding the platform is a
config-only change — no new handler code.
Follows the same pattern as the Antigravity CLI (AGY) addition (#2551):
one platform-codes.yaml entry plus a Test Suite asserting the config and
a real IdeManager.setup('zcode') install into a temp project.
* test(installer): harden ZCode test cleanup with try/finally
Move temp directory cleanup into a finally block with nullable guards so
fixtures are removed even when setup throws mid-flight. Aligns Test Suite 6c
with the existing pattern in Suite 28 (Pi) and Suite 32 (Ona).
Addresses CodeRabbit review comment on PR #2613.
---------
Co-authored-by: mindcarver <mindcarver@users.noreply.github.com>
Co-authored-by: Brian <bmadcode@gmail.com>
* docs(changelog): add v6.11.0 entry and sync marketplace.json
Covers 61 merged PRs since v6.10.0: 12 breaking changes, 18 features, 18
fixes, 4 removals. #2587 and #2598 are omitted as a land-then-revert pair
with net-zero effect.
marketplace.json had drifted. Its six plugin versions were still 6.10.0 —
nothing in publish.yaml touches this file, so the drift is chronic (v6.8.0
shipped it at 6.6.0, v6.9.0 and v6.10.0 at 6.8.0). All six now read
6.11.0.
The lifecycle plugin also listed six deprecated skills: bmad-quick-dev,
bmad-create-story, bmad-dev-story, bmad-sprint-status,
bmad-document-project, and bmad-generate-project-context. A published
plugin should expose current skills, not forwarding shims, so they are
removed and bmad-project-context is added in their place. Note this means
the "old IDs keep working through a shim" guarantee holds for module
installs but not for plugin-marketplace installs.
Skills arrays are sorted by path, which groups them agents -> plan -> ship
-> core-skills and makes drift like this easier to spot.
* chore(marketplace): consolidate to one plugin carrying all core skills
Collapses the six published plugin entries into a single
bmad-method-analyze-plan-build, bundling all eight core skills alongside
the twenty bmm skills.
Adds bmad-brainstorming, bmad-forge-idea, and bmad-party-mode, which only
ever appeared in the separate plugin entries and would otherwise have been
dropped by the consolidation.
Plugin name is kebab-case so it resolves; the human-readable label moves to
displayName.
This does not change what the installer installs — core is installed in
full regardless of marketplace structure. The file is being shaped for a
later installer switch and for publishing into marketplaces other than our
own.
A command earns a line when its correct form is not the obvious guess —
a bare-repo prefix, a required wrapper — judged from the repository, no
observed mistake needed. Record files an observed command error as the
exact invocation. A repeatable nonobvious command spotted in anything
read during the session is offered as a candidate.
The installer told users uv was optional while bmad-build had already made
it mandatory. uv-check.js called it "becoming the de facto standard",
install-messages.yaml led with HEADS UP, and installer.js printed a Tip
inside a box titled "BMAD is ready to use!" — while bmad-build and
bmad-build-auto HALT on activation without `uv run`. The probe's result
was discarded (`await checkUvEnvironment();`), so nothing branched on it.
Messaging now names the consequence, and the post-install summary repeats
the warning when it applies — the pre-install probe fires before every
prompt, so by then it is far up the scrollback. Still warn-don't-block:
core-only, docs-only, and CI installs never render a skill, so a missing
uv must not fail the run.
Adds a python3 probe used only when uv is absent, since that is the only
case where the interpreter on PATH matters. It reports whether the
direct-interpreter skills still work (3.11+) or nothing Python-backed will
(below 3.11, or no python3 at all).
Separately, 25 call sites still ran resolve_customization.py under a bare
`python3`. That script requires 3.11+ for tomllib, so on macOS without
Homebrew or Ubuntu 22.04 they fell through to their "if the script fails"
path and hand-merged the TOML in-context — no error surfaced. All 25 now
use `uv run`, which provisions a matching interpreter from the script's
own requires-python.
Four more spawned Python purely to open an HTML file:
python3 -c "import webbrowser, pathlib; webbrowser.open(...)"
Replaced with the platform opener bmad-brainstorming already uses — open /
xdg-open / start. src/ now contains no bare Python invocation at all, so
"Python 3.11+" leaves the user contract: uv provisions its own.
docs/how-to/customize-bmad.md described a transition that this ends.
Test suite 46 grows from 12 to 29 assertions: Python parsing, the 3.11
boundary in both directions, that uv-present skips the python3 probe, and
all three missing-uv sub-branches.
Rewrite the skill description: name the repository so the summary reads
cleanly, list all four intents, and drop the outcome-phrase triggers
("document this project", "apply coding standards") that let the router
fire on inferred intent. The skill now routes only when the user names
it.
* feat(project-context): rewrite as prescriptive AGENTS.md generator
Replace the kernel+bundle context system with a single product: a short
verified agent guide (AGENTS.md). A field trial of the first version showed
repo scanning produces polished-but-useless factoids; the rewrite fills a
fixed section plan from ranked evidence channels (executable config and CI,
targeted git history, session logs, human interview) and uses the repository
only to verify claims, never as the source of knowledge.
- Intents: bootstrap, refresh, record (capture an observed agent mistake),
audit; query is gone with the bundle
- Per-fact entry files, trust frontmatter, index, placement machinery, and
the skill's context.py mechanics script are removed; accountability moves
to one plain ledger file recording every candidate claim and its
disposition
- Skill directory only; docs, forwarding husks, and shared scripts untouched
* refactor(project-context): per-section admission rules, two-tier guide
Revisions from two end-to-end trials plus review:
- Replace the global non-derivable test with per-section admission rules:
brevity (orientation), authority (policy), universal need verified by
execution (commands, verification), wrong-default-assumption (conventions),
localization value (pointers), observed failure only (pitfalls)
- Two-tier output: AGENTS.md (orientation + policy + pointer) for every
session, AGENTS-dev.md for coding sessions; single file when tiny
- Pitfalls can never be nominated by scans: sources are recorded lessons,
maintainer recall, session evidence, and the writing session's own caught
mistakes; retirement only when the guarded thing is gone or the human says
so, since a working rule erases its own evidence
- Interview ergonomics: recall questions, never review lists; testimony the
repo contradicts is surfaced with evidence, never written or dropped
- Trial-driven fixes: guide-to-filesystem link check, mutating-command
go-ahead as the interview's first question, plain-English rewrite
throughout
* fix(project-context): bidirectional coverage trace, history-evidenced pitfalls
Round-3 trial findings: an unsourced pitfall entered the guide at
composition time because coverage only checked ledger-to-guide; and
repeat-fix git history, the strongest pitfall evidence observed, was
not an explicitly admitted source.
* refactor(project-context): move Where-things-are to AGENTS.md, imperative lines
Where-things-are pointers serve planning sessions as much as coding
ones, so they belong in the always-loaded file. Shape rules now require
every line to state an action (bare facts only as justification clauses)
and stable contract headings across runs.
* docs(project-context): session-kind guides as a third structural axis
A maintainer-named frequent session kind (UX, manual testing, data
work) may earn its own AGENTS-<kind>.md behind a pointer; module-level
differences stay with scoped guides.
* refactor(project-context): action-gated dev-guide pointer, two-file example
The AGENTS-dev.md hop is the most common progressive-discovery trigger,
so it is now gated on the first hands-on action rather than session
self-classification, names its payoff, and names the exemption. The
contract's worked example shows the two-file form with the pointer in
situ. Scoped-guide discovery no longer assumes harness nearest-file
loading: the root-guide pointer is the mechanism.
* refactor(project-context): adopt shared memlog, drop unearned claims
The run record is now a standard memlog kept with the shared
memlog.py script — append-only typed entries, latest entry wins —
replacing the bespoke ledger format; stale-disposition notes become
structurally impossible. Two appeal-to-measurement assertions cut:
the operative admission and exclusion rules carry that load.
* docs(project-context): guard handwritten guides
The skill never commits — its output stays as working-tree changes for
the user. Headless runs never rewrite a guide the memlog doesn't record
writing; they leave an AGENTS.md.proposed for an interactive merge.
* docs(project-context): fold in prior-art research findings
Five adoptions from the generator prior-art survey: prohibitions name
their permitted alternative; an emphasis-marker budget; a
git-log --diff-filter=DR drift check on refresh; TODO placeholders over
guessed greenfield commands; commit and branch conventions mined from
history.
* docs(project-context): route candidates to enforcement before prose
Compose now asks, per accepted candidate, whether a hook, lint rule, or
CI check enforces it better than a guide line; the line is the fallback
and a landed check deletes it.
* docs(project-context): narrow refresh interview and contradiction flagging
Refresh interviews shrink to one recall question — what changed since the
last run. Cross-file contradictions are flagged only when they change
behavior; rewording and overlap are not contradictions.
* refactor(project-context): conversational skill, no script, AGENTS.md block
Refine the skill into an implementation-layer capability: a conversation that
produces one small verified block inside the repo's AGENTS.md. The human is in
the loop for every write; there is no autonomous mode.
- Drop src/scripts/context.py and its tests. Nothing it did is needed once the
output is a single spliced block rather than a bundle of files.
- Replace guide-contract.md and evidence.md with best-practices.md (admission,
exclusion, retirement, retrieval, maintenance) and template.md (section list
plus a worked example, no placeholders).
- Collapse the two-file AGENTS.md/AGENTS-dev.md split into one block. A pointer
the agent must choose to follow gets skipped; anything load-bearing goes in
the always-loaded file.
- Replace per-section admission rules with one test: anything derivable from
source is read live, never stored. Commands stated in package.json, a
Makefile, or CI config no longer earn a line; their caveats do.
- Ask up front whether a run covers the root only or named sub-projects, gated
on observable evidence (a workspace manifest, per-directory build manifests).
- Husk bmad-document-project and bmad-generate-project-context onto setup
intent, and say plainly that the deeper system-explanation altitude is a
separate capability rather than shipping a thin substitute.
- Align module-help.csv, bmad-correct-course, the analyst menu, and the docs
set with the block as the output.
---------
Co-authored-by: Alex Verkhovsky <alexey.verkhovsky@gmail.com>
* 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.
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.
* 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
* 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.
`--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.
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.
* 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
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.
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.
* 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.