Commit Graph

13 Commits

Author SHA1 Message Date
Brian 3aa110dfd3 fix(customization): resolve the project root from the working directory (#2802)
* fix(customization): resolve the project root from the working directory

resolve_customization.py inferred the project root by walking up from the
skill's installed directory. For a skill installed under the user's home,
that walk reaches ~ — and when a user-level install has put a ~/_bmad
there, the resolver treats home as the project, finds no override, and
returns shipped defaults. The real project's _bmad/custom/ file is never
opened, with no error and no warning.

Whether an override takes effect therefore depended on where its skill
happened to be installed, which the override's author cannot see from the
override. Every harness installs global skills under ~/<tool>/skills, so
this hits all of them identically.

Resolve from an ordered candidate list instead: the working directory
first (the project is where the user works, not where the skill lives),
then the script's own install path (skills invoke it as
{project-root}/_bmad/scripts/..., so its grandparent is a root the caller
already resolved), then the skill directory as a last resort.

Rank _bmad/ above .git at every depth while walking. A submodule or
nested repo carries .git without being the BMad project, so treating the
two as equal stopped the walk short of the root owning _bmad/custom/ —
the same silent failure, reachable by project-installed skills too.

Break the silence: when the chosen root has no override for the skill but
a rejected candidate does, write a note to stderr naming both roots.
stdout stays pure JSON.

Pass --project-root from all 44 skill and doc invocation sites, matching
resolve_config.py, which already requires it. That asymmetry was the root
cause; with the flag passed there is nothing left to infer.

Fixes #2796

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8Hyqmp2giAVgEAnB49zEQ

* fix(customization): pass --project-root from the party and forge wrappers

resolve_party.py and resolve_personas.py shell out to the customization
resolver with --skill only, though both already hold the project root and
both pass it to resolve_config.py two functions earlier. The resolver
therefore had to infer a root, and since these wrappers capture stderr
and discard it, the note about a masked override went nowhere.

Under the old skill-directory-first inference this happened to land on
the right root for a project-installed skill; under working-directory
-first it takes the ambient root instead, which is wrong whenever the
party runs from a nested project or an unrelated worktree. Passing the
flag removes the inference for both paths rather than trading one wrong
guess for another.

Cover each wrapper with a test that captures the resolver command and
asserts the flag carries the project root it was given.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8Hyqmp2giAVgEAnB49zEQ

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 23:01:32 -05:00
Armel BOBDA 1479a58b2d fix: pin UTF-8 stdout in resolve_config (#2693)
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>
2026-08-23 18:10:56 -05:00
Brian 47bab7d15c refactor(project-context): conversational skill, no script, AGENTS.md block (#2698)
* 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>
2026-08-08 23:03:12 -05: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 6245e34db4 feat: unify build skills on shared renderer (#2657) 2026-08-01 11:19:04 -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
Brian 02739932bc feat(installer): check for uv and standardize messaging on uv run (#2495)
Replace the standalone python3 environment check with a uv check, since
uv is becoming the de facto standard for running BMad's Python scripts
(`uv run <script>`) and uv provisions the interpreter itself.

Installer:
- Remove tools/installer/core/python-check.js and its wiring in ui.js
- Add tools/installer/core/uv-check.js: warn-don't-block, no ack prompt
  (the migration is in progress, so a missing uv never blocks install).
  Missing uv warns and points the user at setup, preferring "ask your
  agent to set up uv"
- Add a uv heads-up to the install intro (install-messages.yaml) and a
  uv tip line to the final "BMAD is ready" summary box
- Swap test Suite 46 from python-check to uv-check coverage

Docs and script comments (no functional skill invocations changed):
- resolve_config.py / resolve_customization.py docstrings: drop the
  "No uv ... plain python3 is sufficient" claims; frame uv run as the
  standard, python3 as the transition fallback; examples use uv run
- customize-bmad.md (en/fr/vi-vn): same reframing; example commands use
  uv run
- Update uv run hints in brain.py / list_customizable test comments
2026-06-22 00:03:03 -05:00
Brian b9431d6d99 Shared canonical memlog script (src/scripts/memlog.py) + bmad-spec as first consumer (#2462)
* bmad-spec: make the memlog canonical, SPEC.md a derived view

Replace the bespoke .decision-log.md with the shared memlog script
(_bmad/scripts/memlog.py, same location as resolve_customization.py).
The append-only memlog becomes the single source of truth; SPEC.md and
spec-authored companions are re-derived from it (plus cited sources for
raw content) on each run instead of hand-patched. This makes bmad-spec
the sole writer of the spec and lets the surrounding steps (PRD, UX,
architecture, epics) feed one spec in any order without merge drift.

- New "Memory and derivation" section: memlog canonical, SPEC.md a
  projection, single-writer rule, append/init via the shared script,
  no status field (terminal moments are event entries).
- Operation reads the prior memlog (not the rendered SPEC.md) as the
  authority on decisions and capability IDs on update.
- Conflict-surfacing: live sources/companions that disagree on a field
  are raised to the user, resolution logged as a new entry.
- Rename .decision-log.md -> .memlog.md across SKILL.md and assets.

* core: add shared canonical memlog.py in src/scripts

Single source-of-truth memlog: append-only, chronological working-memory
log for skills. Installs to _bmad/scripts/memlog.py via the existing
src/scripts sync (beside resolve_customization.py), so any skill can call
it at runtime — bmad-spec is the first consumer.

Merges the neutral API (--workspace, free-form --type/--by, generic set)
with crash-safe fsync atomic writes. No lifecycle status by design: a
memory log records completion as an event entry, never a frontmatter flag.
Also accepts --path for callers that hold the file path directly. 30 tests.

* bmad-spec: include event in memlog --type list

The documented append --type set omitted event while the next line
requires --type event for terminal moments. Align the list.

* Fix memlog Python floor and exclude tests from install

- memlog.py: add 'from __future__ import annotations' so PEP 585/604
  hints stay lazy; the script runs on Python 3.8+ instead of crashing
  below 3.10. Correct the requires-python header to >=3.8.
- installer.js: filter tests/, __pycache__/, .pytest_cache/, and *.pyc
  out of _installSharedScripts so dev-only files never ship to users.
2026-06-11 08:17:03 -05:00
Rayan Salhab f28d04a92a fix: write customization JSON as UTF-8 (#2414)
Co-authored-by: cyphercodes <cyphercodes@users.noreply.github.com>
Co-authored-by: Brian <bmadcode@gmail.com>
2026-05-24 14:42:45 -05:00
Brian 4405b817a9 refactor(skills): remove bmad-skill-manifest yaml; introduce central config.toml (#2285)
* refactor: remove bmad-skill-manifest yaml; introduce four-layer central config.toml

- Agent essence moves from per-skill bmad-skill-manifest.yaml files
  into each module.yaml's `agents:` block (code, name, title, icon,
  description). Per-agent customize.toml remains the deep-behavior
  source of truth.
- Installer emits four TOML files:
    _bmad/config.toml              team install answers + agent roster
    _bmad/config.user.toml         user install answers
    _bmad/custom/config.toml       team overrides stub
    _bmad/custom/config.user.toml  personal overrides stub
  Prompts declare scope: user to route answers to config.user.toml.
- resolve_config.py merges four layers: base-team -> base-user ->
  custom-team -> custom-user.
- Three consumer skills (party-mode, advanced-elicitation,
  retrospective) switched from agent-manifest.csv to the resolver.
- installer.js mergeModuleHelpCatalogs now takes the in-memory
  agent list from ManifestGenerator -- no CSV roundtrip.
- Deleted: 6 bmad-skill-manifest.yaml files, agent-manifest.csv
  emission, collectAgents/getAgentsFromDirRecursive,
  paths.agentManifest().

* fix(installer): strip core-key pollution from [modules.*]; soften config headers

- writeCentralConfig now always strips core-module keys from every
  [modules.<code>] bucket, even when the module's schema is not
  available in src/ (external / marketplace modules like cis, bmb).
  Core values belong in [core] only; workflows read them directly.
- When the module's own schema IS available (built-in modules),
  also drop any key it does not declare as a prompt — same
  spread-pollution filter as before, now layered on top.
- Section-aware headers on both _bmad/config.toml and
  _bmad/config.user.toml: [core] / [modules.*] values are
  editable (installer reads them as defaults on next install);
  [agents.*] is regenerated from module.yaml and will be wiped —
  overrides for agents go in _bmad/custom/config*.toml instead.

* docs: cover central config.toml + Diataxis prose pass across three files

Document the new four-file central configuration surface (_bmad/config.toml,
config.user.toml, and custom/ overrides) alongside the existing per-skill
customize.toml. Make editing rules, scope partitioning, and when-to-use-which
guidance explicit.

- customize-bmad.md: new "Central Configuration" section with editing rules,
  three worked examples (rebrand, fictional agent, module settings override),
  and a "when to use which surface" table. Converted five h4 headers to
  bold paragraph intros per style guide.
- expand-bmad-for-your-org.md: two-layer mental model extended to three;
  new Recipe 5 with three variants (rebrand, custom crew, pinned team
  settings); reinforcement table extended.
- named-agents.md: noted the dual customization surface — per-skill shapes
  behavior, central config shapes roster identity.

Diataxis prose pass applied across all three files: banned vocabulary
check, em-dash cap, hypophora / metanoia / amplificatio / stakes-inflation
cleanup, rhythm and burstiness fixes. Structural conformance verified;
markdownlint and prettier clean.

* test+docs: add central config unit tests; fix stale recipe count

- test: two new suites (35 + 36) covering writeCentralConfig and
  ensureCustomConfigStubs. Verifies scope partitioning (user_name
  lands only in config.user.toml), core-key pollution stripping
  from [modules.*], unknown-schema fallthrough (external modules
  survive without schema), agent roster baked into config.toml
  [agents.*] only, stub-preservation on re-install. 44 new
  assertions.
- docs: fixed four stale "four recipes" references to say "five"
  after Recipe 5 (Customize the Agent Roster) was added. Touches
  frontmatter, opening paragraph, Combining Recipes paragraph,
  and the named-agents cross-link blurb.

* fix: address PR review feedback on central config

- resolve_config.py argparse: three-layer → four-layer description
- SKILL/workflow/explanation docs: document all four layers including
  _bmad/config.user.toml (was missing from merge-stack descriptions)
- customize-bmad.md + installer headers: drop the false "direct edits to
  config.toml persist" claim; installer reads from per-module config.yaml,
  not central TOML, so direct edits get clobbered. Route users to
  _bmad/custom/config.toml for durable overrides
- writeCentralConfig: warn loudly when a module.yaml can't be parsed
  (previously silent — user-scoped keys could mis-file into team config)
- writeCentralConfig: preserve [agents.*] blocks for modules that didn't
  contribute fresh agents this run (e.g. quickUpdate skipping modules
  whose source is unavailable) so the roster doesn't silently shrink
- add extractAgentBlocks helper + Test Suite 37 covering preservation

Addresses comments from augmentcode and coderabbitai on PR #2285.
2026-04-19 23:11:44 -05:00
Brian 0dbfae675b feat(skills): TOML-based agent and workflow customization (#2284)
* feat(skills): TOML-based agent customization with stdlib Python resolver

Re-applies PR #2282's three-layer customization model (skill defaults →
team → user) but swaps YAML for TOML and uv for stdlib tomllib. Users
no longer need uv, pip, or a virtualenv — plain python3 (3.11+) is
sufficient, since tomllib shipped in the standard library.

## Schema changes vs PR #2282

- Flat agent schema: fields live directly under [agent], no nested
  metadata/persona sub-tables. Easier to author, less indentation.
- Non-configurable identity: name and title are declared in
  customize.toml as source-of-truth metadata (for future skill-manifest
  generation) but SKILL.md ignores overrides there — identity is
  hardcoded to preserve brand recognition.
- role redefined: now describes what the skill does for the user
  within its module phase, not a restatement of the title.
- persistent_facts replaces the activation-time file-context load AND
  the old memories concept. Entries can be literal sentences or
  file: prefixed paths/globs; avoids collision with the upcoming
  runtime memory sidecar.
- activation_steps_prepend / activation_steps_append harmonized across
  agents and workflows (replaces agent-specific critical_actions).
- [workflow] namespace mirrors [agent] for workflow customization.
  Same four structural rules, same field vocabulary.

## Resolver (src/scripts/resolve_customization.py)

Four purely structural merge rules, zero field-name hardcoding:

  - Scalars: override wins
  - Tables: deep merge
  - Arrays of tables where every item has `code` or `id`: merge by
    that key (matching keys replace, new keys append)
  - Any other array: append

No removal mechanism — overrides cannot delete base items. Fork the
skill or override by code with a no-op value to suppress defaults.

## Agents ported (6)

All six BMad agents now ship customize.toml + rewritten SKILL.md:
analyst (Mary), tech-writer (Paige), pm (John), ux-designer (Sally),
architect (Winston), dev (Amelia). Each uses the same 8-step
activation template: resolve → execute prepend → adopt persona →
load persistent facts → load config → greet (with {agent.icon}) →
execute append → dispatch or present menu.

Step 8 supports fast-path invocation: "hey Mary, let's brainstorm"
dispatches the matching menu item directly after greeting, skipping
the menu render when intent is clear. Chat, clarifying questions,
and bmad-help remain available when nothing on the menu fits.

## Installer + tooling

- _bmad/scripts/ provisioned on install (copies src/scripts/)
- _bmad/custom/ seeded with .gitignore for *.user.toml on fresh install
- Non-module-dir filter extended to skip _memory, memory, docs,
  scripts, and custom when scanning for modules
- Dead _config/agents/ directory no longer created
- metadata.capabilities removed from agent-manifest.csv and schema
- eslint config extended to cover src/scripts/**
- validate-file-refs.js knows about custom/ as install-only

## Deferred for follow-up

- bmad-product-brief workflow port (the pilot that demonstrates
  [workflow] + on_complete)
- Translated docs (cs/fr/vi-vn/zh-cn) — regenerate from English

* feat(skills): port bmad-product-brief to TOML workflow customization

Completes the customization surface rollout by giving the product-brief
workflow the same override model as the six BMad agents, under the
[workflow] namespace instead of [agent].

## customize.toml

Mirrors the agent shape under [workflow] with:
- activation_steps_prepend / activation_steps_append (harmonized across
  agents and workflows — same field names, same append semantics)
- persistent_facts with the file: convention, seeded with
  file:{project-root}/**/project-context.md
- on_complete scalar (renamed from PR #2282's skill_end for clarity —
  reads cleaner as "what runs when the workflow completes")

## SKILL.md

7-step workflow activation:
  1. Resolve workflow block
  2. Execute prepend steps
  3. Load persistent facts (file: or literal)
  4. Load config
  5. Greet if not already
  6. Execute append steps
  7. Stage 1 — Understand Intent

python3 + stdlib tomllib invocation; no uv required.

## Prompt file changes

- Path normalization: ../agents/ → agents/, ../resources/ → resources/,
  bare foo.md → prompts/foo.md. All references now resolve from the
  skill root (matches the convention documented in SKILL.md).
- Paths: meta-line added to each of the 4 prompt files that reference
  other files, reinforcing "bare paths resolve from skill root" so the
  LLM doesn't lose the convention when operating two hops into a
  prompt chain.
- finalize.md terminal stage now calls the resolver for
  workflow.on_complete — non-empty values run as the final step.

## Validation

- Resolver output verified: 4 workflow fields returned cleanly.
- validate-file-refs.js: 254 files scanned, 139 refs checked, 0 broken.
- test:refs: passing.

* docs(skills): enterprise customization recipes + workflow template variable

Three independent improvements bundled because they share the same
surface (workflow/agent customization) and landed from the same design
discussion:

## Fallback sentence disambiguated (7 SKILL.md files)

The "if the script fails" fallback used to say `{project-root}/_bmad/
custom/{skill-name}.toml` for the team override and then just `{skill-
name}.user.toml` for the user override, leaving the user file's
location implicit. LLMs could reasonably guess skill root or project
root instead. Replaced with an unambiguous numbered list that spells
out the full path for every file in the merge chain.

## Product-brief: stage promotion + brief_template variable

- Promoted `## Stage 1: Understand Intent` from a nested step inside
  "On Activation" to a top-level section. The previous "Step 7: Stage
  1 — Understand Intent → Proceed to Stage 1 below" was mechanical
  numbering pretending to be a step. Activation now ends cleanly at
  Step 6; Stage 1 is a peer section.
- Added `brief_template` as a workflow-level scalar customization
  defaulting to `resources/brief-template.md`. Stage 4 reads
  `{workflow.brief_template}` instead of the hardcoded path, so orgs
  can point at their own template under `{project-root}/...` without
  forking the skill.

## New doc: docs/how-to/extend-bmad-for-your-org.md

Four worked recipes that together cover most enterprise scenarios:

1. Shape an agent across every workflow it dispatches (dev agent +
   Context7 MCP + Linear search — the highest-leverage pattern)
2. Enforce org conventions inside a specific workflow (product-brief
   + compliance-field persistent_facts)
3. Publish completed outputs to external systems (product-brief +
   Confluence + Jira via MCP, gated on user confirmation for Jira)
4. Swap in your own output template (product-brief + brief_template
   variable swap)

Opens with the two-layer mental model (agent spans workflows,
workflow is local) so readers pick the right granularity before
reading any recipe. Closes with a "Combining Recipes" section
showing all four composed. Cross-linked from customize-bmad.md.

## Validation

- Resolver: workflow.brief_template returns the default cleanly.
- validate-file-refs.js: 254 files scanned, 146 refs checked
  (+7 from this commit), 0 broken.

* docs(skills): encourage CLAUDE.md/AGENTS.md reinforcement of critical rules

Added a "Reinforce Global Rules in Your IDE's Session File" section to
extend-bmad-for-your-org.md. BMad customizations only load when a
skill activates, but IDE session files (CLAUDE.md, AGENTS.md, cursor
rules, copilot-instructions) load every turn — worth restating the
most critical rules there too so they survive ad-hoc chat outside a
BMad skill.

Includes a one-line example reinforcing the Recipe 1 Context7 rule,
plus a scope table that clarifies what each layer is for:
  - IDE session file: universal, every session, keep succinct
  - Agent customization: persona-specific, every dispatched workflow
  - Workflow customization: one workflow run

Emphasizes brevity — noise in the session file crowds out signal.

* docs(skills): add Named Agents explanation doc

New docs/explanation/named-agents.md walking through the three-legged
stool (skills + named agents + customization) with the "Hey Mary,
let's brainstorm" activation flow as the narrative thread.

Covers:
- Why named agents vs menu-driven or prompt-driven alternatives
- The 8-step activation flow and what each step contributes
- How customization scales the model beyond a single developer
- Cross-links to the how-to docs for implementation details

Sits alongside brainstorming.md, quick-dev.md, party-mode.md in the
explanation folder — feature narratives for users who want to
understand why BMad is designed the way it is, not just how to use it.

* docs(skills): clarify that keyed-merge requires a single identifier key per array

Review feedback (PR #2284) flagged that the merge-rules wording was
ambiguous: "every item has a `code` or `id` field" could reasonably
be read as "each item individually has at least one of the two",
allowing arrays to mix `code` and `id` across items.

The resolver has always required all items share the *same* identifier
key (all `code`, or all `id`). Mixed arrays fall through to append —
intentional, because mixing identifier keys within one array is a
schema smell and any guess about which key should merge creates a
worse trap than the append-fallback.

Clarified in three places:
- Merge-rules table in customize-bmad.md: "every item shares the
  **same** identifier field"
- `code`/`id` convention paragraph: "pick **one** convention ... and
  stick with it across the whole array"
- Resolver docstring and `_detect_keyed_merge_field` docstring:
  explicit note that mixed arrays fall through with rationale

No behavior change.

* docs(skills): address CodeRabbit review — fallback rules, OS claim, headless greeting

Three fixes from PR #2284 review feedback:

## 1. Fallback merge wording (7 SKILL.md files)

Every SKILL.md told the LLM to merge the three customization files
"in priority order (later wins)" when the resolver fails. That reads
as shallow last-write-wins — but the resolver does structural merge
(scalars override, tables deep-merge, code/id-keyed arrays merge by
key, other arrays append). Following the old wording manually would
have silently stripped base `principles`, `persistent_facts`, and
`menu` items whenever a team override was present.

Expanded the fallback sentence to restate the four structural rules
explicitly, matching the resolver's behavior.

Applied to all 6 agents + bmad-product-brief workflow.

## 2. Python 3.11 / OS shipping claim (customize-bmad.md)

The docs claimed "macOS 13+, Ubuntu 22.04+, Debian 12+, Fedora 37+
all ship 3.11 or newer." Inaccurate — Ubuntu 22.04 defaults `python3`
to 3.10.6 (3.11 is a separate package), and macOS doesn't really
ship Python by default anymore.

Replaced with honest guidance: check `python3 --version` and note
that macOS without Homebrew and Ubuntu 22.04 default to 3.10 or
earlier.

## 3. Autonomous mode greeting gate (bmad-product-brief)

Product-brief's activation-mode detection documents autonomous mode
as "produce complete brief without interaction" — but Step 5 greeted
unconditionally, adding conversational output before the headless
artifact. Gated the greeting on `{mode}` != `autonomous`.

## Dismissed (replied on thread)

- `.gitignore` migration from *.user.yaml to *.user.toml: YAML
  installer code was in reverted #2282, never released. No users
  affected. Same rationale as Augment's earlier thread.

Validated: 254 files, 146 refs, 0 broken. test:refs 7/7,
test:install 242/242.

* docs: rename Extend to Expand throughout customization docs
2026-04-19 19:30:29 -05:00
Brian e550df2474 Revert "feat(skills): YAML-based agent customization with Python resolver (#2282)" (#2283)
This reverts commit bd1c0053d5.
2026-04-19 11:09:21 -05:00
Brian bd1c0053d5 feat(skills): YAML-based agent customization with Python resolver (#2282)
Three-layer customization (skill defaults → team → user) for BMad agents    
  and any skill that opts in. Users edit `_bmad/custom/{skill-name}.yaml`
  (team, committed) or `{skill-name}.user.yaml` (personal, gitignored);       
  customizations survive updates.                                             
                                                                              
  Resolver is a Python script using PEP 723 inline metadata, invoked via      
  `uv run` so deps auto-install into a cached isolated env on first call.     
  This aligns with Anthropic's Agent Skills spec and BMB conventions, and     
  keeps the dependency declared (scannable by pip-audit/Dependabot) rather    
  than vendored.                                                              
                                                                              
  ## Design choices                                                           
                                                                              
  - **Agent identity is hardcoded** in SKILL.md (name, title, Overview prose) 
    so skills can be invoked reliably by role *or* default name. Brand
    recognition is preserved; customization shapes behavior, not identity.    
  - **Luminary-anchored personas** (e.g. "Channels Martin Fowler's            
    pragmatism and Werner Vogels's cloud-scale realism") deliver ~55%
    token savings per agent while preserving distinctive voice beats.         
  - **Universal per-field merge rules** with v6.1-compatible agent            
    semantics: metadata shallow-merge, persona replace, critical_actions      
    and memories append, menu merge-by-code, all else deep-merge.             
  - **Workflow customization** shares the same surface — `bmad-product-brief`
    pilots `activation_steps_prepend`, `activation_steps_append`, and         
    `skill_end` hooks that any workflow-style skill can adopt.                
                                                                              
  ## Infrastructure                                                           
                                                                              
  - `_bmad/scripts/` houses shared Python scripts (resolver + future).        
  - `_bmad/custom/` is provisioned empty with a seeded `.gitignore` for
    `*.user.yaml` on fresh installs.                                          
  - Installer filters ensure `scripts/`, `custom/`, and sidecar-generated   
    `memory/` directories are never treated as modules.                       
  - Dead v6.1 code cleaned up: `_config/agents/` no longer created,         
    `metadata.capabilities` removed from schema and CSV manifest.
2026-04-18 23:13:31 -05:00