* Rename bmad-checkpoint-preview to bmad-walkthrough
"Checkpoint" said nothing about what the skill does and "preview" was wrong: it is a guided human walkthrough of a change, not a preview. Its siblings bmad-code-review and bmad-review already own "review", so the new name leans on what sets this one apart. "Walk me through this change" was already its trigger phrase.
- Skill folder, SKILL.md name/description, module-help.csv (menu code CK -> WT), marketplace.json
- Trigger words are now "walkthrough", "walk me through this change", "human review"; "checkpoint" is dropped
- English how-to page moves to docs/build/walk-through-a-change.md; build-a-change link updated
- fr, vi-vn, zh-cn pages move to docs/<lang>/build/walk-through-a-change.md to mirror the English path; explanation sidebar orders renumbered to close the gap
- Redirects for the old English and localized routes; sidebar label and translations updated
- Diagram assets renamed (image contents unchanged)
* Regenerate walkthrough diagrams with the new title
Title reads Walkthrough and the input box reads bmad-build spec file (was quick-dev, stale since the Build rename). English and French, same layout and style as before.
* Add bmad-checkpoint-preview forwarding shim
Forwards to bmad-walkthrough and offers to migrate legacy _bmad/custom/bmad-checkpoint-preview{,.user}.toml files, same as the other v6 shims.
* Point test-completed-work links at the renamed walkthrough page
Replace the Testing Options catalog with a decision-oriented completed-work
guide at /build/test-completed-work/. Redirect /reference/testing/, list the
page in the Build sidebar after Checkpoint a Change, and close the Reference
sidebar-order gap. Claims are grounded in bmad-qa-generate-e2e-tests; TEA
workflow catalogs stay on the TEA site.
* docs: create Review a Completed Change page
Turn Checkpoint Preview into the Build-chapter how-to for
bmad-checkpoint-preview and redirect the old English route.
* docs: retitle checkpoint how-to as Checkpoint a Change
The Review a Completed Change title collided with bmad-code-review and
the review step in bmad-build. Name the page after the skill and say it
does not replace those reviews.
* docs: update review link format in checkpoint-a-change.md
* docs: create Build a Change page and retire Quick Fixes and Build
Consolidate how-to/quick-fixes and explanation/build into the canonical
build/build-a-change page, opening with the sizing model and Where Build
Fits table and preserving the Build diagram and intent examples. Add the
Build sidebar group after Start, redirect both old routes, retarget
first-party English links and the llms.txt entry, and close the resulting
sidebar-order gaps.
* fix(docs): track Build a Change page by scoping Astro build ignore
The bare build/ gitignore rule also matched docs/build/, so the new
canonical page never entered the prior commit.
* docs: rewrite Build a Change page in plain English
Name the skill as bmad-build instead of Build, drop the duplicated
routing tables, and explain why it spends human attention on a few
checkpoints instead of a Continue slog.
* docs: make the landing page route readers by task
* docs: frame the landing page as think then build
The first pass routed by task but still treated bmad-build as the product.
Name both skill groups, send first-time readers to Getting Started, and
split spec work from the longer planning path.
* Update docs/index.md
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
---------
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
The full-config dump writes ensure_ascii=False JSON to a stdout still
bound to the platform default. On Windows that is cp1252, which cannot
encode the emoji icons carried by the shipped agent configs, so the
script raises UnicodeEncodeError and exits having produced no output.
Adopts write_json_stdout() from the sibling resolve_customization.py,
and adds the stdout regression test the suite was missing - it fails
against the unpatched script.
Fixes#2682
Co-authored-by: abobdadjimo <abobdadjimo@iqera.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
brain.py prints two kinds of arbitrary user text: --extra overlay
techniques (customize.toml additional_techniques) and, on stderr, the
technique name echoed back by `show NAME` when it is not found. Either
can carry a character the platform default cannot encode, and print()
then raises UnicodeEncodeError. The shipped catalog is cp1252-safe (its
only non-ASCII is U+2014), so this is an overlay/argv path, not a
default-catalog crash.
pin_utf8() passes errors= through rather than letting it default:
reconfigure(encoding=...) alone resets the handler to strict, which
would silently downgrade stderr's POSIX default of backslashreplace
and turn a diagnostic about an undecodable path into a traceback.
Thanks to @armelhbobdad for catching that on #2693.
Four regression tests, all four red against the unpatched script.
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Confirmed against real session logs across bmad-build and
bmad-build-auto: zero fires, ever, including a session built
specifically to test it. The tier produces boilerplate at
spec-authoring time and gets silently fantasized past at execution
time, so it does nothing but add noise.
Boundaries & Constraints drops from three tiers to two: Always,
Never. No replacement mechanism — a real judgment call that turns
out to matter surfaces at step-04 review like everything else does.
The Mayakovsky-style envoi at the end of get-answers-about-bmad was
written as indented lines in one paragraph, so every renderer collapsed
it: the leading spaces were dropped and the lines were soft-wrapped into
running prose glued onto the GitHub Issues link above it.
Use hard line breaks and em-space entities so the staircase survives
Markdown rendering and Prettier, and put a blank line back between the
link and the poem. Same fix applied to the fr and zh-cn translations.
The triage rule 'A finding whose fix edits {spec_file}: dismiss' gets
quoted verbatim into Review Triage Logs, leaking the unresolved
placeholder into story specs (observed in three consecutive unattended
runs). Name the file by its role instead — 'the spec this build is
implementing' / 'the spec under review' — so quoting the rule is
harmless, mark the defer clause's other-spec distinction explicit,
and make its document list read as examples (e.g.), not an enumeration.
* fix(skills): judge each review finding on its own before grouping
Triage in bmad-build, bmad-build-auto, bmad-code-review, and the one-shot
route previously deduplicated and grouped findings first and judged the
groups. A false finding merged into a group could dilute or sink a true
one, and a true finding could be dismissed on facts about its neighbors.
Now, once every layer has reported, each finding gets its own verdict
before any grouping: verify its claimed consequence at the site it names
(reading past the diff hunk into callers and guards), assign severity from
the verified consequence, and keep or dismiss on that verification alone.
A dismissal must dispose of the finding's own claim — an adjacent fact
that leaves the claim standing is not a dismissal — and every dismissal
is recorded with its reason, never dropped silently. Grouping applies
only to survivors, by shared root cause; same location or a shared fix
alone does not qualify.
Presentation reports the dismissed count in conversation, with the full
reasons preserved in the spec trace / report as the audit trail.
* fix(skills): route paperwork findings out of the patch lane
A review finding whose fix edits the story spec is dismissed; one whose
fix edits an agent-context document (CLAUDE.md, AGENTS.md, rules files,
specs) is deferred. An unattended run rewrote a repo's CLAUDE.md and its
own story spec through the legal patch chain; the triage had no concept
of documents that are not the run's to change.
* fix(bmad-build-auto): state subagent launches as one batched message
The Subagents section led with 'launch it, wait for it to return, then
continue with its result' — a serial recipe that contradicts step-04's
'launch every active layer before handling any layer's result'. An
unattended run followed the recipe and serialized all thirteen of its
subagent launches, including both four-reviewer fan-outs. The lead
sentence now prescribes the batched shape directly and covers
single-subagent steps, so no serial reading survives.
The content under review is staged exactly once as a file, and layer and
lens prompts carry its absolute path instead of the diff bytes. The parent
no longer regenerates the diff into every child prompt, which is what made
launch prompts large and staggered their dispatch.
bmad-build and bmad-build-auto stage the diff in step-03, before the
acceptance/verification check, and read it there so that check judges the
diff rather than the implementation subagent's report; a code change during
the check rewrites and re-reads it. Step-04 restages and hands the layers
the path. Staged files are uniquely named in the system temp directory so
concurrent runs cannot collide — bmad-code-review's staged diff moves there
too, off the fixed path it shared between runs.
bmad-review states the same contract once in its dispatch, covering every
lens: stage a branch, uncommitted work, or a commit range to one file and
pass the path. A branch means the diff against the merge base; uncommitted
work includes untracked files.
Inlining survives only in bmad-build's no-subagents fallback, where the
prompt is pasted into a session that shares no filesystem with this one. It
inlines every file the prompt points to and leaves every other line alone,
so the reviewer constraints that follow the content label survive.
Also carries the claims falsification pass to the build skills, adapted
rather than copied. In bmad-code-review the claims mechanism recovers a
narrative the skill does not own, so it guards on whether a claims file was
supplied. Build wrote the spec and ran the implementer, so there is no such
asymmetry: {claims_file} is {spec_file}, the check is unconditional, and it
reads only the Intent and Tasks & Acceptance sections. The reviewer's own
asymmetry survives — it is context-free by design and still opens the spec
for the first time after its independent path tracing.
bmad-code-review defined {diff_output} as holding diff text, so the
parent regenerated the whole diff into every layer launch prompt. On a
~31 KB diff that is roughly 8k output tokens per prompt, which staggered
the layer launches by minutes.
Rename the placeholder to {diff_file} and redefine it as a path. Step-01
writes the diff once to {implementation_artifacts}/code-review.diff,
creating that directory since artifact dirs are made lazily, and every
layer prompt now carries the path instead of the bytes. The two
review-prompt files accept either a path or inline content, matching the
contract core bmad-review already gives its lenses.
Inlining survives only in the no-subagents fallback, whose prompts are
pasted into a session that may not share this filesystem; that exception
is now stated where it applies so it stops reading as the general rule.
* 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>