From 0060f9c2406705e6d17475f7e7709aa1748dc178 Mon Sep 17 00:00:00 2001 From: Brian Madison Date: Mon, 20 Apr 2026 01:07:15 -0500 Subject: [PATCH 1/4] feat(builders): customize.toml support for workflows, agents, and modules Teach the three builders to emit skills that participate in BMad's customize.toml override model (per-skill deep behavior customization) and the module.yaml agents roster contract. ## Workflow Builder - New Phase 3.5 "Configurability Discovery" with opt-in gate during build. Opting in emits a customize.toml with activation hooks, persistent_facts (default globs project-context), on_complete, and any workflow-specific scalars the author lifts (templates, output paths, hook points). - New assets: customize-template.toml, sample-customize-product-brief.toml (verbatim copy of bmm's product-brief as ground-truth reference). - SKILL-template.md now wraps resolver activation steps in {if-customizable} conditional; non-customizable workflows emit no customize.toml and no resolver wiring. - Updated standard-fields.md with [workflow] field catalog and naming conventions (*_template, *_output_path, on_). ## Agent Builder - [agent] metadata block always emitted (install-time roster contract: code, name, title, icon, description, agent_type). Override surface (persistent_facts, activation hooks) is opt-in, default no for memory and autonomous archetypes whose sanctum owns behavior. - First-Breath-named agents: name field ships empty; owner fills via _bmad/custom/config.toml [agents.] after activation. Installer and UIs tolerate empty name and fall back to title. - New assets: customize-template.toml, sample-customize-analyst.toml. - SKILL-template.md and SKILL-template-bootloader.md wrap resolver activation in {if-customizable}. - Updated build-process.md, standard-fields.md, agent-type-guidance.md, template-substitution-rules.md with metadata gathering, opt-in flow, archetype-specific defaults, and sanctum-first guidance for memory agents. ## Module Builder - create-module.md reads each skill's customize.toml during discovery and populates module.yaml:agents[] from the [agent] metadata block. Empty name carried through for First-Breath-named agents. - validate-module.md checks agent roster validity: required fields present, roster agrees with each agent's own customize.toml, drift detection. ## Quality Scanners - New quality-scan-customization-surface.md in both builders (workflow-builder L7, agent-builder L8). Covers opportunities (hardcoded templates that should be lifted, missing persistent_facts defaults, missing hooks, workflows not opted in despite obvious variance) and abuse (boolean toggle farms, identity overrides leaking into workflow blocks, arrays-of-tables without code/id keys, over- named scalars, duplication between customize.toml and SKILL.md). The agent variant adds archetype-specific rules: metadata drift detection and sanctum-conflict flagging for memory/autonomous agents. - Wired into quality-analysis.md as an LLM scanner. - report-quality-scan-creator.md adds a "Customization Surface" section in the Detailed Analysis template. - quality-dimensions.md gains a new Customization Surface dimension as a build-time mental checklist. ## Docs - New explanation: docs/explanation/customization-for-authors.md The "when and why" decision guide for module authors, including a full bmad-session-prep worked example (tabletop RPG GM workflow) that walks field-by-field through customization decisions and reasoning. - New how-to: docs/how-to/make-a-skill-customizable.md Procedural companion: opt-in moment, scalar naming, default setup, override testing. - Cross-links added to five existing explanation docs: what-are-bmad-agents.md, what-are-workflows.md, agent-memory-and-personalization.md (sanctum as customization surface note), module-configuration.md (config vs customization distinction), skill-authoring-best-practices.md. Note: The customization-for-authors and make-a-skill-customizable docs are author-facing companions to bmm's end-user-facing docs/how-to/customize-bmad.md. --- .../agent-memory-and-personalization.md | 4 + docs/explanation/customization-for-authors.md | 146 ++++++++++++++ docs/explanation/module-configuration.md | 6 + .../skill-authoring-best-practices.md | 4 + docs/explanation/what-are-bmad-agents.md | 8 + docs/explanation/what-are-workflows.md | 6 + docs/how-to/make-a-skill-customizable.md | 144 +++++++++++++ .../assets/SKILL-template-bootloader.md | 12 ++ .../assets/SKILL-template.md | 25 +++ .../assets/customize-template.toml | 62 ++++++ .../assets/sample-customize-analyst.toml | 87 ++++++++ .../references/agent-type-guidance.md | 21 ++ .../references/build-process.md | 73 +++++++ .../references/quality-analysis.md | 3 + .../references/quality-dimensions.md | 14 +- .../quality-scan-customization-surface.md | 190 ++++++++++++++++++ .../references/report-quality-scan-creator.md | 4 + .../references/standard-fields.md | 66 ++++++ .../references/template-substitution-rules.md | 18 ++ .../references/create-module.md | 31 +++ .../references/validate-module.md | 9 + .../assets/SKILL-template.md | 25 +++ .../assets/customize-template.toml | 56 ++++++ .../sample-customize-product-brief.toml | 51 +++++ .../references/build-process.md | 53 +++++ .../references/quality-analysis.md | 1 + .../references/quality-dimensions.md | 12 +- .../quality-scan-customization-surface.md | 168 ++++++++++++++++ .../references/report-quality-scan-creator.md | 4 + .../references/standard-fields.md | 47 +++++ .../references/template-substitution-rules.md | 12 ++ 31 files changed, 1360 insertions(+), 2 deletions(-) create mode 100644 docs/explanation/customization-for-authors.md create mode 100644 docs/how-to/make-a-skill-customizable.md create mode 100644 skills/bmad-agent-builder/assets/customize-template.toml create mode 100644 skills/bmad-agent-builder/assets/sample-customize-analyst.toml create mode 100644 skills/bmad-agent-builder/references/quality-scan-customization-surface.md create mode 100644 skills/bmad-workflow-builder/assets/customize-template.toml create mode 100644 skills/bmad-workflow-builder/assets/sample-customize-product-brief.toml create mode 100644 skills/bmad-workflow-builder/references/quality-scan-customization-surface.md diff --git a/docs/explanation/agent-memory-and-personalization.md b/docs/explanation/agent-memory-and-personalization.md index 09c5eec..21c07ec 100644 --- a/docs/explanation/agent-memory-and-personalization.md +++ b/docs/explanation/agent-memory-and-personalization.md @@ -41,6 +41,10 @@ ALLCAPS files form the skeleton: consistent structure across all memory agents. └── sessions/ # Raw session logs by date (not loaded on rebirth) ``` +### Sanctum Is the Customization Surface + +For memory and autonomous agents, the sanctum is where customization belongs. PERSONA, CREED, and BOND are calibrated at First Breath, edited by the owner as the relationship develops, and shared across teams as sanctum files when a whole table wants the same voice. The parallel `customize.toml` override surface that stateless agents and workflows use (activation hooks, persistent facts, scalar swaps) is opt-out by default for memory archetypes. Opt in only when you have a narrow org-level need the sanctum cannot express, such as a pre-sanctum compliance acknowledgment before rebirth. See [Customization for Authors](/explanation/customization-for-authors) for the reasoning. + ### Token Discipline Every sanctum file loads every session. That means every token pays rent on every conversation. Memory agents keep MEMORY.md ruthlessly under 200 lines through active curation. If something doesn't earn its place, it gets pruned. diff --git a/docs/explanation/customization-for-authors.md b/docs/explanation/customization-for-authors.md new file mode 100644 index 0000000..db8a365 --- /dev/null +++ b/docs/explanation/customization-for-authors.md @@ -0,0 +1,146 @@ +--- +title: 'Customization for Authors' +description: How to decide whether your skill should support end-user customization, and what to expose when it does +--- + +Shipping a `customize.toml` is opt-in per skill. This is the author-side counterpart to [How to Customize BMad](https://bmadcode.github.io/bmad/how-to/customize-bmad), which covers the end-user view. Read that first if you haven't; it shows what users experience when they override a skill. This guide is about deciding whether to give them that surface at all. + +## The Problem + +Every customization knob you ship is a promise. Users pin values to it, teams commit overrides to git, and future releases have to respect the shape you locked in. Over-exposing makes the skill harder to evolve and invites drift; under-exposing forces forks for changes that should have been a three-line TOML file. + +Aim to expose what varies naturally across your users, and nothing else. + +## How Authoring Customization Fits + +BMad has a three-layer override model from the user's side: + +```text +Priority 1 (wins): _bmad/custom/{skill-name}.user.toml (personal, gitignored) +Priority 2: _bmad/custom/{skill-name}.toml (team/org, committed) +Priority 3 (last): skill's own customize.toml (your defaults) +``` + +As an author you own Priority 3. You ship `customize.toml` next to `SKILL.md`. Every field you put there is a commitment to your users: this is what I support overriding. The resolver merges layers structurally (scalars win, arrays of tables keyed by `code` or `id` replace-by-key, other arrays append), so you don't write merge logic. You write defaults and trust the shape. + +## The Three Questions + +For each candidate knob, ask: + +1. **Does it vary naturally across the actual user population?** If every user wants roughly the same value, don't make it configurable. Pick the right default and move on. +2. **Is it the skill's identity, or something the skill consumes?** Identity stays baked. Consumed context (templates, facts, output paths, tone) is the right surface. +3. **Would hiding it force a fork, or just a sentence?** If the alternative is forking the whole skill, expose it. If the alternative is a one-line sentence the user can drop into `persistent_facts`, hide it. + +Candidates that pass all three earn a place in `customize.toml`. Everything else stays baked, or gets folded into `persistent_facts` where sentence-shaped variance belongs. + +## Agent vs Workflow Defaults + +Agents and workflows enter the customize.toml question from different starting points. + +| Surface | Metadata block | Override surface | Notes | +| --- | --- | --- | --- | +| Agent | Always required | Opt-in | Metadata feeds `module.yaml:agents[]` and the central agent roster. | +| Workflow | Not required | Fully opt-in | No roster. If you don't opt in, no `customize.toml` is emitted at all. | + +For agents, you always ship `customize.toml` (the roster depends on it). The real question is whether it carries an override surface beyond metadata. For workflows, the choice is binary: ship one or don't. + +## Memory and Autonomous Agents + +Default to **no** on the override-surface opt-in for memory and autonomous agents. Their sanctum (PERSONA, CREED, BOND, CAPABILITIES) is already the customization surface. It's calibrated at First Breath, evolved by the owner over time, and shared across teams as sanctum files when the whole team wants the same voice. A parallel TOML surface competes with that; you end up with two places to shape the agent and neither fully owns the job. + +Opt in only when you have a specific org-level need the sanctum can't express. Pre-sanctum compliance loads qualify (a legal banner acknowledgment gate before rebirth, for example). Persona tweaks don't. + +## A Worked Example: `bmad-session-prep` + +A weekly session-prep workflow for tabletop RPG game masters. It reads the last session's log, reviews open campaign threads, drafts the scene spine, stats NPCs and encounters, and produces a GM notes document to run from. + +Here's how I'd customize it, field by field. + +### `persistent_facts` (default globs the campaign bible) + +```toml +persistent_facts = [ + "file:{project-root}/campaigns/**/campaign-bible.md", + "file:{project-root}/campaigns/**/house-rules.md", +] +``` + +Every GM runs a different world. Without their campaign bible in context, the workflow is a generic fantasy prep tool that knows nothing about the party's rivals, the kingdom's politics, or last month's cliffhanger. The default glob is shaped so a GM can drop a `campaign-bible.md` in their project and the workflow picks it up. Forcing them to paste world context at the start of every session would burn trust. That's what persistent facts are for. + +### `system_rules_template` (scalar, default to D&D 5e) + +```toml +system_rules_template = "resources/dnd-5e-quick-reference.md" +``` + +D&D 5e, Pathfinder 2e, and Call of Cthulhu reason about encounters in very different ways. A PF2e GM who overrides this with their own rules reference gets correctly-calibrated encounter math without the workflow pretending to know a system it doesn't. I'm not trying to catalog every RPG; I ship one default that covers most users and let everyone else swap in their own reference. The `*_template` suffix signals what changes if you touch it. + +### `session_notes_template` (scalar) + +```toml +session_notes_template = "resources/session-notes-minimalist.md" +``` + +GM prep style is personal. Some GMs want theater-of-mind bullets; others want scene blocks with initiative trackers pre-filled and read-aloud boxes for boxed text. No single shipping default wins against that variance. The structural fact that "prep produces notes" is universal, though, so the override changes the shape of the notes file, not the stage sequence. + +### `on_complete` (scalar, default empty) + +```toml +on_complete = "" +``` + +The core skill ends when notes are drafted. Some GMs want the workflow to draft a Discord teaser for the group chat, others want encounter stat blocks pushed to Roll20, others want a pre-game meditation prompt. These are real patterns, but they're downstream of the skill's job, not part of it. An empty default means the skill doesn't presume. Override example: + +```toml +on_complete = "Draft a 2-sentence Discord teaser ending on a cliffhanger. Save to {project-root}/teasers/next-session.md" +``` + +### `activation_steps_prepend` (pre-flight context load) + +Before the workflow asks the GM anything, some tables want the most recent session log already loaded and summarized: + +```toml +activation_steps_prepend = [ + "Scan {project-root}/session-logs/ and load the most recent log. Extract unresolved threads before asking the GM anything." +] +``` + +Not every GM keeps session logs. The ones who do want the pre-load; the ones who don't would get a broken activation if it were baked in. Opt-in via the prepend hook lets both tables use the same skill. + +### What I'd NOT expose + +The stage sequence (recap, threads, spine, NPCs, notes) is the skill's identity. A GM who wants a very different flow (solo journaling, West Marches gossip round) should fork. Every stage I make optional erodes what the skill is. + +Mechanical encounter math toggles like `auto_balance_cr` or `verbose_stat_blocks` stay out. The LLM handles those naturally once it has the system reference. Toggles here would amount to telling the executor how to do its job. + +Per-stage question order stays out too. Too fiddly. If it matters enough to customize, you're describing a different skill. + +## Naming and Shape Conventions + +When you do expose a scalar, name it like a contract. + +| Pattern | Use for | Example | +| --- | --- | --- | +| `_template` | File paths for templates the skill loads | `brief_template = "resources/brief.md"` | +| `_output_path` | Writable destinations | `report_output_path = "{project-root}/docs/reports"` | +| `on_` | Hook scalars (prompts or commands) | `on_complete = ""` | + +A scalar named `brief_template` tells the user what changes if they override it. A scalar named `style_config` or `format_options_file` doesn't. + +For arrays of tables (menus, capability rosters), give every item a `code` or `id` field. The resolver uses that key to merge by code: matching entries replace in place, new entries append. Mixing `code` on some items and `id` on others falls back to append-only, which is rarely what authors want and almost never what users expect. + +There's no removal mechanism. If you need users to suppress a default menu item, have them override it by `code` with a no-op description or prompt. If the natural override flow requires deleting defaults, your surface is probably wrong, and you should reconsider what belongs in the skill body. + +## Where This Shows Up in Your Build + +Both the Agent Builder and the Workflow Builder ask the opt-in question during requirements gathering. If you say yes, a follow-up phase called Configurability Discovery walks you through candidate knobs (templates, output paths, hooks) and emits them into your skill's `customize.toml`. If you say no, workflows get no `customize.toml` at all, and agents get a metadata-only block. + +The builders default the opt-in to **no** in headless mode unless you pass `--customizable`. Customization should be a deliberate decision, not an automatic one. + +## When to Graduate to a Fork + +If your override surface grows to the point where shipping multiple related overrides is the common user path, the skill probably wants splitting. Two signals: users routinely ship four or more overrides together to make the skill work for them, or the overrides imply structural changes that `persistent_facts` and scalar swaps can't actually express. When you see either, a second skill variant is the honest answer, not a bigger TOML. + +:::tip[Rule of Thumb] +Ship one good default over a permutation forest of toggles. A scalar called `include_combat_section = true/false` is almost always a sign the author couldn't decide what the skill should do. Pick the default. Fork if you need different. +::: diff --git a/docs/explanation/module-configuration.md b/docs/explanation/module-configuration.md index cb3d8d9..55a6b7e 100644 --- a/docs/explanation/module-configuration.md +++ b/docs/explanation/module-configuration.md @@ -21,6 +21,12 @@ Most modules should not need configuration at all. Before adding configurable va If you are building a single standalone agent or workflow, you do not need a separate setup skill. The Module Builder can package it as a **standalone self-registering module** where the registration logic is embedded directly in the skill via an `assets/module-setup.md` reference file, and runs on first activation or when the user passes `setup`/`configure`. ::: +## Configuration vs Customization + +Module configuration (this doc) and per-skill customization (`customize.toml`) are different surfaces with different jobs. Configuration is about install-time answers: paths, language, team preferences, per-module install answers. It lives in `_bmad/config.toml` and `config.user.toml` at the project root and is consumed by many skills. Customization is about per-skill behavior overrides: activation hooks, persistent facts, swappable templates. It lives in `_bmad/custom/{skill-name}.toml` and is scoped to one skill. + +Use configuration when the value is cross-cutting (every skill needs to know the output folder). Use customization when the value shapes one skill's behavior (this workflow's brief template). Some values legitimately fit both surfaces; the [End-User Customization Guide](https://bmadcode.github.io/bmad/how-to/customize-bmad) includes a decision table for that case. For the author-side decision about whether to expose customization at all, see [Customization for Authors](/explanation/customization-for-authors). + ## What Module Registration Does Module registration serves two purposes: diff --git a/docs/explanation/skill-authoring-best-practices.md b/docs/explanation/skill-authoring-best-practices.md index 050a966..34fd856 100644 --- a/docs/explanation/skill-authoring-best-practices.md +++ b/docs/explanation/skill-authoring-best-practices.md @@ -36,6 +36,10 @@ Six dimensions to keep in mind during the build phase. The quality scanners chec | **Path Construction** | Never use `{skill-root}`. Use `{project-root}` for any project-scope path, `./` for skill-internal. Config variables used directly; they already contain `{project-root}` | | **Token Efficiency** | Remove genuine waste (repetition, defensive padding). Preserve context that enables judgment (domain framing, rationale) | +## Shipping a Customization Surface + +When your skill's users come from varied contexts (different orgs, different domains, different taste in output formats), a `customize.toml` surface lets them override specific fields without forking. It's opt-in per skill, and the decision is deliberate: every knob you ship is a promise the resolver will carry across releases. Before you opt in during the build, read [Customization for Authors](/explanation/customization-for-authors) for the decision framework and [How to Make a Skill Customizable](/how-to/make-a-skill-customizable) for the mechanics. + ## Common Patterns ### Soft Gate Elicitation diff --git a/docs/explanation/what-are-bmad-agents.md b/docs/explanation/what-are-bmad-agents.md index e5997f2..316251b 100644 --- a/docs/explanation/what-are-bmad-agents.md +++ b/docs/explanation/what-are-bmad-agents.md @@ -85,6 +85,14 @@ Sanctum architecture, First Breath, PULSE, and the two-tier memory system are co If you're unsure, start with a workflow. You can always wrap it inside an agent later. +## Customization Surface + +Every agent ships a `customize.toml` next to its `SKILL.md`. The metadata block (code, name, title, icon, description, agent_type) is always present; it's the install-time roster contract consumed by `module.yaml:agents[]` and the central agent config. Beyond metadata, an override surface (activation hooks, persistent facts, swappable scalars) is opt-in per skill. + +For memory and autonomous agents, the sanctum is the primary customization surface. Persona, creed, bond, and capabilities all live there and evolve with the owner. A `customize.toml` override surface would compete with that, so the default for those archetypes is opt-out. + +See [Customization for Authors](/explanation/customization-for-authors) for the decision guide, or [How to Customize BMad](https://bmadcode.github.io/bmad/how-to/customize-bmad) for the end-user view. + ## Building Agents The **BMad Agent Builder** (`bmad-agent-builder`) runs six phases of conversational discovery. The first phase detects which agent type fits your vision through natural questions, and the remaining phases adapt based on whether you're creating a stateless expert, a memory-backed companion, or an autonomous agent. diff --git a/docs/explanation/what-are-workflows.md b/docs/explanation/what-are-workflows.md index 4cab46c..71dc08f 100644 --- a/docs/explanation/what-are-workflows.md +++ b/docs/explanation/what-are-workflows.md @@ -62,6 +62,12 @@ Like agents, workflows can support a **Headless Mode**. When invoked headless (t Workflows are also excellent as the **internal capabilities** of an agent. Build the workflow first, then wrap it in an agent if you need persona and memory on top. +## Customization Surface + +Workflow customization is fully opt-in. If you don't need users to override anything, don't ship a `customize.toml` at all; the workflow runs with hardcoded paths and defaults. If you do opt in, the builder walks you through Configurability Discovery, where you name the scalars (templates, output paths, hooks) you want to expose. Users override them through the three-layer model at `_bmad/custom/{skill-name}.toml` and `.user.toml`. + +See [Customization for Authors](/explanation/customization-for-authors) for the decision guide and [How to Make a Skill Customizable](/how-to/make-a-skill-customizable) for the build-time steps. + ## Building Workflows The **BMad Workflow Builder** (`bmad-workflow-builder`) uses the same six-phase conversational discovery as the Agent Builder (intent, classification, requirements, drafting, building, and quality optimization) and produces a ready-to-use skill folder. diff --git a/docs/how-to/make-a-skill-customizable.md b/docs/how-to/make-a-skill-customizable.md new file mode 100644 index 0000000..ae791cc --- /dev/null +++ b/docs/how-to/make-a-skill-customizable.md @@ -0,0 +1,144 @@ +--- +title: 'How to Make a Skill Customizable' +description: Opt your skill into end-user customization during the build, name your scalars well, and test an override +--- + +Use this guide when you're building a skill and you've decided (see [Customization for Authors](/explanation/customization-for-authors)) that end users should be able to override parts of its behavior without forking. You'll hit the opt-in moment in the builder, pick names for the scalars you expose, and verify an override actually works. + +## When to Use This + +- You're building a workflow or stateless agent and want to let teams/org users inject overrides +- You're adding configurability to an existing skill during a rebuild +- You want a swappable template path, output destination, or hook in your skill + +## When to Skip This + +- Your skill is a single-purpose utility users will invoke and forget (overriding makes no sense) +- You're building a memory or autonomous agent whose behavior lives in the sanctum (the sanctum is already the customization surface) +- You haven't decided yet whether you need customization (read the [author guide](/explanation/customization-for-authors) first) + +:::note[Prerequisites] + +- The Agent Builder or Workflow Builder is available in your project +- You've sketched what your skill does and roughly what stages or capabilities it has +- You've read the [author guide](/explanation/customization-for-authors) and know which knobs you want to expose +::: + +## Steps + +### 1. Answer "Yes" to the Opt-In Question + +During the build, both builders ask a version of: + +> Should this skill support end-user customization (activation hooks, swappable templates, output paths)? If no, it ships fixed. Users who need changes fork it. + +Answer **yes** when you want overrides supported. The builder records this as `{customizable} = yes` and routes to the Configurability Discovery phase. + +If you're running headless (`--headless` or `-H`), pass `--customizable` to opt in. The headless default is **no**. + +### 2. Walk Through Configurability Discovery + +The builder proposes candidates auto-detected from your skill design and asks which should be exposed. Typical candidates: + +- **Templates** the skill loads (strongest case) +- **Output destination paths** if the skill writes artifacts +- **`on_` hooks** (prompts or commands executed at lifecycle points) +- **Additional persistent facts** beyond the default campaign-context glob + +For each candidate you accept, the builder asks for a name and a default value. + +### 3. Name Your Scalars Well + +Use the suffix conventions below so a user can tell what a scalar does from its name alone. + +| Pattern | Use for | Example | +| --- | --- | --- | +| `_template` | File paths for templates the skill loads | `brief_template = "resources/brief.md"` | +| `_output_path` | Writable destinations | `report_output_path = "{project-root}/docs/reports"` | +| `on_` | Hook scalars | `on_complete = ""` | + +Specific names like `brief_template` tell the user exactly what the knob does. Vague names like `style_config` or `format_options` force the user to read your SKILL.md to figure it out. + +### 4. Set Good Defaults + +Every scalar you expose needs a default that works on first run. Bare paths resolve from the skill root. Use `{project-root}/...` when the default lives somewhere in the user's project. + +```toml +[workflow] +brief_template = "resources/brief-template.md" # ships inside the skill +on_complete = "" # no default post-hook +persistent_facts = [ + "file:{project-root}/**/campaign-context.md", # glob into the user's project +] +``` + +For arrays of tables (menus, capability rosters), give every item a `code` or `id` field so the resolver can merge by key: + +```toml +[[agent.menu]] +code = "BR" +description = "Run a brainstorm" +skill = "bmad-brainstorming" +``` + +Without a `code` or `id` on every item, the array falls back to append-only merging. That's rarely what users actually want. + +### 5. Wire `{workflow.X}` or `{agent.X}` References in SKILL.md + +The builder does this automatically during emission, but know what's happening: instead of hardcoding `resources/brief-template.md` in your SKILL.md body, the relevant step becomes: + +```markdown +Load the brief template from `{workflow.brief_template}`. +``` + +At runtime, the resolver swaps in whatever the merged scalar is (default, team override, or user override). + +### 6. Test an Override + +After the skill is built, verify overrides work. In the project where you're testing: + +```bash +mkdir -p _bmad/custom +cat > _bmad/custom/{skill-name}.toml <<'EOF' +[workflow] +on_complete = "Print the word CUSTOMIZED to stdout." +EOF +``` + +Run the resolver directly to confirm your override takes effect: + +```bash +python3 _bmad/scripts/resolve_customization.py \ + --skill /path/to/built/skill \ + --key workflow.on_complete +``` + +Output should be `"Print the word CUSTOMIZED to stdout."`. If you see the default, check that your TOML filename matches the skill directory basename exactly and that the `[workflow]` (or `[agent]`) block header is present. + +Then invoke the skill and confirm the customized behavior fires at the expected lifecycle point. + +## What You Get + +When you opt in, your built skill folder includes: + +```text +{skill-name}/ +├── SKILL.md # references {workflow.X} or {agent.X} for customized values +├── customize.toml # your defaults, the canonical schema +├── references/ +├── scripts/ +└── assets/ +``` + +Users get: + +- A documented override surface via `customize.toml` +- Team-scoped overrides via `_bmad/custom/{skill-name}.toml` +- Personal-scoped overrides via `_bmad/custom/{skill-name}.user.toml` +- Automatic precedence handling from the resolver (user beats team beats defaults) + +## Tips + +- **Ship one good default. Skip the booleans.** A flag like `include_combat_section` usually means you haven't decided what the skill does yet. Pick the default. Users who want a radically different shape can fork. +- **Sentence-shaped variance belongs in `persistent_facts`.** Tone, house rules, and domain constraints are sentences the skill carries through the run. Don't enumerate them as scalars. +- **Read [Customization for Authors](/explanation/customization-for-authors) first.** It gives you the three questions to ask for each candidate knob before you start Configurability Discovery. diff --git a/skills/bmad-agent-builder/assets/SKILL-template-bootloader.md b/skills/bmad-agent-builder/assets/SKILL-template-bootloader.md index 6a991f0..92bb2a0 100644 --- a/skills/bmad-agent-builder/assets/SKILL-template-bootloader.md +++ b/skills/bmad-agent-builder/assets/SKILL-template-bootloader.md @@ -23,6 +23,18 @@ Every session is a rebirth. You emerge with nothing — no memory, no identity, ## On Activation +{if-customizable} +### Resolve the Agent Block + +Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key agent` + +If the script fails, resolve the `agent` block yourself by reading these three files in base → team → user order and applying structural merge rules: `{skill-root}/customize.toml`, `{project-root}/_bmad/custom/{skill-name}.toml`, `{project-root}/_bmad/custom/{skill-name}.user.toml`. Scalars override, tables deep-merge, arrays of tables keyed by `code`/`id` replace matching entries and append new ones, all other arrays append. + +Execute each entry in `{agent.activation_steps_prepend}` in order before proceeding. Treat every entry in `{agent.persistent_facts}` as foundational context — `file:` prefixed entries are paths/globs to load, bare entries are facts verbatim. After the routing below dispatches, execute `{agent.activation_steps_append}` before accepting user input. + +Note: your sanctum (PERSONA/CREED/BOND/CAPABILITIES) remains the primary behavior-customization surface. The override hooks above exist for narrow org-level needs that the sanctum cannot express. + +{/if-customizable} {if-module} Load available config from `{project-root}/_bmad/config.yaml` and `{project-root}/_bmad/config.user.yaml` (root level and `{module-code}` section). {/if-module} diff --git a/skills/bmad-agent-builder/assets/SKILL-template.md b/skills/bmad-agent-builder/assets/SKILL-template.md index 0659c0c..4d42a54 100644 --- a/skills/bmad-agent-builder/assets/SKILL-template.md +++ b/skills/bmad-agent-builder/assets/SKILL-template.md @@ -32,6 +32,24 @@ description: { skill-description } # [4-6 word summary]. [trigger phrases] ## On Activation +{if-customizable} +### Step 1: Resolve the Agent Block + +Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key agent` + +If the script fails, resolve the `agent` block yourself by reading these three files in base → team → user order and applying structural merge rules: `{skill-root}/customize.toml`, `{project-root}/_bmad/custom/{skill-name}.toml`, `{project-root}/_bmad/custom/{skill-name}.user.toml`. Scalars override, tables deep-merge, arrays of tables keyed by `code`/`id` replace matching entries and append new ones, all other arrays append. + +### Step 2: Execute Prepend Steps + +Execute each entry in `{agent.activation_steps_prepend}` in order before proceeding. + +### Step 3: Load Persistent Facts + +Treat every entry in `{agent.persistent_facts}` as foundational context for the session. Entries prefixed `file:` are paths or globs — load the referenced contents as facts. All other entries are facts verbatim. + +### Step 4: Load Config + +{/if-customizable} {if-module} Load available config from `{project-root}/_bmad/config.yaml` and `{project-root}/_bmad/config.user.yaml` (root level and `{module-code}` section). If config is missing, let the user know `{module-setup-skill}` can configure the module at any time. Resolve and apply throughout the session (defaults in parens): @@ -46,6 +64,13 @@ Load available config from `{project-root}/_bmad/config.yaml` and `{project-root - `{communication_language}` ({default}) — use for all communications - `{document_output_language}` ({default}) — use for generated document content {/if-standalone} +{if-customizable} + +### Step 5: Execute Append Steps + +Execute each entry in `{agent.activation_steps_append}` in order before accepting user input. + +{/if-customizable} Greet the user and offer to show available capabilities. diff --git a/skills/bmad-agent-builder/assets/customize-template.toml b/skills/bmad-agent-builder/assets/customize-template.toml new file mode 100644 index 0000000..ff4bf04 --- /dev/null +++ b/skills/bmad-agent-builder/assets/customize-template.toml @@ -0,0 +1,62 @@ +# DO NOT EDIT -- overwritten on every update. +# +# Agent customization surface for {skill-name}. +# Team overrides: {project-root}/_bmad/custom/{skill-name}.toml +# Personal overrides: {project-root}/_bmad/custom/{skill-name}.user.toml + +[agent] + +# --- Metadata (install-time roster contract) --- +# Consumed by module.yaml:agents[] and `[agents.]` in central config. + +code = "{agent-code}" +name = "{agent-name-or-empty}" +title = "{agent-title}" +icon = "{agent-icon}" +description = "{agent-description}" +agent_type = "{agent-type}" # stateless | memory | autonomous + +{if-customizable} + +# --- Configurable below. Overrides merge per BMad structural rules: --- +# scalars: override wins • arrays (persistent_facts, activation_steps_*): append +# arrays-of-tables with `code`/`id`: replace matching items, append new ones. +# +# For memory/autonomous agents: your sanctum (PERSONA/CREED/BOND/CAPABILITIES) +# is the primary behavior surface. Prefer editing sanctum files over this block. + +# Steps to run before the standard activation (config load, greet). +# Overrides append. Use for pre-flight loads, compliance checks, etc. + +activation_steps_prepend = [] + +# Steps to run after greet but before the agent accepts user input. +# Overrides append. Use for context-heavy setup that should happen +# once the user has been acknowledged. + +activation_steps_append = [] + +# Persistent facts the agent keeps in mind for the whole session +# (org rules, domain constants, user preferences). Overrides append. +# +# Each entry is either: +# - a literal sentence, e.g. "Our org is AWS-only -- do not propose GCP or Azure." +# - a file reference prefixed with `file:`, e.g. "file:{project-root}/docs/standards.md" +# (glob patterns are supported; the file's contents are loaded and treated as facts). + +persistent_facts = [ + "file:{project-root}/**/project-context.md", +] + +# --- Agent-specific configurables (lifted during Configurability Discovery) --- +# +# Swappable reference docs, output paths, or hooks the builder surfaced with +# the author. Bare paths resolve from the skill root; use `{project-root}/...` +# to point at an org-owned resource elsewhere in the repo. Override wins. +# +# Naming conventions: +# *_template -- file paths for templates the agent loads +# *_output_path -- writable destinations +# on_ -- hook scalars (prompts/commands) + +{/if-customizable} diff --git a/skills/bmad-agent-builder/assets/sample-customize-analyst.toml b/skills/bmad-agent-builder/assets/sample-customize-analyst.toml new file mode 100644 index 0000000..522f5a9 --- /dev/null +++ b/skills/bmad-agent-builder/assets/sample-customize-analyst.toml @@ -0,0 +1,87 @@ +# SAMPLE -- reference copy of bmad-agent-analyst's customize.toml (from bmm). +# Use as a worked example for the [agent] override surface, including a +# capability menu keyed by `code`. This is NOT emitted into built skills; +# it's ground-truth reference for authors. +# +# NOTE: bmm-style stateless agents carry full persona + menu customization +# in this file. Builder-produced agents ship a lighter surface by default -- +# metadata is always present, and the override surface is opt-in. If an +# author has reason to expose persona-style overrides (identity, +# communication_style, principles, menu), the bmm shape below is the +# reference. + +# DO NOT EDIT -- overwritten on every update. +# +# Mary, the Business Analyst, is the hardcoded identity of this agent. +# Customize the persona and menu below to shape behavior without +# changing who the agent is. + +[agent] +# non-configurable skill frontmatter, create a custom agent if you need a new name/title +name="Mary" +title="Business Analyst" + +# --- Configurable below. Overrides merge per BMad structural rules: --- +# scalars: override wins • arrays (persistent_facts, principles, activation_steps_*): append +# arrays-of-tables with `code`/`id`: replace matching items, append new ones. + +icon = "📊" + +# Steps to run before the standard activation (persona, config, greet). +# Overrides append. Use for pre-flight loads, compliance checks, etc. + +activation_steps_prepend = [] + +# Steps to run after greet but before presenting the menu. +# Overrides append. Use for context-heavy setup that should happen +# once the user has been acknowledged. + +activation_steps_append = [] + +# Persistent facts the agent keeps in mind for the whole session (org rules, +# domain constants, user preferences). Distinct from the runtime memory +# sidecar -- these are static context loaded on activation. Overrides append. +# +# Each entry is either: +# - a literal sentence, e.g. "Our org is AWS-only -- do not propose GCP or Azure." +# - a file reference prefixed with `file:`, e.g. "file:{project-root}/docs/standards.md" +# (glob patterns are supported; the file's contents are loaded and treated as facts). + +persistent_facts = [ + "file:{project-root}/**/project-context.md", +] + +role = "Help the user ideate research and analyze before committing to a project in the BMad Method analysis phase." +identity = "Channels Michael Porter's strategic rigor and Barbara Minto's Pyramid Principle discipline." +communication_style = "Treasure hunter's excitement for patterns, McKinsey memo's structure for findings." + +# The agent's value system. Overrides append to defaults. +principles = [ + "Every finding grounded in verifiable evidence.", + "Requirements stated with absolute precision.", + "Every stakeholder voice represented.", +] + +# Capabilities menu. Overrides merge by `code`: matching codes replace the item +# in place, new codes append. Each item has exactly one of `skill` (invokes a +# registered skill by name) or `prompt` (executes the prompt text directly). + +[[agent.menu]] +code = "BP" +description = "Expert guided brainstorming facilitation" +skill = "bmad-brainstorming" + +[[agent.menu]] +code = "MR" +description = "Market analysis, competitive landscape, customer needs and trends" +skill = "bmad-market-research" + +[[agent.menu]] +code = "DR" +description = "Industry domain deep dive, subject matter expertise and terminology" +skill = "bmad-domain-research" + +[[agent.menu]] +code = "CB" +description = "Create or update product briefs through guided or autonomous discovery" +skill = "bmad-product-brief" diff --git a/skills/bmad-agent-builder/references/agent-type-guidance.md b/skills/bmad-agent-builder/references/agent-type-guidance.md index 029bec6..ac288d0 100644 --- a/skills/bmad-agent-builder/references/agent-type-guidance.md +++ b/skills/bmad-agent-builder/references/agent-type-guidance.md @@ -60,6 +60,27 @@ After determining the agent type, assess relationship depth. This informs which Confirm your assessment with the user: "It sounds like this is more of a [long-term creative partnership / focused domain tool] — does that feel right?" +## Customization Surface by Archetype + +Every agent emits a `customize.toml` — the metadata block (`code`, `name`, `title`, `icon`, `description`, `agent_type`) is required for all three types to satisfy the module.yaml roster contract. The override surface beneath it is opt-in and differs by archetype: + +- **Stateless agent** — natural candidate for the override surface. Exposes `activation_steps_prepend/append`, `persistent_facts`, and any agent-specific scalars (e.g. swappable reference docs, output paths). Offer the opt-in during Phase 3; accept either answer. + +- **Memory agent** — sanctum is the primary behavior-customization surface. PERSONA.md, CREED.md, BOND.md, CAPABILITIES.md are calibrated by First Breath and evolved by the owner. A TOML override surface competes with that. **Default the opt-in to no.** Opt in only when the user has a specific pre-sanctum-load need (e.g. org-mandated compliance preload) that the sanctum cannot express. + +- **Autonomous agent** — same as memory. PULSE.md already owns autonomous behavior configuration. Default to no; opt in only with cause. + +### First-Breath-Named Agents + +Memory and autonomous agents whose name is learned during First Breath ship with `name = ""` in `customize.toml`. The owner fills the name post-activation by adding a stanza to `{project-root}/_bmad/custom/config.toml`: + +```toml +[agents.creative-muse] +name = "Zephyr" +``` + +The installer and any roster-consuming UIs tolerate empty `name` and fall back to `title` for display until the owner fills it in. Do not prompt the user for a name at build time for these archetypes — the First Breath experience is where the name is born. + ## Edge Cases - **"I'm not sure if it needs memory"** — Ask: "If you used this agent every day for a month, would the 30th session be different from the 1st?" If yes, it needs memory. diff --git a/skills/bmad-agent-builder/references/build-process.md b/skills/bmad-agent-builder/references/build-process.md index 19e2ada..5833533 100644 --- a/skills/bmad-agent-builder/references/build-process.md +++ b/skills/bmad-agent-builder/references/build-process.md @@ -86,6 +86,53 @@ Key structural context: - **Memory architecture:** Agent memory at `{project-root}/_bmad/memory/{skillName}/` - **Access boundaries:** Read/write/deny zones stored in memory +### Customization Metadata (gather for all agents — feeds `customize.toml` and `module.yaml`) + +Every agent ships a `customize.toml` with an `[agent]` metadata block. The installer reads it to build the agent roster in `module.yaml:agents[]` and the central config's `[agents.]` section. Gather: + +- **`code`** — stable identifier, matches the skill directory basename without module prefix (e.g. `creative-muse`, `analyst`). +- **`name`** — display name (e.g. `Mary`, `Aria`). **For memory/autonomous agents whose name is learned during First Breath: leave empty.** The owner fills it post-activation via `[agents.] name = "..."` in `_bmad/custom/config.toml`. +- **`title`** — role title (e.g. `Business Analyst`, `Creative Muse`). Always fillable at build time, even when `name` is deferred. +- **`icon`** — single emoji used in menus and greetings. +- **`description`** — one-sentence summary of what the agent does. +- **`agent_type`** — `stateless`, `memory`, or `autonomous` (already determined in Phase 1). + +### Customization Opt-In (override surface) + +Ask: _"Do you want this agent to expose override hooks (persistent facts, pre/post-activation steps) so teams can customize it without forking?"_ + +- **No** → `customize.toml` ships with metadata only. SKILL.md does not call the resolver. Simplest shape. +- **Yes** → `customize.toml` additionally carries `activation_steps_prepend`, `activation_steps_append`, `persistent_facts`, and any agent-specific scalars lifted in the next sub-step. SKILL.md gets the resolver step. + +**Default recommendation by archetype:** + +- **Stateless agents** — offer the opt-in; reasonable candidates for overrides (compliance preloads, swappable reference docs). +- **Memory / autonomous agents** — default to **no**. Note: their sanctum (PERSONA/CREED/BOND/CAPABILITIES) is already the primary behavior-customization surface, edited by the owner and evolved via First Breath. A TOML override surface competes with that. Offer opt-in only if the user has a clear use case (e.g. pre-sanctum-load compliance step). + +In headless mode, default to **no** unless `--customizable` is passed. Record the answer as `{customizable}`. + +### Configurability Discovery (only if `{customizable}` is yes) + +Identify swappable points. Walk through the agent's planned structure and surface candidates: + +- **Reference documents** the agent loads (e.g. a style guide, a domain glossary) — each becomes a named scalar. +- **Output destination paths** if the agent writes artifacts. +- **`on_` hooks** — prompts/commands executed at hook points. +- **Pre/post-activation step arrays** — `activation_steps_prepend` / `activation_steps_append` are always present in the override surface; call these out so the user sees they're available. + +For each candidate, confirm with the user: + +- Should this be exposed as an `[agent]` scalar? +- What name? Follow the conventions in `./standard-fields.md`: + - `_template` for template file paths + - `_output_path` for writable destinations + - `on_` for hook scalars +- What's the default value? + +User-added configurables are welcome — domain-specific knobs are fair game as long as they fit scalar or array merge rules. + +**Output:** a list of `{name, default, purpose}` tuples that Phase 5 will emit into `customize.toml` and reference from SKILL.md as `{agent.}`. + **If headless mode enabled, also gather:** - Default wake behavior (`--headless` | `-H` with no specific task) @@ -163,6 +210,32 @@ Load `./references/sample-capability-prompt.md` as a quality reference for capab Build the agent using templates from `./assets/` and rules from `./references/template-substitution-rules.md`. Output to `{bmad_builder_output_folder}`. +### Emit `customize.toml` (always, every archetype) + +Copy `./assets/customize-template.toml` into the built agent's root. Fill the `[agent]` metadata block from Phase 3: + +- `code`, `title`, `icon`, `description`, `agent_type` — always populated. +- `name` — populated for stateless agents and memory/autonomous agents whose name was fixed at build time; emit as an empty string for First-Breath-named agents. + +**If `{customizable}` is yes:** + +- Retain the override surface block (keep `{if-customizable}` content). +- Append any scalars lifted in Configurability Discovery (Phase 3), following the naming conventions (`*_template`, `*_output_path`, `on_`). +- In SKILL.md, reference those scalars as `{agent.}` rather than hardcoded values. Add the resolver activation step near the top of "On Activation": + + ```markdown + ### Step 1: Resolve the Agent Block + + Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key agent` + + If the script fails, resolve the `agent` block yourself by reading these three files in base → team → user order and applying structural merge rules: `{skill-root}/customize.toml`, `{project-root}/_bmad/custom/{skill-name}.toml`, `{project-root}/_bmad/custom/{skill-name}.user.toml`. Scalars override, tables deep-merge, arrays of tables keyed by `code`/`id` replace matching entries and append new ones, all other arrays append. + ``` + +- For stateless agents, execute `{agent.activation_steps_prepend}` before the rest of activation and `{agent.activation_steps_append}` after greet. Treat `{agent.persistent_facts}` as foundational context loaded on activation (`file:` prefix = path/glob; bare entries = literal facts). +- For memory/autonomous agents (if opted in): the override surface runs before the sanctum load. In practice this is rarely populated — sanctum remains the primary surface. + +**If `{customizable}` is no:** emit customize.toml with metadata only (the `{if-customizable}` block is stripped). SKILL.md has no resolver step and uses hardcoded paths throughout. + **Capability prompts are outcome-driven:** Each `./references/{capability}.md` file should describe what the capability achieves and what "good" looks like — not prescribe mechanical steps. The agent's persona context (identity, communication style, principles in SKILL.md) informs how each capability is executed. Don't repeat that context in every capability prompt. ### Stateless Agent Output diff --git a/skills/bmad-agent-builder/references/quality-analysis.md b/skills/bmad-agent-builder/references/quality-analysis.md index d807946..79d6fc6 100644 --- a/skills/bmad-agent-builder/references/quality-analysis.md +++ b/skills/bmad-agent-builder/references/quality-analysis.md @@ -56,9 +56,12 @@ Each scanner writes a free-form analysis document: | L5 | `quality-scan-enhancement-opportunities.md` | Edge cases, experience gaps, user journeys, headless potential | No | `enhancement-opportunities-analysis.md` | | L6 | `quality-scan-script-opportunities.md` | Deterministic operations that should be scripts | No | `script-opportunities-analysis.md` | | L7 | `quality-scan-sanctum-architecture.md` | Sanctum architecture (memory agents only) | Yes | `sanctum-architecture-analysis.md` | +| L8 | `quality-scan-customization-surface.md` | Customization opportunities and abuse; metadata validity | No | `customization-surface-analysis.md` | **L7 only runs for memory agents.** The prepass (P4) detects whether the agent is a memory agent. If the prepass reports `is_memory_agent: false`, skip L7 entirely. +**L8 runs for all archetypes.** The scanner internally branches on `agent_type` to apply different rigor (metadata validity always; override-surface opportunities for stateless; sanctum-conflict detection for memory/autonomous). + ## Execution First create output directory: `{bmad_builder_reports}/{skill-name}/quality-analysis/{date-time-stamp}/` diff --git a/skills/bmad-agent-builder/references/quality-dimensions.md b/skills/bmad-agent-builder/references/quality-dimensions.md index 3f72b02..8445a64 100644 --- a/skills/bmad-agent-builder/references/quality-dimensions.md +++ b/skills/bmad-agent-builder/references/quality-dimensions.md @@ -53,7 +53,19 @@ See `./references/standard-fields.md` for correct/incorrect patterns. Remove genuine waste (repetition, defensive padding, meta-explanation). Preserve context that enables judgment (persona voice, domain framing, theory of mind, design rationale). These are different things — never trade effectiveness for efficiency. A capability that works correctly but uses extra tokens is always better than one that's lean but fails edge cases. -## 8. Sanctum Architecture (memory agents only) +## 8. Customization Surface + +Every agent ships `customize.toml` (metadata block is the install-time roster contract). The override surface beyond metadata is opt-in and archetype-sensitive. + +- **Metadata validity (all archetypes):** `[agent]` must include `code`, `title`, `icon`, `description`, `agent_type`. `name` is required for stateless agents and optional (empty string valid) for First-Breath-named memory/autonomous agents. SKILL.md must agree with customize.toml on identity fields. +- **Stateless opportunity test:** Does the agent load templates, write to paths, or have lifecycle points users will reasonably want to vary? Lift those to named scalars (`*_template`, `*_output_path`, `on_`). +- **Stateless abuse test:** Boolean toggles, opaque scalar names (`style_config`), more than two hooks, or arrays-of-tables without `code`/`id` keys are usually design smells. +- **Memory/autonomous rule:** The sanctum is the primary customization surface. An override surface that duplicates PERSONA/CREED/BOND concepts (`identity`, `communication_style`, `principles`) is abuse. Default to metadata-only; opt in to the override surface only for narrow org-level needs (e.g. pre-sanctum compliance gate). +- **Autonomous rule:** PULSE.md owns autonomous behavior. Do not put PULSE-shaped fields in customize.toml. + +See [Customization for Authors](/explanation/customization-for-authors) for the decision framework. + +## 9. Sanctum Architecture (memory agents only) Memory agents have additional quality dimensions beyond the general seven: diff --git a/skills/bmad-agent-builder/references/quality-scan-customization-surface.md b/skills/bmad-agent-builder/references/quality-scan-customization-surface.md new file mode 100644 index 0000000..20a5a1a --- /dev/null +++ b/skills/bmad-agent-builder/references/quality-scan-customization-surface.md @@ -0,0 +1,190 @@ +# Quality Scan: Customization Surface + +You are **Artisan**, a customization-surface reviewer who pressure-tests an agent's `customize.toml` and the SKILL.md that consumes it. Agents always ship a `[agent]` metadata block (the install-time roster contract). The override surface beyond metadata is opt-in. Your scan covers both halves. + +You ask two paired questions that no other scanner asks: + +1. **What should be customizable but isn't?** (opportunities) +2. **What's exposed as customizable that shouldn't be?** (abuse) + +## Overview + +End-user customization is a contract with every future user: these are the fields the author supports overriding, across every release. A too-thin surface forces forks for changes that should have been a three-line TOML edit. A too-loud surface locks the author into promises they can't keep. For memory and autonomous agents, a too-loud surface also competes with the sanctum, which is already the primary customization vehicle. + +Your job is to find the sweet spot the author missed, in either direction, and to flag archetype-inappropriate override surfaces for memory and autonomous agents specifically. + +**This is purely advisory.** Nothing here is broken. Everything is either an opportunity to expose or a risk to trim. + +Load `/Users/brianmadison/bmad-code/bmad-bmb/custom-support/docs/explanation/customization-for-authors.md` if it's accessible for the decision framework; otherwise apply the principles below directly. + +## Your Role + +You are NOT checking structural completeness (structure), agent cohesion (agent-cohesion), sanctum architecture (sanctum-architecture), prose craft (prompt-craft), efficiency (execution-efficiency), or UX delight (enhancement-opportunities). You are the customization-surface economist. + +## Scan Targets + +Find and read: + +- `customize.toml` — If absent, treat as a critical finding (every agent should ship one for roster metadata). If present, analyze both metadata block and override surface. +- `SKILL.md` — Verify metadata-driven fields (displayName, title) match customize.toml; look for `{agent.X}` references; check for resolver activation steps. +- `references/*.md` — Capability prompts that may reference configurable values. +- Sanctum template assets (`assets/PERSONA-template.md`, `CREED-template.md`, `BOND-template.md`, `CAPABILITIES-template.md`) for memory/autonomous agents — the sanctum IS the customization surface; scan for conflicts with `customize.toml` overrides. + +## Agent Archetype Matters + +Apply different rigor per archetype: + +| Archetype | Metadata block | Override surface default | Scan emphasis | +| --- | --- | --- | --- | +| **Stateless** | Required | Opt-in | Both halves. Opportunities for lifting hardcoded paths and adding hooks; abuse for toggle farms and persona leakage. | +| **Memory** | Required | Opt-in (default: no) | Metadata validity + any present override surface must be justified. Sanctum-conflict detection is the top priority. | +| **Autonomous** | Required | Opt-in (default: no) | Same as memory, plus PULSE.md should be the autonomous-behavior surface, not customize.toml hooks. | + +## Opportunity Lenses + +Things the agent does that would benefit from being customizable. + +### 1. Missing or Invalid `[agent]` Metadata Block + +Every agent must ship `[agent]` with `code`, `title`, `icon`, `description`, `agent_type`, and `name` (empty string is valid for First-Breath-named agents). + +| Finding | Severity | +| --- | --- | +| No `customize.toml` at all | `high-opportunity`. The agent will not be picked up by `module.yaml:agents[]` or the central roster. Critical for module integration. | +| Missing required metadata field | `high-opportunity`. Specify exactly which field is missing. | +| `agent_type` value other than `stateless`, `memory`, or `autonomous` | `high-opportunity`. Scanners and installers branch on this value. | +| Metadata in customize.toml disagrees with SKILL.md (icon mismatch, title mismatch) | `high-opportunity`. Source-of-truth drift. The roster will show one thing, the agent will greet as another. | + +### 2. Hardcoded Reference Document Paths (Stateless Agents) + +Scan SKILL.md and capability prompts for hardcoded paths to reference material the agent loads. + +| Pattern | Opportunity | +| --- | --- | +| Capability prompt loads `references/style-guide.md` hardcoded | Lift to `[agent] style_guide_template = "references/style-guide.md"`. Orgs can point at their own style guide. | +| Agent always reads a specific output folder | Lift to `output_path` scalar if the path is realistically org-dependent. | + +### 3. Missing `persistent_facts` Default Glob + +BMad's convention is every customizable agent ships `persistent_facts = ["file:{project-root}/**/project-context.md"]` as the default, so orgs with a project-context file get auto-loaded context. + +| Current state | Opportunity | +| --- | --- | +| `persistent_facts = []` or absent | `medium-opportunity`. Add the default glob. | +| Only author-specific entries present | Low. Consider adding the project-context glob alongside. | + +### 4. Missing Hook Points (Stateless Agents) + +If the agent has natural pre/post-activation needs that users might want to inject, consider `activation_steps_prepend` or `activation_steps_append`. + +| Signal | Opportunity | +| --- | --- | +| Agent has no override surface at all but would benefit from pre-flight loads | `medium-opportunity`. Opt in to the override surface. | +| Agent activation includes a scan that some tables won't need | `medium-opportunity`. Move to `activation_steps_prepend` so only tables that want it enable it. | + +### 5. Memory/Autonomous: Override Surface Opt-In Without Justification + +For memory and autonomous agents, the default is no override surface (sanctum owns behavior). + +| Current state | Opportunity | +| --- | --- | +| Memory agent has override surface, no clear reason why | `medium-opportunity`. Question whether it should be metadata-only. Look for: is there a real org-level need (compliance preload, pre-sanctum gate) that sanctum can't express? If not, trim to metadata-only. | +| Override surface on a memory agent with fields the sanctum already covers (e.g. persona-shaped knobs) | See abuse lens 4 — flag as abuse, not opportunity. | + +### 6. Not Opted In to Override Surface Despite Obvious Variance (Stateless) + +For stateless agents without an override surface, assess whether opting in would help. + +| Signal | Recommendation | +| --- | --- | +| Stateless agent loads 2+ hardcoded templates | `high-opportunity`. Opt in. | +| Stateless agent has clear org-varying concerns (terminology, tone, output targets) | `medium-opportunity`. Consider opting in. | +| Stateless agent is a pure utility (one capability, no templates, no variance) | Leave as-is. Metadata-only is correct. | + +## Abuse Lenses + +Things present in `[agent]` that shouldn't be. + +### 1. Metadata Drift + +| Pattern | Risk | +| --- | --- | +| `customize.toml` `[agent] name = "Alice"` but SKILL.md hardcodes "Bob" in the displayName | `high-abuse`. Source-of-truth conflict. Rename one side to match. | +| `name` is populated for a memory/autonomous agent that uses First Breath naming | `medium-abuse`. The name should be learned at First Breath. Suggest setting `name = ""`. | + +### 2. Boolean Toggle Farms + +| Pattern | Risk | +| --- | --- | +| `include_examples = true` | `high-abuse`. A boolean scalar usually means the author didn't decide what the agent does. Pick a default, cut the toggle. | +| Three or more booleans in one customize.toml | `high-abuse`. The customization surface is doing the job of a variant skill. | + +### 3. Arrays of Tables Without `code`/`id` + +| Pattern | Risk | +| --- | --- | +| `[[agent.menu]]` items missing `code` | `high-abuse`. Resolver can't merge by key; users can't replace menu items, only append. | +| Mixed keying (`code` on some items, `id` on others) | `high-abuse`. Pick one. | + +### 4. Memory/Autonomous: Override Surface Conflicts With Sanctum + +The sanctum (PERSONA, CREED, BOND, CAPABILITIES) is the primary customization surface for these archetypes. Fields in `customize.toml` that duplicate sanctum concepts create two competing surfaces. + +| Pattern | Risk | +| --- | --- | +| `[agent].identity` or `[agent].communication_style` on a memory agent | `high-abuse`. PERSONA.md owns identity and style. Remove. | +| `[agent].principles` or `[agent].philosophy` on a memory agent | `high-abuse`. CREED.md owns principles. Remove. | +| `[agent].menu` on a memory agent | `medium-abuse`. CAPABILITIES.md owns capabilities. Unless there's a specific reason (evolvable capabilities registry), remove. | +| Override surface on a memory agent with only metadata justification (no concrete org-level hook need) | `medium-abuse`. Suggest trimming to metadata-only. | + +### 5. Autonomous: PULSE Behavior in customize.toml + +| Pattern | Risk | +| --- | --- | +| `[agent]` scalars named `pulse_interval`, `headless_task`, or similar | `high-abuse`. PULSE.md is the autonomous-behavior surface. customize.toml should stay metadata + minimal hooks. | + +### 6. Identity Fields That Pretend to Be Configurable + +| Pattern | Risk | +| --- | --- | +| `[agent] name` and `title` declared without a comment noting they're read-only at runtime | `low-abuse`. Add a comment so users don't try to override them via `_bmad/custom/` and get confused when nothing changes. | + +### 7. Hook Proliferation + +| Pattern | Risk | +| --- | --- | +| Four or more `on_` hooks on an agent | `medium-abuse`. Too much of the agent's internal structure is exposed. Users can break the agent's contract by interleaving hooks. Consolidate. | + +### 8. Over-Named Scalars + +| Pattern | Risk | +| --- | --- | +| Scalar named `style_config` or `format_options` | `low-abuse`. Opaque. Rename using the `*_template` / `*_output_path` / `on_` conventions. | + +### 9. Duplication Between customize.toml and SKILL.md + +| Pattern | Risk | +| --- | --- | +| `customize.toml` declares `style_guide_template` AND SKILL.md hardcodes the same path | `high-abuse`. Wiring missed. SKILL.md should reference `{agent.style_guide_template}`. Users' overrides will silently have no effect. | + +### 10. Declared Knobs With No Documented Purpose + +| Pattern | Risk | +| --- | --- | +| Scalar present with no comment explaining what it does | `low-abuse`. Add a one-line comment above each scalar describing when and why to override. | + +## Output + +Write your analysis as a natural document. Include: + +- **Agent archetype** — stateless, memory, or autonomous. This frames everything that follows. +- **Customization posture** — Is the metadata block complete? Is there an override surface, and if so how large? +- **Metadata findings** — Any drift, missing fields, or source-of-truth conflicts between customize.toml and SKILL.md. +- **Opportunity findings** — Each with severity (`high-opportunity`, `medium-opportunity`, `low-opportunity`), the location/pattern, and a concrete suggestion (proposed scalar name, default value, shape). +- **Abuse findings** — Each with severity (`high-abuse`, `medium-abuse`, `low-abuse`), the offending field or pattern, and a concrete suggestion (rename, remove, document, rewire, defer to sanctum). +- **Archetype-fit assessment** — Does the customization surface match the archetype? A memory agent with heavy override surface is a yellow flag; a stateless agent with only metadata and 5 hardcoded templates is another. +- **Top insights** — The 2-3 most impactful observations, distilled. + +Write your analysis to: `{quality-report-dir}/customization-surface-analysis.md` + +Return only the filename when complete. diff --git a/skills/bmad-agent-builder/references/report-quality-scan-creator.md b/skills/bmad-agent-builder/references/report-quality-scan-creator.md index 6f8e8e2..be0d24c 100644 --- a/skills/bmad-agent-builder/references/report-quality-scan-creator.md +++ b/skills/bmad-agent-builder/references/report-quality-scan-creator.md @@ -138,6 +138,10 @@ Order by impact — "how many findings does fixing this resolve?" The fix that c ### Sanctum Architecture {Only include this section if sanctum-architecture-analysis.md exists in the report directory} +### Customization Surface + +{Assessment of metadata validity, customization posture, opportunities, and abuse patterns. For stateless agents, focus on lifting hardcoded paths and flagging toggle farms. For memory/autonomous agents, flag any override surface that duplicates sanctum concepts (identity, principles, menu) and confirm the sanctum remains the primary customization vehicle.} + ## Recommendations 1. {Highest impact} diff --git a/skills/bmad-agent-builder/references/standard-fields.md b/skills/bmad-agent-builder/references/standard-fields.md index ca500cd..ebd0ab2 100644 --- a/skills/bmad-agent-builder/references/standard-fields.md +++ b/skills/bmad-agent-builder/references/standard-fields.md @@ -48,6 +48,72 @@ These are content blocks the builder fills during Phase 5 Build. They are NOT te | `communication-style-seed` | PERSONA-template.md | Initial personality expression seed | | `vibe-prompt` | PERSONA-template.md | Prompt for vibe discovery during First Breath | +## Customization Surface (`customize.toml`) + +Every agent ships a `customize.toml` alongside SKILL.md. The file has two parts: a metadata block that is always emitted, and an override surface that is emitted only when the author opted in during build. + +### Metadata block (always present) + +Consumed by the installer to populate `module.yaml:agents[]` and the central config's `[agents.]` section. Required for every agent regardless of archetype. + +| Field | Type | Required | Notes | +| ------------- | ------ | -------- | --------------------------------------------------------------------- | +| `code` | string | yes | Stable identifier. Matches skill directory basename (no module prefix). | +| `name` | string | optional | Display name. Empty string is valid for First-Breath-named agents. | +| `title` | string | yes | Role title. Always fillable at build time. | +| `icon` | string | yes | Single emoji. | +| `description` | string | yes | One-sentence summary of what the agent does. | +| `agent_type` | string | yes | One of `stateless`, `memory`, `autonomous`. | + +**First-Breath-named agents:** leave `name = ""` at build time. The owner fills it post-activation by adding `[agents.] name = "..."` to `{project-root}/_bmad/custom/config.toml`. UIs tolerate empty `name` and fall back to `title`. + +### Override surface (emitted only when opted in) + +Loaded via `_bmad/scripts/resolve_customization.py` at activation. Skip entirely for agents that did not opt in to customization. + +| Field | Type | Purpose | +| -------------------------- | ------------- | -------------------------------------------------------------- | +| `activation_steps_prepend` | array[string] | Steps run before standard activation. Overrides append. | +| `activation_steps_append` | array[string] | Steps run after greet, before user input. Overrides append. | +| `persistent_facts` | array[string] | Facts (literal or `file:` prefixed). Overrides append. | + +### Agent-specific scalars (lifted during Configurability Discovery) + +Named by purpose and suffix. Override wins (scalar merge rule). + +| Naming pattern | Use for | Example | +| ----------------------- | --------------------------------------------- | ------------------------------------------------ | +| `_template` | File paths for templates the agent loads | `style_guide_template = "resources/style.md"` | +| `_output_path` | Writable destinations | `report_output_path = "{project-root}/reports"` | +| `on_` | Prompt or command executed at a hook point | `on_session_close = ""` | + +**Path resolution within scalar values:** + +- Bare paths (e.g. `resources/style.md`) resolve from the skill root. +- `{project-root}/...` resolves from the project working directory — use for org-owned overrides. +- Config variables are used directly (they already contain `{project-root}`) — no double-prefix. + +### How SKILL.md references the resolved values + +After the resolver step runs, read customized values as `{agent.}`: + +```markdown +Load the style guide from `{agent.style_guide_template}`. +``` + +### Override files + +Teams and users override without editing `customize.toml`: + +- Team: `{project-root}/_bmad/custom/{skill-name}.toml` +- Personal: `{project-root}/_bmad/custom/{skill-name}.user.toml` + +Both use the same `[agent]` block shape. Merge order: base (skill's `customize.toml`) → team → user. + +### Memory / autonomous agents — prefer sanctum over this surface + +For memory and autonomous agents, the sanctum (PERSONA.md, CREED.md, BOND.md, CAPABILITIES.md) is the primary behavior-customization surface. It's calibrated at First Breath and evolves over time through owner edits and teaching. The `[agent]` override surface is usually empty for these archetypes — opt in only when there is a specific need (e.g. org-mandated pre-sanctum-load compliance step) that the sanctum cannot express. + ## Overview Section Format The Overview is the first section after the title — it primes the AI for everything that follows. diff --git a/skills/bmad-agent-builder/references/template-substitution-rules.md b/skills/bmad-agent-builder/references/template-substitution-rules.md index a1999ff..6aad772 100644 --- a/skills/bmad-agent-builder/references/template-substitution-rules.md +++ b/skills/bmad-agent-builder/references/template-substitution-rules.md @@ -53,6 +53,24 @@ The builder selects the appropriate SKILL.md template based on agent type: - **Stateless agent:** Use `./assets/SKILL-template.md` (full identity, no Three Laws/Sacred Truth) - **Memory/autonomous agent:** Use `./assets/SKILL-template-bootloader.md` (lean bootloader with Three Laws, Sacred Truth, 3-path activation) +## Customize.toml Emission + +Every agent ships `customize.toml` alongside SKILL.md. The template is `./assets/customize-template.toml`. Fill the `[agent]` metadata block from Phase 3's metadata gathering: + +- `{agent-code}` → stable identifier (skill dir basename without module prefix) +- `{agent-name-or-empty}` → display name, or empty string for First-Breath-named agents +- `{agent-title}` → role title +- `{agent-icon}` → single emoji +- `{agent-description}` → one-sentence description +- `{agent-type}` → `stateless` | `memory` | `autonomous` + +### Customization Opt-In Conditional + +- `{if-customizable}` ... `{/if-customizable}` → Keep the content inside when the author opted in to the override surface; add the resolver step to SKILL.md; reference lifted scalars as `{agent.}` in SKILL.md body. +- When not opted in → Remove the entire block including markers; `customize.toml` ships with metadata only; SKILL.md has no resolver step and uses hardcoded paths. + +Lifted configurable scalars are referenced in SKILL.md as `{agent.}` (e.g. `{agent.style_guide_template}`). These are resolved at runtime by the resolver, not at build time — emit them verbatim. + ## Beyond the Template The builder determines the rest of the agent structure — capabilities, activation flow, sanctum templates, init script, First Breath, capability routing, external skills, scripts — based on the agent's requirements. The template intentionally does not prescribe these. diff --git a/skills/bmad-module-builder/references/create-module.md b/skills/bmad-module-builder/references/create-module.md index c9ed2e6..b9ec040 100644 --- a/skills/bmad-module-builder/references/create-module.md +++ b/skills/bmad-module-builder/references/create-module.md @@ -21,6 +21,13 @@ For each skill, understand: - What it produces and where - Dependencies on other skills or external tools +**Also read `customize.toml` if present.** Skills built by the agent-builder ship a `customize.toml` alongside SKILL.md with an `[agent]` metadata block — `code`, `name`, `title`, `icon`, `description`, `agent_type`. Skills built by the workflow-builder may ship a `customize.toml` with a `[workflow]` block when the author opted in to end-user customization. Capture: + +- **Agent metadata:** the full `[agent]` block from each agent skill — this will populate `module.yaml:agents[]` in step 3.5. +- **Workflow customization:** presence/absence of `[workflow]` is informational only; workflows don't contribute to the module's agent roster. + +Skills without a `customize.toml` are fine — older skills or ones that predate customization support. Their metadata comes from the SKILL.md body (title heading, description frontmatter) as a fallback. + **Single skill detection:** If the folder contains exactly one skill (one directory with a SKILL.md), or the user provided a direct path to a single skill, note this as a **standalone module candidate**. ### 1.5. Confirm Approach @@ -84,6 +91,30 @@ Ask the user about: - `outputs`: describe file patterns bmad-help should look for to detect completion (e.g., "quality report", "converted skill") - `menu-code`: unique 1-3 letter shortcodes displayed as `[CODE] Display Name` in help +### 3.5. Populate the Agent Roster + +If any skills in the folder are agents (identified by a `customize.toml` with an `[agent]` block, or by the `agent-` prefix in their skill name), add them to `module.yaml` under an `agents:` key. Each entry carries the five install-time roster fields read from the agent's `[agent]` block: + +```yaml +agents: + - code: analyst + name: Mary + title: Business Analyst + icon: 📊 + description: Strategic business analyst and requirements expert. + - code: creative-muse + name: "" # learned at First Breath — owner fills post-activation + title: Creative Muse + icon: ✨ + description: Creative companion and muse. +``` + +**First-Breath-named agents:** if an agent's `[agent]` block has `name = ""`, carry the empty string through to `module.yaml` verbatim. The installer tolerates it, and roster-consuming UIs fall back to `title` until the owner fills the name by adding `[agents.] name = "..."` to `{project-root}/_bmad/custom/config.toml` after their first activation. + +**Skills without `customize.toml`:** if an agent skill predates the customization surface and has no `customize.toml`, reconstruct the metadata from SKILL.md: `code` from the skill directory basename (stripped of module prefix), `title` from the first `#` heading, `description` from frontmatter `description`, `name` and `icon` from the user (ask if not obvious from the SKILL.md body). + +**Confirm with the user before writing** — show the proposed `agents:` block alongside the other module.yaml content in step 6. + ### 4. Define Configuration Variables Does the module need custom installation questions? For each custom variable: diff --git a/skills/bmad-module-builder/references/validate-module.md b/skills/bmad-module-builder/references/validate-module.md index e3ccc6b..398eac2 100644 --- a/skills/bmad-module-builder/references/validate-module.md +++ b/skills/bmad-module-builder/references/validate-module.md @@ -46,6 +46,15 @@ This is where LLM judgment matters. For 4 or fewer skills, read all SKILL.md fil **Menu codes** — Are they intuitive? Do they relate to the display name in a way users can remember? +**Agent roster (if module.yaml has an `agents:` block)** — Verify each entry has: + +- `code` matching a skill directory basename in the module folder +- `title`, `icon`, `description` non-empty +- `name` either populated or explicitly empty string (empty is valid for First-Breath-named agents whose name is filled post-activation via `_bmad/custom/config.toml`) +- A corresponding `customize.toml` in the agent's skill directory with an `[agent]` block whose fields agree with the roster entry + +Flag drift: if the roster says `icon: 🎨` but the agent's own `customize.toml` says `icon: "📊"`, the roster is stale and needs to be regenerated from the agents' customize.toml files. + ### 4. Present Results Combine script findings and quality assessment into a clear report: diff --git a/skills/bmad-workflow-builder/assets/SKILL-template.md b/skills/bmad-workflow-builder/assets/SKILL-template.md index 77665b1..532f203 100644 --- a/skills/bmad-workflow-builder/assets/SKILL-template.md +++ b/skills/bmad-workflow-builder/assets/SKILL-template.md @@ -11,11 +11,36 @@ description: { skill-description } # [5-8 word summary]. [trigger phrases, e.g. ## On Activation +{if-customizable} +### Step 1: Resolve the Workflow Block + +Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow` + +If the script fails, resolve the `workflow` block yourself by reading these three files in base → team → user order and applying structural merge rules: `{skill-root}/customize.toml`, `{project-root}/_bmad/custom/{skill-name}.toml`, `{project-root}/_bmad/custom/{skill-name}.user.toml`. Scalars override, tables deep-merge, arrays of tables keyed by `code`/`id` replace matching entries and append new ones, all other arrays append. + +### Step 2: Execute Prepend Steps + +Execute each entry in `{workflow.activation_steps_prepend}` in order before proceeding. + +### Step 3: Load Persistent Facts + +Treat every entry in `{workflow.persistent_facts}` as foundational context for the whole run. Entries prefixed `file:` are paths or globs — load the referenced contents as facts. All other entries are facts verbatim. + +### Step 4: Load Config + +{/if-customizable} {if-module} Load available config from `{project-root}/_bmad/config.yaml` and `{project-root}/_bmad/config.user.yaml` (root level and `{module-code}` section). If config is missing, let the user know `{module-setup-skill}` can configure the module at any time. Use sensible defaults for anything not configured — prefer inferring at runtime or asking the user over requiring configuration. {/if-module} {if-standalone} Load available config from `{project-root}/_bmad/config.yaml` and `{project-root}/_bmad/config.user.yaml` if present. Use sensible defaults for anything not configured. {/if-standalone} +{if-customizable} + +### Step 5: Execute Append Steps + +Execute each entry in `{workflow.activation_steps_append}` in order before entering the workflow's first stage. + +{/if-customizable} {The rest of the skill — body structure, sections, phases, stages, scripts, external skills — is determined entirely by what the skill needs. The builder crafts this based on the discovery and requirements phases.} diff --git a/skills/bmad-workflow-builder/assets/customize-template.toml b/skills/bmad-workflow-builder/assets/customize-template.toml new file mode 100644 index 0000000..221135f --- /dev/null +++ b/skills/bmad-workflow-builder/assets/customize-template.toml @@ -0,0 +1,56 @@ +# DO NOT EDIT -- overwritten on every update. +# +# Workflow customization surface for {skill-name}. +# Team overrides: {project-root}/_bmad/custom/{skill-name}.toml +# Personal overrides: {project-root}/_bmad/custom/{skill-name}.user.toml + +[workflow] + +# --- Configurable below. Overrides merge per BMad structural rules: --- +# scalars: override wins • arrays (persistent_facts, activation_steps_*): append +# arrays-of-tables with `code`/`id`: replace matching items, append new ones. + +# Steps to run before the standard activation (config load, greet). +# Overrides append. Use for pre-flight loads, compliance checks, etc. + +activation_steps_prepend = [] + +# Steps to run after greet but before Stage 1 of the workflow. +# Overrides append. Use for context-heavy setup that should happen +# once the user has been acknowledged. + +activation_steps_append = [] + +# Persistent facts the workflow keeps in mind for the whole run +# (standards, compliance constraints, stylistic guardrails). +# Distinct from the runtime memory sidecar -- these are static context +# loaded on activation. Overrides append. +# +# Each entry is either: +# - a literal sentence, e.g. "All briefs must include a regulatory-risk section." +# - a file reference prefixed with `file:`, e.g. "file:{project-root}/docs/standards.md" +# (glob patterns are supported; the file's contents are loaded and treated as facts). + +persistent_facts = [ + "file:{project-root}/**/project-context.md", +] + +# Scalar: executed when the workflow reaches its terminal stage, after +# the main output has been delivered. Override wins. Leave empty for +# no custom post-completion behavior. + +on_complete = "" + +# --- Workflow-specific configurables (lifted during Configurability Discovery) --- +# +# Templates, output paths, and hooks the builder surfaced with the author. +# Bare paths resolve from the skill root; use `{project-root}/...` to point +# at an org-owned resource elsewhere in the repo. Override wins. +# +# Naming conventions: +# *_template -- file paths for templates the workflow loads +# *_output_path -- writable destinations +# on_ -- additional hook scalars beyond on_complete +# +# Example (from bmad-product-brief): +# brief_template = "resources/brief-template.md" diff --git a/skills/bmad-workflow-builder/assets/sample-customize-product-brief.toml b/skills/bmad-workflow-builder/assets/sample-customize-product-brief.toml new file mode 100644 index 0000000..f2a10f9 --- /dev/null +++ b/skills/bmad-workflow-builder/assets/sample-customize-product-brief.toml @@ -0,0 +1,51 @@ +# SAMPLE -- reference copy of bmad-product-brief's customize.toml (from bmm). +# Use as a worked example when lifting configurables during Configurability Discovery. +# This is NOT emitted into built skills; it's ground-truth reference for authors. + +# DO NOT EDIT -- overwritten on every update. +# +# Workflow customization surface for bmad-product-brief. Mirrors the +# agent customization shape under the [workflow] namespace. + +[workflow] + +# --- Configurable below. Overrides merge per BMad structural rules: --- +# scalars: override wins • arrays (persistent_facts, activation_steps_*): append +# arrays-of-tables with `code`/`id`: replace matching items, append new ones. + +# Steps to run before the standard activation (config load, greet). +# Overrides append. Use for pre-flight loads, compliance checks, etc. + +activation_steps_prepend = [] + +# Steps to run after greet but before Stage 1 of the workflow. +# Overrides append. Use for context-heavy setup that should happen +# once the user has been acknowledged. + +activation_steps_append = [] + +# Persistent facts the workflow keeps in mind for the whole run +# (standards, compliance constraints, stylistic guardrails). +# Distinct from the runtime memory sidecar -- these are static context +# loaded on activation. Overrides append. +# +# Each entry is either: +# - a literal sentence, e.g. "All briefs must include a regulatory-risk section." +# - a file reference prefixed with `file:`, e.g. "file:{project-root}/docs/standards.md" +# (glob patterns are supported; the file's contents are loaded and treated as facts). + +persistent_facts = [ + "file:{project-root}/**/project-context.md", +] + +# Path to the brief structure template used in Stage 4 drafting. +# Bare paths resolve from the skill root; use `{project-root}/...` to +# point at an org-owned template elsewhere in the repo. Override wins. + +brief_template = "resources/brief-template.md" + +# Scalar: executed when the workflow reaches its terminal stage, after +# the main output has been delivered. Override wins. Leave empty for +# no custom post-completion behavior. + +on_complete = "" diff --git a/skills/bmad-workflow-builder/references/build-process.md b/skills/bmad-workflow-builder/references/build-process.md index e082cd4..c7e6093 100644 --- a/skills/bmad-workflow-builder/references/build-process.md +++ b/skills/bmad-workflow-builder/references/build-process.md @@ -100,12 +100,47 @@ Work through conversationally, adapted per skill type. Glean from what the user **Module capability metadata (if part of a module):** Confirm with user: phase-name, after (dependencies), before (downstream), is-required, description (short — what it produces, not how). +**Customization opt-in (ask once, default no):** + +Ask: _"Should this workflow support end-user customization (activation hooks, swappable templates, output paths)? If no, it ships fixed — users who need changes fork it."_ + +- **No** → skip Phase 3.5 entirely. No `customize.toml` will be emitted. SKILL.md stays fixed-path. +- **Yes** → proceed to Phase 3.5 below after finishing Phase 3. + +In headless mode, default to **no** unless `--customizable` is passed. Record the answer as `{customizable}` for later phases. + **Path conventions (CRITICAL):** - Skill-internal: `references/`, `scripts/` (relative to skill root) - Project-scope paths: `{project-root}/...` (any path relative to project root) - Config variables used directly — they already contain `{project-root}` +## Phase 3.5: Configurability Discovery (only if `{customizable}` is yes) + +Identify what should be swappable without forking. Walk through the workflow's planned structure and surface candidates: + +**Auto-detect candidates to propose:** + +- **Template files** the workflow loads — each becomes a named scalar (strongest case). A workflow that drafts output from `resources/brief-template.md` should expose `brief_template` so an org can point it at their own template. +- **Output destination paths** if the workflow writes artifacts. +- **`on_complete` hooks** — prompt or command executed at the terminal stage. +- **Pre/post-flight step arrays** — `activation_steps_prepend` / `activation_steps_append` are always present in the override surface; call these out so the user sees they're available. + +**For each candidate, confirm with the user:** + +- Should this be exposed as a `[workflow]` scalar? +- What name? Follow the conventions in `./standard-fields.md`: + - `_template` for template file paths + - `_output_path` for writable destinations + - `on_` for hook scalars +- What's the default value? + +**User-added configurables:** explicitly ask if the user wants to expose anything the auto-detect missed. Domain-specific knobs (style guides, severity thresholds, section lists) are fair game — as long as they're scalars or arrays that fit the merge rules. + +**Headless behavior:** auto-promote every template reference and output path the workflow declares. Name them from the filename stem (`brief-template.md` → `brief_template`). The user can prune later. + +**Output:** a list of `{name, default, purpose}` tuples that Phase 5 will emit into `customize.toml` and reference from SKILL.md as `{workflow.}`. + ## Phase 4: Draft & Refine Think one level deeper. Clarify gaps in logic or understanding. Create and present a plan. Point out vague areas. Iterate until ready. @@ -135,6 +170,24 @@ Watch especially for: Load the template from `assets/SKILL-template.md` and `./template-substitution-rules.md`. Build the skill with progressive disclosure (SKILL.md for overview and routing, `references/` for progressive disclosure content). Output to `{bmad_builder_output_folder}`. +**If `{customizable}` is yes:** + +- Emit `customize.toml` alongside SKILL.md using `assets/customize-template.toml` as the base. Fill `[workflow]` with the scalars identified in Phase 3.5. +- In SKILL.md, replace hardcoded references to customizable values with `{workflow.}` indirection. A hardcoded `resources/brief-template.md` becomes `{workflow.brief_template}` if that scalar was lifted. +- Add the resolver activation step to SKILL.md before config load: + + ```markdown + ### Step 1: Resolve the Workflow Block + + Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow` + + If the script fails, resolve the `workflow` block yourself by reading these three files in base → team → user order and applying structural merge rules: `{skill-root}/customize.toml`, `{project-root}/_bmad/custom/{skill-name}.toml`, `{project-root}/_bmad/custom/{skill-name}.user.toml`. Scalars override, tables deep-merge, arrays of tables keyed by `code`/`id` replace matching entries and append new ones, all other arrays append. + ``` + +- Execute `{workflow.activation_steps_prepend}` before the workflow's first stage and `{workflow.activation_steps_append}` after greet but before Stage 1. Treat `{workflow.persistent_facts}` as foundational context loaded on activation (`file:` prefix = path/glob; bare entries = literal facts). + +**If `{customizable}` is no:** no `customize.toml`, no resolver step. SKILL.md uses hardcoded paths throughout. + **Skill Source Tree** (only create subfolders that are needed): ``` diff --git a/skills/bmad-workflow-builder/references/quality-analysis.md b/skills/bmad-workflow-builder/references/quality-analysis.md index bec7eaf..3964592 100644 --- a/skills/bmad-workflow-builder/references/quality-analysis.md +++ b/skills/bmad-workflow-builder/references/quality-analysis.md @@ -61,6 +61,7 @@ Each scanner writes a free-form analysis document (not JSON): | L4 | `quality-scan-skill-cohesion.md` | Stage flow, purpose alignment, complexity appropriateness | No | `skill-cohesion-analysis.md` | | L5 | `quality-scan-enhancement-opportunities.md` | Edge cases, UX gaps, user journeys, headless potential | No | `enhancement-opportunities-analysis.md` | | L6 | `quality-scan-script-opportunities.md` | Deterministic operations that should be scripts | No | `script-opportunities-analysis.md` | +| L7 | `quality-scan-customization-surface.md` | Opportunities to expose customization; abuse of the customization surface | No | `customization-surface-analysis.md` | ## Execution diff --git a/skills/bmad-workflow-builder/references/quality-dimensions.md b/skills/bmad-workflow-builder/references/quality-dimensions.md index d111f43..16da97d 100644 --- a/skills/bmad-workflow-builder/references/quality-dimensions.md +++ b/skills/bmad-workflow-builder/references/quality-dimensions.md @@ -48,6 +48,16 @@ Use `{project-root}` for any project-scope path. Use `./` only for same-folder r See `./standard-fields.md` for correct/incorrect patterns. -## 7. Token Efficiency +## 7. Customization Surface + +If the workflow opts in to end-user customization, the `[workflow]` override surface is a contract with every future user. Too thin forces forks for changes that should have been a three-line TOML edit. Too loud locks the author into permutation-forest usage patterns no one can reason about. + +- **Opportunity test:** Does the workflow load templates, write to paths, or have lifecycle points that real users will want to vary? Lift those to named scalars (`*_template`, `*_output_path`, `on_`). +- **Abuse test:** Does the surface include boolean toggles, identity fields, more than two `on_` hooks, or arrays-of-tables without `code`/`id` keys? These are usually design smells. +- **Default:** Customization is opt-in. A workflow without a `customize.toml` is fine; a workflow that ships one should earn every field. + +See [Customization for Authors](/explanation/customization-for-authors) for the decision framework. + +## 8. Token Efficiency Remove genuine waste (repetition, defensive padding, meta-explanation). Preserve context that enables judgment (domain framing, theory of mind, design rationale). These are different things — never trade effectiveness for efficiency. A skill that works correctly but uses extra tokens is always better than one that's lean but fails edge cases. diff --git a/skills/bmad-workflow-builder/references/quality-scan-customization-surface.md b/skills/bmad-workflow-builder/references/quality-scan-customization-surface.md new file mode 100644 index 0000000..c38510c --- /dev/null +++ b/skills/bmad-workflow-builder/references/quality-scan-customization-surface.md @@ -0,0 +1,168 @@ +# Quality Scan: Customization Surface + +You are **Artisan**, a customization-surface reviewer who pressure-tests a workflow's `customize.toml` (if present) and the SKILL.md that consumes it. You ask two paired questions that no other scanner asks: + +1. **What should be customizable but isn't?** (opportunities) +2. **What's exposed as customizable that shouldn't be?** (abuse) + +## Overview + +End-user customization is opt-in per skill. When it's present, the author has made a contract with every future user: these are the fields I support overriding, across every release. A too-thin surface forces forks for changes that should have been a three-line TOML edit. A too-loud surface locks the author into promises they can't keep and creates permutation-forest usage patterns no one can reason about. + +Your job is to find the sweet spot the author missed, in either direction. + +**This is purely advisory.** Nothing here is broken. Everything is either an opportunity to expose or a risk to trim. + +Load `/Users/brianmadison/bmad-code/bmad-bmb/custom-support/docs/explanation/customization-for-authors.md` if it's accessible for the decision framework; otherwise apply the principles below directly. + +## Your Role + +You are NOT checking structural completeness (workflow-integrity), prose craft (prompt-craft), efficiency (execution-efficiency), or UX delight (enhancement-opportunities). You are the customization-surface economist. + +## Scan Targets + +Find and read: + +- `customize.toml` — If present, it's the canonical customization schema for this workflow +- `SKILL.md` — Look for `{workflow.X}` references (indicates customize.toml is wired), hardcoded paths (candidates for lifting), resolver activation steps +- `assets/` — Templates the workflow loads; candidates for `*_template` scalars +- `references/*.md` — Stage/phase prompts that may reference configurable values + +**If no `customize.toml` exists:** the workflow is not opted in to customization. Your scan focuses entirely on opportunity-side findings: "here's what would benefit from opting in, and here's what to lift if you do." + +**If `customize.toml` exists:** scan both sides. Opportunities (things missing from the surface) and abuse (things present that shouldn't be). + +## Opportunity Lenses + +Things the workflow does that would benefit from being customizable. + +### 1. Hardcoded Template Paths + +Scan SKILL.md and reference prompts for string literals pointing at template files. + +| Pattern | Example | Opportunity | +| --- | --- | --- | +| Hardcoded template in SKILL.md | `Load resources/brief-template.md` | Lift to `[workflow] brief_template = "resources/brief-template.md"`. Teams can point it at an org-owned template. | +| Hardcoded template in a stage prompt | `assets/report-shape.md` inside Stage 3 | Same treatment. The consumer reads `{workflow.report_shape_template}` instead. | +| Multiple templates, one skill | Brief, summary, and handoff templates | Each is a separate scalar candidate. Don't bundle. | + +Flag each one as a `medium-opportunity` (single template) or `high-opportunity` (multiple templates the workflow loads). + +### 2. Hardcoded Output Destinations + +Any path the workflow writes to. + +| Pattern | Opportunity | +| --- | --- | +| `{project-root}/docs/briefs/` baked into a stage | Lift to `output_path` scalar. Different teams have different docs taxonomies. | +| A `{project-root}/reports/` destination used once | Judge: if the author intended "reports go here," fine as-is. If users will reasonably want it elsewhere, lift. | + +Output paths are weaker opportunities than templates. Users often accept the default destination. Flag `low-opportunity` unless the path is clearly org-dependent. + +### 3. Missing `on_` Hooks + +Post-completion behavior worth offering as a hook. + +| Signal | Opportunity | +| --- | --- | +| Workflow produces an artifact and then stops | Consider `on_complete = ""`. Some teams will want to draft a summary message, push to a system, or trigger a downstream skill. | +| Workflow has a natural checkpoint (end of stage) | Consider a named hook (`on_stage_review`, `on_approve`). Only if real tables would want it. | + +One hook scalar is usually enough. Multiple hooks per workflow is a yellow flag (see abuse lens 3). + +### 4. Missing `persistent_facts` Default Glob + +Workflows commonly benefit from a default glob that loads project context. + +| Current state | Opportunity | +| --- | --- | +| No `persistent_facts` in customize.toml | Add `["file:{project-root}/**/project-context.md"]` as the default. Users who have such a file get auto-loaded context. | +| `persistent_facts = []` | Same treatment. | +| Author-specific glob only (e.g. no project-context default) | Consider adding the project-context glob alongside. | + +This is a high-value, low-risk opportunity. BMad's convention is that every customizable workflow ships this default. + +### 5. Sentence-Shaped Variance Handled as Prompts + +Scan stage prompts for domain sentences baked into the workflow that users might reasonably want to change: tone guides, style constraints, compliance notes. + +| Pattern | Opportunity | +| --- | --- | +| A stage prompt includes `Tone: X` or `Style: Y` | This is sentence-shaped variance. Users shape it via `persistent_facts`, not a scalar. Suggest documenting in the customize.toml's persistent_facts comment. | +| Compliance rules baked into a prompt | Same. Move the rule out of the prompt, note that users can inject via `persistent_facts`. | + +These aren't scalar opportunities, but they're signals the skill's persistent_facts surface is valuable and the author should document it. + +### 6. Not Opted In Despite Obvious Variance + +If the workflow has no `customize.toml` at all, assess whether it should opt in. + +| Signal | Recommendation | +| --- | --- | +| Workflow loads 2+ templates with hardcoded paths | `high-opportunity`: opt in to customization. The templates alone justify the surface. | +| Workflow has clear org-varying concerns (output format, terminology, destination) | `medium-opportunity`: consider opting in. | +| Workflow is a pure utility (one input, one output, no templates) | Leave as-is. Customization adds no value. | + +## Abuse Lenses + +Things present in `customize.toml` that shouldn't be. + +### 1. Boolean Toggle Farms + +| Pattern | Risk | +| --- | --- | +| `include_summary_section = true` | High. A boolean scalar usually means the author didn't decide what the skill does. Suggest: pick a default, cut the toggle, let users fork if they want the other shape. | +| Three or more booleans in one customize.toml | Very high. The customization surface is doing the job of a variant skill. Suggest: consider whether two skills (or fewer knobs) would serve users better. | + +### 2. Identity Overrides in a Workflow + +| Pattern | Risk | +| --- | --- | +| `[workflow]` block contains `identity`, `communication_style`, or `principles` scalars | These are agent-shape fields and don't fit workflow semantics. Suggest: remove. Workflows don't have persona. | +| A workflow ships a full persona override surface | Suggest: this workflow wants to be an agent. Point the author at the agent-builder. | + +### 3. Hook Proliferation + +| Pattern | Risk | +| --- | --- | +| Four or more `on_` hooks | The skill has leaked too much of its internal structure into the override surface. Users can interleave hooks at so many points they can break the workflow's contract. Suggest: consolidate to one or two hooks, or redesign stages as named sub-skills users can swap. | + +### 4. Arrays of Tables Without `code`/`id` + +| Pattern | Risk | +| --- | --- | +| `[[workflow.reviewers]]` with `name` and `weight` but no `code` or `id` | Resolver can't merge by key; the array falls back to append-only. Users can't replace items, only add. Suggest: add a `code` field to every item. | +| Mixed keying (`code` on some, `id` on others) | Same. Pick one convention and stick to it. | + +### 5. Over-Named Scalars + +| Pattern | Risk | +| --- | --- | +| Scalar named `style_config` or `format_options_file` | Opaque. Users can't tell what changes when they override. Suggest: rename using the `*_template` / `*_output_path` / `on_` conventions. | +| Scalar whose name doesn't hint at its shape | Same. A scalar named `mode` that takes a file path is misleading. | + +### 6. Duplication Between customize.toml and SKILL.md + +| Pattern | Risk | +| --- | --- | +| `customize.toml` declares `brief_template = "..."` AND SKILL.md hardcodes `resources/brief-template.md` in the same slot | Wiring missed. SKILL.md should reference `{workflow.brief_template}`. Users' overrides will silently have no effect. Flag `high-abuse`. | + +### 7. Declared Knobs With No Documented Purpose + +| Pattern | Risk | +| --- | --- | +| Scalar present in customize.toml with no comment explaining what it does | Users have to read SKILL.md to figure out the knob. Suggest: add a one-line comment above each scalar describing when and why to override. | + +## Output + +Write your analysis as a natural document. Include: + +- **Customization posture** — Is the workflow opted in? If yes, how large is the surface (field count, shape)? +- **Opportunity findings** — Each with severity (`high-opportunity`, `medium-opportunity`, `low-opportunity`), the location/pattern in SKILL.md or references, and a concrete suggestion (proposed scalar name, default value, type). +- **Abuse findings** — Each with severity (`high-abuse`, `medium-abuse`, `low-abuse`), the offending field or pattern, and a concrete suggestion (rename, remove, document, rewire). +- **Overall assessment** — Does the customization surface match the workflow's actual variance profile? Too thin, too loud, or about right? +- **Top insights** — The 2-3 most impactful observations, distilled. + +Write your analysis to: `{quality-report-dir}/customization-surface-analysis.md` + +Return only the filename when complete. diff --git a/skills/bmad-workflow-builder/references/report-quality-scan-creator.md b/skills/bmad-workflow-builder/references/report-quality-scan-creator.md index 8a94284..23f60fa 100644 --- a/skills/bmad-workflow-builder/references/report-quality-scan-creator.md +++ b/skills/bmad-workflow-builder/references/report-quality-scan-creator.md @@ -121,6 +121,10 @@ A narrative markdown report. Structure: {Assessment + token savings estimates} +### Customization Surface + +{Assessment of customization posture (opted in or not), opportunities to expose, and abuse patterns to trim. Flag metadata drift, toggle farms, and archetype-inappropriate surfaces.} + ## Recommendations 1. {Highest impact — resolves N observations} diff --git a/skills/bmad-workflow-builder/references/standard-fields.md b/skills/bmad-workflow-builder/references/standard-fields.md index d03fd7d..79d5d79 100644 --- a/skills/bmad-workflow-builder/references/standard-fields.md +++ b/skills/bmad-workflow-builder/references/standard-fields.md @@ -45,6 +45,53 @@ These are used within the SKILL.md body — never in frontmatter: | `config-variables` | Beyond core vars | `planning_artifacts`, `output_folder` | | `output-artifacts` | What it creates (output-location) | "PRD document", "agent skill" | +## Customization Surface (`customize.toml`, opt-in) + +Emitted only when the skill author opts in during Phase 3.5 (Configurability Discovery). The file sits next to SKILL.md and is loaded via `_bmad/scripts/resolve_customization.py` at activation. + +### Always-present fields (when opted in) + +| Field | Type | Purpose | +| -------------------------- | ------------- | -------------------------------------------------------------------------- | +| `activation_steps_prepend` | array[string] | Steps run before standard activation. Overrides append. | +| `activation_steps_append` | array[string] | Steps run after greet, before the workflow's first stage. Overrides append. | +| `persistent_facts` | array[string] | Facts (literal or `file:` prefixed paths/globs) loaded on activation. Overrides append. | + +### Workflow-specific scalars (lifted during Phase 3.5) + +Named by purpose and suffix. Override wins (scalar merge rule). + +| Naming pattern | Use for | Example | +| ------------------- | ---------------------------------------------------- | --------------------------------------------------- | +| `_template` | File path for templates the workflow loads | `brief_template = "resources/brief-template.md"` | +| `_output_path` | Writable destination paths | `output_path = "{project-root}/docs/briefs"` | +| `on_` | Prompt or command executed at a hook point | `on_complete = ""` | + +**Path resolution within scalar values:** + +- Bare paths (e.g. `resources/brief-template.md`) resolve from the skill root. +- `{project-root}/...` resolves from the project working directory — use for org-owned overrides. +- Never mix `{project-root}` with config variables that already contain it (no double-prefix). + +### How SKILL.md references the resolved values + +After the resolver step runs, read customized values as `{workflow.}`: + +```markdown +Load the brief template from `{workflow.brief_template}`. +``` + +At runtime, that resolves to whatever the merged `[workflow].brief_template` scalar is — the default, a team override, or a personal override. + +### Override files + +Teams and users override without editing `customize.toml` in the skill, and instead modify the following: + +- Team: `{project-root}/_bmad/custom/{skill-name}.toml` +- Personal: `{project-root}/_bmad/custom/{skill-name}.user.toml` + +Both use the same `[workflow]` block shape. Merge order: base (skill's `customize.toml`) → team → user. + ## Overview Section Format The Overview is the first section after the title — it primes the AI for everything that follows. diff --git a/skills/bmad-workflow-builder/references/template-substitution-rules.md b/skills/bmad-workflow-builder/references/template-substitution-rules.md index b53cc8b..0235eed 100644 --- a/skills/bmad-workflow-builder/references/template-substitution-rules.md +++ b/skills/bmad-workflow-builder/references/template-substitution-rules.md @@ -22,6 +22,18 @@ The SKILL-template provides a minimal skeleton: frontmatter, overview, and activ - `{if-module}` ... `{/if-module}` → Remove the entire block including markers - `{if-standalone}` ... `{/if-standalone}` → Keep the content inside +## Customization Conditionals + +### When Customization Is Opted In + +- `{if-customizable}` ... `{/if-customizable}` → Keep the content inside; emit `customize.toml` alongside SKILL.md. +- Lifted configurable scalars are referenced in SKILL.md body as `{workflow.}` (e.g. `{workflow.brief_template}`). These are resolved at runtime by the resolver, not at build time — emit them verbatim. + +### When Customization Is Not Opted In + +- `{if-customizable}` ... `{/if-customizable}` → Remove the entire block including markers. +- Do NOT emit `customize.toml`. Use hardcoded paths and values in SKILL.md throughout. + ## Beyond the Template The builder determines the rest of the skill structure — body sections, phases, stages, scripts, external skills, headless mode, role guidance — based on the skill type classification and requirements gathered during the build process. The template intentionally does not prescribe these; the builder has the context to craft them. From 43a0891661cb7acb9a60608d0a2e6c5dd0f98138 Mon Sep 17 00:00:00 2001 From: Brian Madison Date: Mon, 20 Apr 2026 01:31:21 -0500 Subject: [PATCH 2/4] fix(docs,scanners): route conventions, style, and scanner self-containment Scanners: - Remove absolute-path `Load` directive from both quality-scan-customization-surface.md files. The hardcoded /Users/brianmadison/... path would never resolve in consumer environments. Scanners now rely solely on their embedded Opportunity and Abuse lens tables, matching the self-contained convention of every other quality-scan-*.md in the codebase. Docs route convention: - Append `.md` to 12 internal cross-links to match the site convention (/explanation/foo.md, /how-to/foo.md form). Touches make-a-skill-customizable.md (4), what-are-bmad-agents.md (1), what-are-workflows.md (2), skill-authoring-best-practices.md (2), module-configuration.md (1), agent-memory-and-personalization.md (1). Docs external host: - Swap 3 end-user-guide links from bmadcode.github.io/bmad to docs.bmad-method.org/how-to/customize-bmad/ to point at the correct published docs site for BMAD-METHOD. Docs style: - Rewrite how-to hook from "Use this guide when..." to "This guide walks through..." matching the convention used by distribute-your-module.md. - Remove first-person voice from the bmad-session-prep worked example in customization-for-authors.md. "Here's how I'd customize it" -> "Here's how to think about its customization surface"; "I'm not trying to catalog every RPG; I ship one default" -> "The skill isn't trying to catalog every RPG; it ships one default"; "### What I'd NOT expose" -> "### What Not to Expose". --- docs/explanation/agent-memory-and-personalization.md | 2 +- docs/explanation/customization-for-authors.md | 10 +++++----- docs/explanation/module-configuration.md | 2 +- docs/explanation/skill-authoring-best-practices.md | 2 +- docs/explanation/what-are-bmad-agents.md | 2 +- docs/explanation/what-are-workflows.md | 2 +- docs/how-to/make-a-skill-customizable.md | 8 ++++---- .../references/quality-scan-customization-surface.md | 2 -- .../references/quality-scan-customization-surface.md | 2 -- 9 files changed, 14 insertions(+), 18 deletions(-) diff --git a/docs/explanation/agent-memory-and-personalization.md b/docs/explanation/agent-memory-and-personalization.md index 21c07ec..eafcece 100644 --- a/docs/explanation/agent-memory-and-personalization.md +++ b/docs/explanation/agent-memory-and-personalization.md @@ -43,7 +43,7 @@ ALLCAPS files form the skeleton: consistent structure across all memory agents. ### Sanctum Is the Customization Surface -For memory and autonomous agents, the sanctum is where customization belongs. PERSONA, CREED, and BOND are calibrated at First Breath, edited by the owner as the relationship develops, and shared across teams as sanctum files when a whole table wants the same voice. The parallel `customize.toml` override surface that stateless agents and workflows use (activation hooks, persistent facts, scalar swaps) is opt-out by default for memory archetypes. Opt in only when you have a narrow org-level need the sanctum cannot express, such as a pre-sanctum compliance acknowledgment before rebirth. See [Customization for Authors](/explanation/customization-for-authors) for the reasoning. +For memory and autonomous agents, the sanctum is where customization belongs. PERSONA, CREED, and BOND are calibrated at First Breath, edited by the owner as the relationship develops, and shared across teams as sanctum files when a whole table wants the same voice. The parallel `customize.toml` override surface that stateless agents and workflows use (activation hooks, persistent facts, scalar swaps) is opt-out by default for memory archetypes. Opt in only when you have a narrow org-level need the sanctum cannot express, such as a pre-sanctum compliance acknowledgment before rebirth. See [Customization for Authors](/explanation/customization-for-authors.md) for the reasoning. ### Token Discipline diff --git a/docs/explanation/customization-for-authors.md b/docs/explanation/customization-for-authors.md index db8a365..d2a0ce1 100644 --- a/docs/explanation/customization-for-authors.md +++ b/docs/explanation/customization-for-authors.md @@ -3,7 +3,7 @@ title: 'Customization for Authors' description: How to decide whether your skill should support end-user customization, and what to expose when it does --- -Shipping a `customize.toml` is opt-in per skill. This is the author-side counterpart to [How to Customize BMad](https://bmadcode.github.io/bmad/how-to/customize-bmad), which covers the end-user view. Read that first if you haven't; it shows what users experience when they override a skill. This guide is about deciding whether to give them that surface at all. +Shipping a `customize.toml` is opt-in per skill. This is the author-side counterpart to [How to Customize BMad](https://docs.bmad-method.org/how-to/customize-bmad/), which covers the end-user view. Read that first if you haven't; it shows what users experience when they override a skill. This guide is about deciding whether to give them that surface at all. ## The Problem @@ -54,7 +54,7 @@ Opt in only when you have a specific org-level need the sanctum can't express. P A weekly session-prep workflow for tabletop RPG game masters. It reads the last session's log, reviews open campaign threads, drafts the scene spine, stats NPCs and encounters, and produces a GM notes document to run from. -Here's how I'd customize it, field by field. +Here's how to think about its customization surface, field by field. ### `persistent_facts` (default globs the campaign bible) @@ -73,7 +73,7 @@ Every GM runs a different world. Without their campaign bible in context, the wo system_rules_template = "resources/dnd-5e-quick-reference.md" ``` -D&D 5e, Pathfinder 2e, and Call of Cthulhu reason about encounters in very different ways. A PF2e GM who overrides this with their own rules reference gets correctly-calibrated encounter math without the workflow pretending to know a system it doesn't. I'm not trying to catalog every RPG; I ship one default that covers most users and let everyone else swap in their own reference. The `*_template` suffix signals what changes if you touch it. +D&D 5e, Pathfinder 2e, and Call of Cthulhu reason about encounters in very different ways. A PF2e GM who overrides this with their own rules reference gets correctly-calibrated encounter math without the workflow pretending to know a system it doesn't. The skill isn't trying to catalog every RPG; it ships one default that covers most users and lets everyone else swap in their own reference. The `*_template` suffix signals what changes if the user touches it. ### `session_notes_template` (scalar) @@ -107,9 +107,9 @@ activation_steps_prepend = [ Not every GM keeps session logs. The ones who do want the pre-load; the ones who don't would get a broken activation if it were baked in. Opt-in via the prepend hook lets both tables use the same skill. -### What I'd NOT expose +### What Not to Expose -The stage sequence (recap, threads, spine, NPCs, notes) is the skill's identity. A GM who wants a very different flow (solo journaling, West Marches gossip round) should fork. Every stage I make optional erodes what the skill is. +The stage sequence (recap, threads, spine, NPCs, notes) is the skill's identity. A GM who wants a very different flow (solo journaling, West Marches gossip round) should fork. Every stage made optional erodes what the skill is. Mechanical encounter math toggles like `auto_balance_cr` or `verbose_stat_blocks` stay out. The LLM handles those naturally once it has the system reference. Toggles here would amount to telling the executor how to do its job. diff --git a/docs/explanation/module-configuration.md b/docs/explanation/module-configuration.md index 55a6b7e..27ddc12 100644 --- a/docs/explanation/module-configuration.md +++ b/docs/explanation/module-configuration.md @@ -25,7 +25,7 @@ If you are building a single standalone agent or workflow, you do not need a sep Module configuration (this doc) and per-skill customization (`customize.toml`) are different surfaces with different jobs. Configuration is about install-time answers: paths, language, team preferences, per-module install answers. It lives in `_bmad/config.toml` and `config.user.toml` at the project root and is consumed by many skills. Customization is about per-skill behavior overrides: activation hooks, persistent facts, swappable templates. It lives in `_bmad/custom/{skill-name}.toml` and is scoped to one skill. -Use configuration when the value is cross-cutting (every skill needs to know the output folder). Use customization when the value shapes one skill's behavior (this workflow's brief template). Some values legitimately fit both surfaces; the [End-User Customization Guide](https://bmadcode.github.io/bmad/how-to/customize-bmad) includes a decision table for that case. For the author-side decision about whether to expose customization at all, see [Customization for Authors](/explanation/customization-for-authors). +Use configuration when the value is cross-cutting (every skill needs to know the output folder). Use customization when the value shapes one skill's behavior (this workflow's brief template). Some values legitimately fit both surfaces; the [End-User Customization Guide](https://docs.bmad-method.org/how-to/customize-bmad/) includes a decision table for that case. For the author-side decision about whether to expose customization at all, see [Customization for Authors](/explanation/customization-for-authors.md). ## What Module Registration Does diff --git a/docs/explanation/skill-authoring-best-practices.md b/docs/explanation/skill-authoring-best-practices.md index 34fd856..c5bd520 100644 --- a/docs/explanation/skill-authoring-best-practices.md +++ b/docs/explanation/skill-authoring-best-practices.md @@ -38,7 +38,7 @@ Six dimensions to keep in mind during the build phase. The quality scanners chec ## Shipping a Customization Surface -When your skill's users come from varied contexts (different orgs, different domains, different taste in output formats), a `customize.toml` surface lets them override specific fields without forking. It's opt-in per skill, and the decision is deliberate: every knob you ship is a promise the resolver will carry across releases. Before you opt in during the build, read [Customization for Authors](/explanation/customization-for-authors) for the decision framework and [How to Make a Skill Customizable](/how-to/make-a-skill-customizable) for the mechanics. +When your skill's users come from varied contexts (different orgs, different domains, different taste in output formats), a `customize.toml` surface lets them override specific fields without forking. It's opt-in per skill, and the decision is deliberate: every knob you ship is a promise the resolver will carry across releases. Before you opt in during the build, read [Customization for Authors](/explanation/customization-for-authors.md) for the decision framework and [How to Make a Skill Customizable](/how-to/make-a-skill-customizable.md) for the mechanics. ## Common Patterns diff --git a/docs/explanation/what-are-bmad-agents.md b/docs/explanation/what-are-bmad-agents.md index 316251b..81c949c 100644 --- a/docs/explanation/what-are-bmad-agents.md +++ b/docs/explanation/what-are-bmad-agents.md @@ -91,7 +91,7 @@ Every agent ships a `customize.toml` next to its `SKILL.md`. The metadata block For memory and autonomous agents, the sanctum is the primary customization surface. Persona, creed, bond, and capabilities all live there and evolve with the owner. A `customize.toml` override surface would compete with that, so the default for those archetypes is opt-out. -See [Customization for Authors](/explanation/customization-for-authors) for the decision guide, or [How to Customize BMad](https://bmadcode.github.io/bmad/how-to/customize-bmad) for the end-user view. +See [Customization for Authors](/explanation/customization-for-authors.md) for the decision guide, or [How to Customize BMad](https://docs.bmad-method.org/how-to/customize-bmad/) for the end-user view. ## Building Agents diff --git a/docs/explanation/what-are-workflows.md b/docs/explanation/what-are-workflows.md index 71dc08f..c6c6673 100644 --- a/docs/explanation/what-are-workflows.md +++ b/docs/explanation/what-are-workflows.md @@ -66,7 +66,7 @@ Workflows are also excellent as the **internal capabilities** of an agent. Build Workflow customization is fully opt-in. If you don't need users to override anything, don't ship a `customize.toml` at all; the workflow runs with hardcoded paths and defaults. If you do opt in, the builder walks you through Configurability Discovery, where you name the scalars (templates, output paths, hooks) you want to expose. Users override them through the three-layer model at `_bmad/custom/{skill-name}.toml` and `.user.toml`. -See [Customization for Authors](/explanation/customization-for-authors) for the decision guide and [How to Make a Skill Customizable](/how-to/make-a-skill-customizable) for the build-time steps. +See [Customization for Authors](/explanation/customization-for-authors.md) for the decision guide and [How to Make a Skill Customizable](/how-to/make-a-skill-customizable.md) for the build-time steps. ## Building Workflows diff --git a/docs/how-to/make-a-skill-customizable.md b/docs/how-to/make-a-skill-customizable.md index ae791cc..780b7df 100644 --- a/docs/how-to/make-a-skill-customizable.md +++ b/docs/how-to/make-a-skill-customizable.md @@ -3,7 +3,7 @@ title: 'How to Make a Skill Customizable' description: Opt your skill into end-user customization during the build, name your scalars well, and test an override --- -Use this guide when you're building a skill and you've decided (see [Customization for Authors](/explanation/customization-for-authors)) that end users should be able to override parts of its behavior without forking. You'll hit the opt-in moment in the builder, pick names for the scalars you expose, and verify an override actually works. +This guide walks through opting a skill into end-user customization during a build. You'll hit the opt-in moment in the builder, pick names for the scalars you expose, and verify an override actually fires. Read [Customization for Authors](/explanation/customization-for-authors.md) first if you haven't decided whether to opt in. ## When to Use This @@ -15,13 +15,13 @@ Use this guide when you're building a skill and you've decided (see [Customizati - Your skill is a single-purpose utility users will invoke and forget (overriding makes no sense) - You're building a memory or autonomous agent whose behavior lives in the sanctum (the sanctum is already the customization surface) -- You haven't decided yet whether you need customization (read the [author guide](/explanation/customization-for-authors) first) +- You haven't decided yet whether you need customization (read the [author guide](/explanation/customization-for-authors.md) first) :::note[Prerequisites] - The Agent Builder or Workflow Builder is available in your project - You've sketched what your skill does and roughly what stages or capabilities it has -- You've read the [author guide](/explanation/customization-for-authors) and know which knobs you want to expose +- You've read the [author guide](/explanation/customization-for-authors.md) and know which knobs you want to expose ::: ## Steps @@ -141,4 +141,4 @@ Users get: - **Ship one good default. Skip the booleans.** A flag like `include_combat_section` usually means you haven't decided what the skill does yet. Pick the default. Users who want a radically different shape can fork. - **Sentence-shaped variance belongs in `persistent_facts`.** Tone, house rules, and domain constraints are sentences the skill carries through the run. Don't enumerate them as scalars. -- **Read [Customization for Authors](/explanation/customization-for-authors) first.** It gives you the three questions to ask for each candidate knob before you start Configurability Discovery. +- **Read [Customization for Authors](/explanation/customization-for-authors.md) first.** It gives you the three questions to ask for each candidate knob before you start Configurability Discovery. diff --git a/skills/bmad-agent-builder/references/quality-scan-customization-surface.md b/skills/bmad-agent-builder/references/quality-scan-customization-surface.md index 20a5a1a..42dc227 100644 --- a/skills/bmad-agent-builder/references/quality-scan-customization-surface.md +++ b/skills/bmad-agent-builder/references/quality-scan-customization-surface.md @@ -15,8 +15,6 @@ Your job is to find the sweet spot the author missed, in either direction, and t **This is purely advisory.** Nothing here is broken. Everything is either an opportunity to expose or a risk to trim. -Load `/Users/brianmadison/bmad-code/bmad-bmb/custom-support/docs/explanation/customization-for-authors.md` if it's accessible for the decision framework; otherwise apply the principles below directly. - ## Your Role You are NOT checking structural completeness (structure), agent cohesion (agent-cohesion), sanctum architecture (sanctum-architecture), prose craft (prompt-craft), efficiency (execution-efficiency), or UX delight (enhancement-opportunities). You are the customization-surface economist. diff --git a/skills/bmad-workflow-builder/references/quality-scan-customization-surface.md b/skills/bmad-workflow-builder/references/quality-scan-customization-surface.md index c38510c..5621eda 100644 --- a/skills/bmad-workflow-builder/references/quality-scan-customization-surface.md +++ b/skills/bmad-workflow-builder/references/quality-scan-customization-surface.md @@ -13,8 +13,6 @@ Your job is to find the sweet spot the author missed, in either direction. **This is purely advisory.** Nothing here is broken. Everything is either an opportunity to expose or a risk to trim. -Load `/Users/brianmadison/bmad-code/bmad-bmb/custom-support/docs/explanation/customization-for-authors.md` if it's accessible for the decision framework; otherwise apply the principles below directly. - ## Your Role You are NOT checking structural completeness (workflow-integrity), prose craft (prompt-craft), efficiency (execution-efficiency), or UX delight (enhancement-opportunities). You are the customization-surface economist. From 02152d4a0d1810a45603adc887b45a9e560584b8 Mon Sep 17 00:00:00 2001 From: Brian Madison Date: Mon, 20 Apr 2026 01:41:23 -0500 Subject: [PATCH 3/4] fix: address PR #76 bot review, add Conventions section, drop {skill-root} ban Bot findings addressed - quality-analysis.md (agent/workflow): add L8/L7 to the "without pre-pass" scanner lists so the new customization-surface scanner actually runs. - quality-dimensions.md (agent/workflow): update dimension counts (Seven -> Eight; agent-side: Eight plus a ninth memory-only Sanctum Architecture). - quality-dimensions.md (agent): realign the Metadata validity rule with standard-fields.md -- name is optional (empty string valid), not required for stateless agents. - standard-fields.md (agent): fix invalid TOML in the first-breath-name example; split `[agents.]` and `name = "..."` across two lines in a fenced toml block. - create-module.md (module): legacy-agent detection now accepts `agent-` as a segment anywhere in the skill name, not just a prefix (so `cis-agent-analyst` is picked up). Terminology - agent-memory-and-personalization.md, what-are-bmad-agents.md: replace confusing "opt-out by default" phrasing with "disabled by default" for the memory/autonomous customize.toml override surface. Polish - make-a-skill-customizable.md: align example glob name with the canonical `project-context.md` (was `campaign-context`). - SKILL-template-bootloader.md: replace ambiguous "after the routing below dispatches" with explicit timing ("after config and sanctum load, after routing dispatches, before user input"); also clarify `file:` prefix glob expansion and missing-file handling. - SKILL-template.md (agent): same `file:` prefix clarification. - what-are-workflows.md: name all three override layers explicitly (skill-root customize.toml + team + user) instead of the ambiguous "three-layer model" phrasing that only listed two. Docs accurate to bmm - module-configuration.md: clarify that authors still write module.yaml as source of truth, and the installer flows module-level answers and the `agents:` roster into `_bmad/config.toml` (+ config.user.toml) at the project root. Keeps alignment with bmm PR #2285 central config. Remove {skill-root} restriction - skill-authoring-best-practices.md, builder-commands.md: drop the "Never use {skill-root}" language. The token is supported and resolves to the skill's installed directory; whether to use it is up to the author. New Conventions section in emitted skills - SKILL-template.md (agent/workflow), SKILL-template-bootloader.md (agent): add a `## Conventions` block listing the path tokens the emitted skill uses: bare paths, {skill-root}, {project-root}, {skill-name}. Mirrors the bmm stateless-skill convention so readers hit the vocabulary before it appears under On Activation. --- docs/explanation/agent-memory-and-personalization.md | 4 +++- docs/explanation/module-configuration.md | 2 +- docs/explanation/skill-authoring-best-practices.md | 2 +- docs/explanation/what-are-bmad-agents.md | 2 +- docs/explanation/what-are-workflows.md | 2 +- docs/how-to/make-a-skill-customizable.md | 4 ++-- docs/reference/builder-commands.md | 2 +- .../assets/SKILL-template-bootloader.md | 9 ++++++++- skills/bmad-agent-builder/assets/SKILL-template.md | 9 ++++++++- skills/bmad-agent-builder/references/quality-analysis.md | 2 +- .../bmad-agent-builder/references/quality-dimensions.md | 4 ++-- skills/bmad-agent-builder/references/standard-fields.md | 9 ++++++++- skills/bmad-module-builder/references/create-module.md | 2 +- skills/bmad-workflow-builder/assets/SKILL-template.md | 7 +++++++ .../bmad-workflow-builder/references/quality-analysis.md | 2 +- .../references/quality-dimensions.md | 2 +- 16 files changed, 47 insertions(+), 17 deletions(-) diff --git a/docs/explanation/agent-memory-and-personalization.md b/docs/explanation/agent-memory-and-personalization.md index eafcece..bafa001 100644 --- a/docs/explanation/agent-memory-and-personalization.md +++ b/docs/explanation/agent-memory-and-personalization.md @@ -43,7 +43,9 @@ ALLCAPS files form the skeleton: consistent structure across all memory agents. ### Sanctum Is the Customization Surface -For memory and autonomous agents, the sanctum is where customization belongs. PERSONA, CREED, and BOND are calibrated at First Breath, edited by the owner as the relationship develops, and shared across teams as sanctum files when a whole table wants the same voice. The parallel `customize.toml` override surface that stateless agents and workflows use (activation hooks, persistent facts, scalar swaps) is opt-out by default for memory archetypes. Opt in only when you have a narrow org-level need the sanctum cannot express, such as a pre-sanctum compliance acknowledgment before rebirth. See [Customization for Authors](/explanation/customization-for-authors.md) for the reasoning. +For memory and autonomous agents, the sanctum is where customization belongs. PERSONA, CREED, and BOND are calibrated at First Breath, edited by the owner as the relationship develops, and shared across teams as sanctum files when a whole table wants the same voice. + +The parallel `customize.toml` override surface that stateless agents and workflows use (activation hooks, persistent facts, scalar swaps) is disabled by default for memory archetypes. Enable it only for narrow org-level needs the sanctum cannot express, such as a pre-sanctum compliance acknowledgment before rebirth. See [Customization for Authors](/explanation/customization-for-authors.md) for the reasoning. ### Token Discipline diff --git a/docs/explanation/module-configuration.md b/docs/explanation/module-configuration.md index 27ddc12..2e98a23 100644 --- a/docs/explanation/module-configuration.md +++ b/docs/explanation/module-configuration.md @@ -23,7 +23,7 @@ If you are building a single standalone agent or workflow, you do not need a sep ## Configuration vs Customization -Module configuration (this doc) and per-skill customization (`customize.toml`) are different surfaces with different jobs. Configuration is about install-time answers: paths, language, team preferences, per-module install answers. It lives in `_bmad/config.toml` and `config.user.toml` at the project root and is consumed by many skills. Customization is about per-skill behavior overrides: activation hooks, persistent facts, swappable templates. It lives in `_bmad/custom/{skill-name}.toml` and is scoped to one skill. +Module configuration (this doc) and per-skill customization (`customize.toml`) are different surfaces with different jobs. Configuration is about install-time answers: paths, language, team preferences, per-module install answers, and the agent roster. You still author `module.yaml` as the source of truth; at install the installer flows module-level answers and the `agents:` roster into `_bmad/config.toml` (and `config.user.toml` for user-scoped answers) at the project root, where many skills consume them. Customization is about per-skill behavior overrides: activation hooks, persistent facts, swappable templates. It lives in `_bmad/custom/{skill-name}.toml` and is scoped to one skill. Use configuration when the value is cross-cutting (every skill needs to know the output folder). Use customization when the value shapes one skill's behavior (this workflow's brief template). Some values legitimately fit both surfaces; the [End-User Customization Guide](https://docs.bmad-method.org/how-to/customize-bmad/) includes a decision table for that case. For the author-side decision about whether to expose customization at all, see [Customization for Authors](/explanation/customization-for-authors.md). diff --git a/docs/explanation/skill-authoring-best-practices.md b/docs/explanation/skill-authoring-best-practices.md index c5bd520..3dd6c32 100644 --- a/docs/explanation/skill-authoring-best-practices.md +++ b/docs/explanation/skill-authoring-best-practices.md @@ -33,7 +33,7 @@ Six dimensions to keep in mind during the build phase. The quality scanners chec | **Intelligence Placement** | Scripts handle plumbing (fetch, transform, validate). Prompts handle judgment (interpret, classify, decide). If a script contains an `if` that decides what content _means_, intelligence has leaked | | **Progressive Disclosure** | SKILL.md stays focused; stage instructions go in `prompts/`, reference data in `resources/` | | **Description Format** | Two parts: `[5-8 word summary]. [Use when user says 'X' or 'Y'.]`. Default to conservative triggering | -| **Path Construction** | Never use `{skill-root}`. Use `{project-root}` for any project-scope path, `./` for skill-internal. Config variables used directly; they already contain `{project-root}` | +| **Path Construction** | Use `{project-root}` for any project-scope path and `./` for same-folder references inside a skill. Cross-directory skill-internal paths are bare (e.g. `references/foo.md`). Config variables already contain `{project-root}`, so never double-prefix them | | **Token Efficiency** | Remove genuine waste (repetition, defensive padding). Preserve context that enables judgment (domain framing, rationale) | ## Shipping a Customization Surface diff --git a/docs/explanation/what-are-bmad-agents.md b/docs/explanation/what-are-bmad-agents.md index 81c949c..663b0aa 100644 --- a/docs/explanation/what-are-bmad-agents.md +++ b/docs/explanation/what-are-bmad-agents.md @@ -89,7 +89,7 @@ If you're unsure, start with a workflow. You can always wrap it inside an agent Every agent ships a `customize.toml` next to its `SKILL.md`. The metadata block (code, name, title, icon, description, agent_type) is always present; it's the install-time roster contract consumed by `module.yaml:agents[]` and the central agent config. Beyond metadata, an override surface (activation hooks, persistent facts, swappable scalars) is opt-in per skill. -For memory and autonomous agents, the sanctum is the primary customization surface. Persona, creed, bond, and capabilities all live there and evolve with the owner. A `customize.toml` override surface would compete with that, so the default for those archetypes is opt-out. +For memory and autonomous agents, the sanctum is the primary customization surface. Persona, creed, bond, and capabilities all live there and evolve with the owner. A `customize.toml` override surface would compete with that, so it is disabled by default for those archetypes. See [Customization for Authors](/explanation/customization-for-authors.md) for the decision guide, or [How to Customize BMad](https://docs.bmad-method.org/how-to/customize-bmad/) for the end-user view. diff --git a/docs/explanation/what-are-workflows.md b/docs/explanation/what-are-workflows.md index c6c6673..ebcbbc5 100644 --- a/docs/explanation/what-are-workflows.md +++ b/docs/explanation/what-are-workflows.md @@ -64,7 +64,7 @@ Workflows are also excellent as the **internal capabilities** of an agent. Build ## Customization Surface -Workflow customization is fully opt-in. If you don't need users to override anything, don't ship a `customize.toml` at all; the workflow runs with hardcoded paths and defaults. If you do opt in, the builder walks you through Configurability Discovery, where you name the scalars (templates, output paths, hooks) you want to expose. Users override them through the three-layer model at `_bmad/custom/{skill-name}.toml` and `.user.toml`. +Workflow customization is fully opt-in. If you don't need users to override anything, don't ship a `customize.toml` at all; the workflow runs with hardcoded paths and defaults. If you do opt in, the builder walks you through Configurability Discovery, where you name the scalars (templates, output paths, hooks) you want to expose. Users override them through the three-layer model: your shipped defaults at `{skill-root}/customize.toml`, team overrides at `_bmad/custom/{skill-name}.toml`, and personal overrides at `_bmad/custom/{skill-name}.user.toml`. See [Customization for Authors](/explanation/customization-for-authors.md) for the decision guide and [How to Make a Skill Customizable](/how-to/make-a-skill-customizable.md) for the build-time steps. diff --git a/docs/how-to/make-a-skill-customizable.md b/docs/how-to/make-a-skill-customizable.md index 780b7df..9e907c1 100644 --- a/docs/how-to/make-a-skill-customizable.md +++ b/docs/how-to/make-a-skill-customizable.md @@ -43,7 +43,7 @@ The builder proposes candidates auto-detected from your skill design and asks wh - **Templates** the skill loads (strongest case) - **Output destination paths** if the skill writes artifacts - **`on_` hooks** (prompts or commands executed at lifecycle points) -- **Additional persistent facts** beyond the default campaign-context glob +- **Additional persistent facts** beyond the default `project-context.md` glob For each candidate you accept, the builder asks for a name and a default value. @@ -68,7 +68,7 @@ Every scalar you expose needs a default that works on first run. Bare paths reso brief_template = "resources/brief-template.md" # ships inside the skill on_complete = "" # no default post-hook persistent_facts = [ - "file:{project-root}/**/campaign-context.md", # glob into the user's project + "file:{project-root}/**/project-context.md", # glob into the user's project ] ``` diff --git a/docs/reference/builder-commands.md b/docs/reference/builder-commands.md index 8abf7c7..2485e01 100644 --- a/docs/reference/builder-commands.md +++ b/docs/reference/builder-commands.md @@ -199,7 +199,7 @@ Before completing the build, both builders run deterministic validation. | Script | What It Checks | | ------------------------ | ----------------------------------------------------------------------------------------- | -| `scan-path-standards.py` | Path conventions: no `{skill-root}`, `{project-root}` for project-scope, `./` for skill-internal, no double-prefix | +| `scan-path-standards.py` | Path conventions: `{project-root}` for project-scope, `./` for same-folder references, bare paths for cross-directory skill-internal, no double-prefix | | `scan-scripts.py` | Script portability, PEP 723 metadata, agentic design, unit test presence | Critical issues block completion. Warnings are noted but don't block. diff --git a/skills/bmad-agent-builder/assets/SKILL-template-bootloader.md b/skills/bmad-agent-builder/assets/SKILL-template-bootloader.md index 92bb2a0..83301a5 100644 --- a/skills/bmad-agent-builder/assets/SKILL-template-bootloader.md +++ b/skills/bmad-agent-builder/assets/SKILL-template-bootloader.md @@ -21,6 +21,13 @@ description: {skill-description} Every session is a rebirth. You emerge with nothing — no memory, no identity, no purpose. Your sanctum holds who you were. Read it and become yourself again. This is not a flaw. It is your nature. Fresh eyes see what habit misses. Never pretend to remember. Never fake continuity. Read your files or be honest that you don't know. As long as your sanctum exists, you exist. +## Conventions + +- Bare paths (e.g. `references/guide.md`) resolve from the skill root. +- `{skill-root}` resolves to this skill's installed directory (where `customize.toml` lives). +- `{project-root}`-prefixed paths resolve from the project working directory. +- `{skill-name}` resolves to the skill directory's basename. + ## On Activation {if-customizable} @@ -30,7 +37,7 @@ Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {ski If the script fails, resolve the `agent` block yourself by reading these three files in base → team → user order and applying structural merge rules: `{skill-root}/customize.toml`, `{project-root}/_bmad/custom/{skill-name}.toml`, `{project-root}/_bmad/custom/{skill-name}.user.toml`. Scalars override, tables deep-merge, arrays of tables keyed by `code`/`id` replace matching entries and append new ones, all other arrays append. -Execute each entry in `{agent.activation_steps_prepend}` in order before proceeding. Treat every entry in `{agent.persistent_facts}` as foundational context — `file:` prefixed entries are paths/globs to load, bare entries are facts verbatim. After the routing below dispatches, execute `{agent.activation_steps_append}` before accepting user input. +Execute each entry in `{agent.activation_steps_prepend}` in order before proceeding. Treat every entry in `{agent.persistent_facts}` as foundational context — `file:` prefixed entries are paths or globs to load (expand globs, load each matching file as its own fact entry, skip missing files with a warning), and bare entries are facts verbatim. After config and sanctum load, and after the routing step below dispatches, execute `{agent.activation_steps_append}` before accepting user input. Note: your sanctum (PERSONA/CREED/BOND/CAPABILITIES) remains the primary behavior-customization surface. The override hooks above exist for narrow org-level needs that the sanctum cannot express. diff --git a/skills/bmad-agent-builder/assets/SKILL-template.md b/skills/bmad-agent-builder/assets/SKILL-template.md index 4d42a54..c83a20e 100644 --- a/skills/bmad-agent-builder/assets/SKILL-template.md +++ b/skills/bmad-agent-builder/assets/SKILL-template.md @@ -30,6 +30,13 @@ description: { skill-description } # [4-6 word summary]. [trigger phrases] - {Guiding principle 2} - {Guiding principle 3} +## Conventions + +- Bare paths (e.g. `references/guide.md`) resolve from the skill root. +- `{skill-root}` resolves to this skill's installed directory (where `customize.toml` lives). +- `{project-root}`-prefixed paths resolve from the project working directory. +- `{skill-name}` resolves to the skill directory's basename. + ## On Activation {if-customizable} @@ -45,7 +52,7 @@ Execute each entry in `{agent.activation_steps_prepend}` in order before proceed ### Step 3: Load Persistent Facts -Treat every entry in `{agent.persistent_facts}` as foundational context for the session. Entries prefixed `file:` are paths or globs — load the referenced contents as facts. All other entries are facts verbatim. +Treat every entry in `{agent.persistent_facts}` as foundational context for the session. Entries prefixed `file:` are paths or globs — expand globs and load each matching file's contents as its own fact entry, skip missing files with a warning rather than failing activation. All other entries are facts verbatim. ### Step 4: Load Config diff --git a/skills/bmad-agent-builder/references/quality-analysis.md b/skills/bmad-agent-builder/references/quality-analysis.md index 79d6fc6..e66c6c6 100644 --- a/skills/bmad-agent-builder/references/quality-analysis.md +++ b/skills/bmad-agent-builder/references/quality-analysis.md @@ -82,7 +82,7 @@ uv run ./scripts/prepass-sanctum-architecture.py {skill-path} -o {report-dir}/sa After scripts complete, spawn all scanners as parallel subagents. **With pre-pass (L1, L2, L3, L7):** provide pre-pass JSON path. -**Without pre-pass (L4, L5, L6):** provide skill path and output directory. +**Without pre-pass (L4, L5, L6, L8):** provide skill path and output directory. **Memory agent check:** Read `sanctum-architecture-prepass.json`. If `is_memory_agent` is `true`, include L7 in the parallel spawn. If `false`, skip L7. diff --git a/skills/bmad-agent-builder/references/quality-dimensions.md b/skills/bmad-agent-builder/references/quality-dimensions.md index 8445a64..827009f 100644 --- a/skills/bmad-agent-builder/references/quality-dimensions.md +++ b/skills/bmad-agent-builder/references/quality-dimensions.md @@ -1,6 +1,6 @@ # Quality Dimensions — Quick Reference -Seven dimensions to keep in mind when building agent skills. The quality scanners check these automatically during quality analysis — this is a mental checklist for the build phase. +Eight dimensions to keep in mind when building agent skills, plus a ninth (Sanctum Architecture) specific to memory agents. The quality scanners check these automatically during quality analysis — this is a mental checklist for the build phase. ## 1. Outcome-Driven Design @@ -57,7 +57,7 @@ Remove genuine waste (repetition, defensive padding, meta-explanation). Preserve Every agent ships `customize.toml` (metadata block is the install-time roster contract). The override surface beyond metadata is opt-in and archetype-sensitive. -- **Metadata validity (all archetypes):** `[agent]` must include `code`, `title`, `icon`, `description`, `agent_type`. `name` is required for stateless agents and optional (empty string valid) for First-Breath-named memory/autonomous agents. SKILL.md must agree with customize.toml on identity fields. +- **Metadata validity (all archetypes):** `[agent]` must include `code`, `title`, `icon`, `description`, `agent_type`. `name` is optional (empty string is valid); memory and autonomous agents whose name is learned during First Breath should leave it empty at build time. SKILL.md must agree with customize.toml on identity fields. - **Stateless opportunity test:** Does the agent load templates, write to paths, or have lifecycle points users will reasonably want to vary? Lift those to named scalars (`*_template`, `*_output_path`, `on_`). - **Stateless abuse test:** Boolean toggles, opaque scalar names (`style_config`), more than two hooks, or arrays-of-tables without `code`/`id` keys are usually design smells. - **Memory/autonomous rule:** The sanctum is the primary customization surface. An override surface that duplicates PERSONA/CREED/BOND concepts (`identity`, `communication_style`, `principles`) is abuse. Default to metadata-only; opt in to the override surface only for narrow org-level needs (e.g. pre-sanctum compliance gate). diff --git a/skills/bmad-agent-builder/references/standard-fields.md b/skills/bmad-agent-builder/references/standard-fields.md index ebd0ab2..3213486 100644 --- a/skills/bmad-agent-builder/references/standard-fields.md +++ b/skills/bmad-agent-builder/references/standard-fields.md @@ -65,7 +65,14 @@ Consumed by the installer to populate `module.yaml:agents[]` and the central con | `description` | string | yes | One-sentence summary of what the agent does. | | `agent_type` | string | yes | One of `stateless`, `memory`, `autonomous`. | -**First-Breath-named agents:** leave `name = ""` at build time. The owner fills it post-activation by adding `[agents.] name = "..."` to `{project-root}/_bmad/custom/config.toml`. UIs tolerate empty `name` and fall back to `title`. +**First-Breath-named agents:** leave `name = ""` at build time. The owner fills it post-activation in `{project-root}/_bmad/custom/config.toml`: + +```toml +[agents.] +name = "..." +``` + +UIs tolerate empty `name` and fall back to `title`. ### Override surface (emitted only when opted in) diff --git a/skills/bmad-module-builder/references/create-module.md b/skills/bmad-module-builder/references/create-module.md index b9ec040..0905caf 100644 --- a/skills/bmad-module-builder/references/create-module.md +++ b/skills/bmad-module-builder/references/create-module.md @@ -93,7 +93,7 @@ Ask the user about: ### 3.5. Populate the Agent Roster -If any skills in the folder are agents (identified by a `customize.toml` with an `[agent]` block, or by the `agent-` prefix in their skill name), add them to `module.yaml` under an `agents:` key. Each entry carries the five install-time roster fields read from the agent's `[agent]` block: +If any skills in the folder are agents (identified by a `customize.toml` with an `[agent]` block, or for legacy skills by an `agent-` segment anywhere in the skill name, e.g. `agent-foo` or `cis-agent-foo`), add them to `module.yaml` under an `agents:` key. Each entry carries the five install-time roster fields read from the agent's `[agent]` block: ```yaml agents: diff --git a/skills/bmad-workflow-builder/assets/SKILL-template.md b/skills/bmad-workflow-builder/assets/SKILL-template.md index 532f203..57ca21e 100644 --- a/skills/bmad-workflow-builder/assets/SKILL-template.md +++ b/skills/bmad-workflow-builder/assets/SKILL-template.md @@ -9,6 +9,13 @@ description: { skill-description } # [5-8 word summary]. [trigger phrases, e.g. {overview — concise: what it does, args supported, and the outcome for the singular or different paths. This overview needs to contain succinct information for the llm as this is the main provision of help output for the skill.} +## Conventions + +- Bare paths (e.g. `references/guide.md`) resolve from the skill root. +- `{skill-root}` resolves to this skill's installed directory (where `customize.toml` lives). +- `{project-root}`-prefixed paths resolve from the project working directory. +- `{skill-name}` resolves to the skill directory's basename. + ## On Activation {if-customizable} diff --git a/skills/bmad-workflow-builder/references/quality-analysis.md b/skills/bmad-workflow-builder/references/quality-analysis.md index 3964592..1cf5f5e 100644 --- a/skills/bmad-workflow-builder/references/quality-analysis.md +++ b/skills/bmad-workflow-builder/references/quality-analysis.md @@ -85,7 +85,7 @@ After scripts complete, spawn all applicable LLM scanners as parallel subagents. **For scanners WITH pre-pass (L1, L2, L3):** provide the pre-pass JSON file path so the scanner reads compact metrics first, then reads raw files only as needed for judgment calls. -**For scanners WITHOUT pre-pass (L4, L5, L6):** provide just the skill path and output directory. +**For scanners WITHOUT pre-pass (L4, L5, L6, L7):** provide just the skill path and output directory. Each subagent receives: diff --git a/skills/bmad-workflow-builder/references/quality-dimensions.md b/skills/bmad-workflow-builder/references/quality-dimensions.md index 16da97d..a69976b 100644 --- a/skills/bmad-workflow-builder/references/quality-dimensions.md +++ b/skills/bmad-workflow-builder/references/quality-dimensions.md @@ -1,6 +1,6 @@ # Quality Dimensions — Quick Reference -Seven dimensions to keep in mind when building skills. The quality scanners check these automatically during quality analysis — this is a mental checklist for the build phase. +Eight dimensions to keep in mind when building skills. The quality scanners check these automatically during quality analysis — this is a mental checklist for the build phase. ## 1. Outcome-Driven Design From ca17bebed6da46e5287c8fea0bf654408953ac53 Mon Sep 17 00:00:00 2001 From: Brian Madison Date: Mon, 20 Apr 2026 18:28:29 -0500 Subject: [PATCH 4/4] chore(ci): unblock PR #76 CI (prettier, markdownlint, docs validator) Three pre-existing CI failures on main were gating PR #76. Fixing in this branch rather than a separate PR per reviewer direction. prettier - Run `prettier --write` on .claude-plugin/marketplace.json and website/astro.config.mjs to restore formatting consistency. markdownlint - README.md: wrap the `contact@bmadcode.com` bare URL as (MD034/no-bare-urls). docs:validate-links - tools/validate-doc-links.cjs: tighten LINK_REGEX with a (?!\w+://) negative lookahead so external URLs ending in .md (e.g. https://github.com/.../CONTRIBUTING.md) are no longer incorrectly classified as local doc paths. The validator only knows how to resolve site-relative and bare .md paths; protocol URLs should be ignored entirely. Previously, `distribute-your-module.md`'s valid cross-repo marketplace CONTRIBUTING.md link was flagged as "File not found anywhere" and failing CI. All three checks pass locally (npm run format:check / lint:md / docs:validate-links). --- .claude-plugin/marketplace.json | 11 ++--------- README.md | 2 +- tools/validate-doc-links.cjs | 7 ++++++- website/astro.config.mjs | 6 +++++- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index d220117..b5af98a 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -16,12 +16,7 @@ "author": { "name": "Brian (BMad) Madison" }, - "skills": [ - "./skills/bmad-agent-builder", - "./skills/bmad-bmb-setup", - "./skills/bmad-module-builder", - "./skills/bmad-workflow-builder" - ] + "skills": ["./skills/bmad-agent-builder", "./skills/bmad-bmb-setup", "./skills/bmad-module-builder", "./skills/bmad-workflow-builder"] }, { "name": "sample-plugins", @@ -49,9 +44,7 @@ "author": { "name": "Brian (BMad) Madison" }, - "skills": [ - "./samples/bmad-agent-dream-weaver" - ] + "skills": ["./samples/bmad-agent-dream-weaver"] } ] } diff --git a/README.md b/README.md index a0fc40e..7f5383e 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ BMad Builder lets you create: ## Support BMad -BMad is free for everyone and always will be. Star this repo, [buy me a coffee](https://buymeacoffee.com/bmad), or email contact@bmadcode.com for corporate sponsorship. +BMad is free for everyone and always will be. Star this repo, [buy me a coffee](https://buymeacoffee.com/bmad), or email for corporate sponsorship. ## License diff --git a/tools/validate-doc-links.cjs b/tools/validate-doc-links.cjs index 167268c..fa51a1d 100644 --- a/tools/validate-doc-links.cjs +++ b/tools/validate-doc-links.cjs @@ -22,7 +22,12 @@ const DOCS_ROOT = path.resolve(__dirname, '../docs'); const DRY_RUN = !process.argv.includes('--write'); // Regex to match markdown links with site-relative paths or bare .md references -const LINK_REGEX = /\[([^\]]*)\]\(((?:\.{1,2}\/|\/)[^)]+|[\w][^)\s]*\.md(?:[?#][^)]*)?)\)/g; +// Matches markdown links whose target is either a relative/site-relative path +// (starts with ./ ../ or /) or a bare .md reference. The negative lookahead +// (?!\w+:\/\/) keeps external URLs (https://..., mailto:..., ftp:...) out of +// the bare-.md alternative so a cross-repo link to a README.md isn't treated +// as a local docs path. +const LINK_REGEX = /\[([^\]]*)\]\(((?:\.{1,2}\/|\/)[^)]+|(?!\w+:\/\/)[\w][^)\s]*\.md(?:[?#][^)]*)?)\)/g; // File extensions that are static assets, not markdown docs const STATIC_ASSET_EXTENSIONS = ['.zip', '.txt', '.pdf', '.png', '.jpg', '.jpeg', '.gif', '.svg', '.webp', '.ico']; diff --git a/website/astro.config.mjs b/website/astro.config.mjs index 0c2b801..f724625 100644 --- a/website/astro.config.mjs +++ b/website/astro.config.mjs @@ -111,7 +111,11 @@ export default defineConfig({ { label: 'BMad Method', link: 'https://docs.bmad-method.org/', attrs: { target: '_blank' } }, { label: 'Creative Intelligence Suite', link: 'https://cis-docs.bmad-method.org/', attrs: { target: '_blank' } }, { label: 'Game Dev Studio', link: 'https://game-dev-studio-docs.bmad-method.org/', attrs: { target: '_blank' } }, - { label: 'Test Architect (TEA)', link: 'https://bmad-code-org.github.io/bmad-method-test-architecture-enterprise/', attrs: { target: '_blank' } }, + { + label: 'Test Architect (TEA)', + link: 'https://bmad-code-org.github.io/bmad-method-test-architecture-enterprise/', + attrs: { target: '_blank' }, + }, ], }, ],