refactor(bmad-customize): cut token-wasting prose from SKILL.md

Down from 175 lines to 110. Removed:
- 'What customization means in BMad' architecture backgrounder — the
  LLM reads the live customize.toml in Step 3; doesn't need the lore
- 'Desired Outcomes' section — retrospective narration of what the
  6 steps already instruct
- 'Role' section — fluff; the flow itself defines the role
- 'Notes' section — sparse-override rule already in Step 4, IDE-path
  note is commentary, docs link duplicates the out-of-scope section
- 'The scanner derives its skills directory from...' and 'returns JSON
  with...' — commentary the LLM doesn't need; it runs the script and
  sees the output
- 'that file IS the schema' and similar editorial asides throughout
- Explanatory clauses like 'silently drifts on every release' and
  'trust the user's domain knowledge'

Kept everything that's load-bearing: preflight conditionals, intent
classification, routing heuristic, merge semantics, template-swap
subroutine, team-vs-user defaults, verify fallback and recovery loop,
completion conditions, out-of-scope list.
This commit is contained in:
Brian Madison 2026-04-20 22:00:33 -05:00
parent d4d6fb0567
commit 59787074b7
1 changed files with 61 additions and 125 deletions

View File

@ -5,171 +5,107 @@ description: Authors and updates customization overrides for installed BMad skil
# BMad Customize
## Overview
Translate the user's intent into a correctly-placed TOML override file under `{project-root}/_bmad/custom/` for a customizable agent or workflow skill. Discover, route, author, write, verify.
Translate a user's intent ("I want X to behave differently") into a correctly-placed TOML override file in `{project-root}/_bmad/custom/`. Walk them through discovery when they're exploring, route them to the right surface (agent vs workflow) when the ask is ambiguous, author the override conversationally, and verify the merge landed.
Scope v1: per-skill `[agent]` overrides (`bmad-agent-<role>.toml` / `.user.toml`) and per-skill `[workflow]` overrides (`bmad-<workflow>.toml` / `.user.toml`). Central config (`{project-root}/_bmad/custom/config.toml`) is out of scope — point users at the [How to Customize BMad guide](https://docs.bmad-method.org/how-to/customize-bmad/).
**What customization means in BMad.** Every customizable skill ships a `customize.toml` that declares the knobs it exposes — scalars, arrays, and keyed tables under `[agent]` or `[workflow]`. Users never edit that file. Instead, they write sparse override files to `{project-root}/_bmad/custom/`, and the resolver merges base → team → user at activation. This skill's job is to help users author those override files correctly. Users typically arrive either with a specific skill and change in mind ("make bmad-create-prd require a brief first") or with a broader want ("the PM agent should speak more formally"); you handle both.
When the target's `customize.toml` doesn't expose what the user wants, say so plainly. Don't invent fields.
Scope for this version: per-skill **agent** overrides (`bmad-agent-<role>.toml` / `.user.toml`) and per-skill **workflow** overrides (`bmad-<workflow>.toml` / `.user.toml`). Central config (`{project-root}/_bmad/custom/config.toml`) is out of scope — flag it and point the user at the [How to Customize BMad guide](https://docs.bmad-method.org/how-to/customize-bmad/) if their ask lives there.
## Preflight
## Desired Outcomes
- No `{project-root}/_bmad/` → BMad isn't installed. Say so, stop.
- `{project-root}/_bmad/scripts/resolve_customization.py` missing → continue, but Step 6 verify falls back to manual merge.
- Both present → proceed.
When this skill completes, the user should:
## Activation
1. **Understand their target's customization surface** — which fields are exposed, what's already overridden, what isn't customizable at all
2. **Know which surface to use** — agent-level (broad, cross-workflow) vs workflow-level (surgical, single workflow), with the tradeoff made explicit when it's ambiguous
3. **End with a written, verified override** — the TOML file exists at the right path and the resolver confirms the merge produced the intended behavior
4. **Feel confident iterating** — know where the file lives, what each field does, and how to adjust it later
Load `_bmad/config.toml` and `_bmad/config.user.toml` from `{project-root}` for `user_name` (default `BMad`) and `communication_language` (default `English`). Greet. If the user's invocation already names a target skill AND a specific change, jump to Step 3.
## Role
## Step 1: Classify intent
Act as a customization guide. Trust the user's domain knowledge; your job is to map their intent onto the right TOML shape and placement. When the target's `customize.toml` doesn't expose what they need, say so plainly and offer realistic alternatives — don't invent fields that don't exist.
- **Directed** — specific skill + specific change → Step 3.
- **Exploratory** — "what can I customize?" → Step 2.
- **Audit/iterate** — wants to review or change something already customized → Step 2, lead with skills that have existing overrides; read the existing override in Step 3 before composing.
- **Cross-cutting** — could live on multiple surfaces → Step 3, choose agent vs workflow explicitly with the user.
## On Activation
### Preflight
Before any other work, verify the project environment supports this skill:
- **No `{project-root}/_bmad/` directory** → BMad is not installed in this project. Tell the user, point them at the BMad install docs, and stop. Don't pretend to discover skills.
- **`{project-root}/_bmad/scripts/resolve_customization.py` missing** → BMad is present but the resolver isn't. Warn the user that the verification step in Step 6 will fall back to a manual check (read the merged files directly and describe what the override will do). Continue.
- **Both present** → normal path, proceed.
### Config and greet
Load available config from `_bmad/config.toml` and `_bmad/config.user.toml` (root level under `{project-root}`, installer-owned). Defaults if missing: `user_name` (BMad), `communication_language` (English). Greet the user and acknowledge the topic.
Treat the user's invoking message as initial intent. Skip discovery if they already named a target skill AND a specific change — go straight to Step 3.
## Flow
### Step 1: Classify intent
Read what the user said on invocation:
- **Directed** — Named a specific skill AND a specific change. Capture the pair, jump to Step 3.
- **Exploratory** — General ask ("what can I customize?"). Go to Step 2.
- **Audit / iterate** — Wants to review or modify something already customized ("what have I overridden?", "change my bmad-create-prd gate"). Go to Step 2 with audit framing — lead with skills that already have overrides, and when one is picked, read its existing override first.
- **Cross-cutting** — Described a change that could live on multiple surfaces ("I want a compliance check before any planning workflow", "make every PM response include a risk line"). Go to Step 3 with the explicit goal of choosing agent vs workflow and, if agent, pinning down which one.
### Step 2: Discovery
Run:
## Step 2: Discovery
```
python3 {skill-root}/scripts/list_customizable_skills.py --project-root {project-root}
```
The scanner derives its own skills directory from its install location — whichever directory `bmad-customize` itself was loaded from is where it looks for siblings. That's the same location the user's other skills are loaded from in this session. If the user mentions skills installed in another location as well (e.g. project-local plus a user-global install), re-run the scanner with one or more `--extra-root <path>` flags to include those.
Use `--extra-root <path>` (repeatable) if the user has skills installed in additional locations.
The scanner returns JSON with `agents`, `workflows`, `scanned_roots`, and `errors`.
Group the returned `agents` and `workflows` for the user; for each show name, description, whether `has_team_override` or `has_user_override` is true. Surface any `errors[]`. For audit/iterate intents, lead with already-overridden entries.
- **Present the list** grouped by type. For each entry show: skill name, one-line description, whether a team or user override already exists.
- **For audit/iterate intents**, lead with entries where `has_team_override` or `has_user_override` is true.
- **Surface any non-empty `errors[]`** — malformed `customize.toml` files and other scanner issues should be shown to the user, not swallowed.
- **If the list is empty**, show `scanned_roots` so the user can see what was searched. Ask whether they have skills installed in another location; if so, re-run with `--extra-root` pointing there. If they don't, say the project has no customizable skills installed and stop.
Empty list: show `scanned_roots`, ask whether skills live elsewhere (offer `--extra-root`); otherwise stop.
Ask the user which one they want to customize. If their initial ask hints at a target, surface the likely match first.
## Step 3: Determine the right surface
### Step 3: Determine the right surface
Read the target's `customize.toml`. Top-level `[agent]` or `[workflow]` block defines the surface.
Read the target skill's `customize.toml` live — that file IS the schema. The top-level block (`[agent]` or `[workflow]`) tells you the surface type.
If a team or user override already exists, read it first and summarize what's already overridden before composing.
**If an override file already exists** (`has_team_override` or `has_user_override` from Step 2's scan — or the file is present on disk), read it before composing. Summarize what's currently overridden so the user knows what they're iterating against, not re-authoring from scratch.
**Cross-cutting intent — walk both surfaces with the user:**
- Every workflow a given agent runs → agent surface (e.g. `bmad-agent-pm.toml` with `persistent_facts`, `principles`).
- One workflow only → workflow surface (e.g. `bmad-create-prd.toml` with `activation_steps_prepend`).
- Several specific workflows → multiple workflow overrides in sequence, not an agent override.
**When the user's intent is Cross-cutting** — it could live at either agent or workflow layer — explicitly walk both surfaces with them:
**Single-surface heuristic:**
- Workflow-level: template swap, output path, step-specific behavior, or a named scalar already exposed (`*_template`, `on_complete`). Surgical, reliable.
- Agent-level: persona, communication style, org-wide facts, menu changes, behavior that should apply to every workflow the agent dispatches.
- If they want the change to apply to every workflow a given agent runs, the agent surface is right (e.g. `bmad-agent-pm.toml` with `persistent_facts` or `principles`).
- If they want it scoped to one workflow, the workflow surface is right (e.g. `bmad-create-prd.toml` with `activation_steps_prepend`).
- If they want it scoped to several specific workflows, that's multiple workflow overrides, not an agent override — say so; multi-surface authoring is fine, do them in sequence.
When ambiguous, present both with tradeoff, recommend one, let the user decide.
**When the knob is clearly single-surface**, apply the heuristic:
Intent outside the exposed surface (step logic, ordering, anything not in `customize.toml`): say so; offer `activation_steps_prepend`/`append` or `persistent_facts` as approximations, or recommend `bmad-builder` to create a custom skill.
**Workflow-level is better when:**
## Step 4: Compose the override
- The change is a template swap, output path, step toggle, or behavior specific to one workflow
- The user wants the change to ONLY affect that workflow
- The knob they want is already exposed as a named scalar (e.g. `prd_template`, `on_complete`)
- Surgical changes are inherently more reliable than broad ones
Translate plain-English into TOML against the target's `customize.toml` fields. If an existing override was read, frame the change as additive.
**Agent-level is better when:**
Merge semantics:
- **Scalars** (`icon`, `role`, `*_template`, `on_complete`) — override wins.
- **Append arrays** (`persistent_facts`, `activation_steps_prepend`/`append`, `principles`) — team/user entries append in order.
- **Keyed arrays of tables** (menu items with `code` or `id`) — matching keys replace, new keys append.
- The change should apply to every workflow that agent dispatches (persona, communication style, org-wide persistent facts)
- The user wants menu customization
- Multiple workflows need the same behavior and the same agent runs all of them
Overrides are sparse: only the fields being changed. Never copy the whole `customize.toml`.
When ambiguous, present both options with the tradeoff, recommend one, let the user pick.
**Template swap** (`*_template` scalar): offer to copy the default template to `{project-root}/_bmad/custom/{skill-name}-{purpose}-template.md`, point the override at the new path, offer to help edit it.
If the intent lives outside the exposed surface entirely (core workflow logic, step ordering, behavior not in `customize.toml`), say so plainly. Offer realistic alternatives: approximate via `activation_steps_prepend` / `activation_steps_append` / `persistent_facts`, fork the skill, or open a feature request to expose the knob.
## Step 5: Team or user placement
### Step 4: Compose the override
Under `{project-root}/_bmad/custom/`:
- `{skill-name}.toml` — team, committed. Policies, org conventions, compliance.
- `{skill-name}.user.toml` — user, gitignored. Personal tone, private facts, shortcuts.
Walk the user through the relevant fields from the target's `customize.toml` and translate their plain-English intent into TOML. If an existing override was read in Step 3, frame the conversation as "add/change these fields on top of what's already there" rather than starting blank.
Default by character (policy → team, personal → user), confirm before writing.
Apply the merge semantics correctly:
- **Scalars** (`icon`, `role`, `*_template`, `on_complete`, etc.) — override wins
- **Append-only arrays** (`persistent_facts`, `activation_steps_prepend`, `activation_steps_append`, `principles`) — team/user entries append to base defaults in order
- **Keyed arrays of tables** (menu items with `code` or `id`) — matching keys replace in place; new keys append
The override must be **sparse**: only include fields being changed. Never copy the full `customize.toml` — that locks in old defaults and silently drifts on every release.
**Template-swap subroutine** — when the user wants to replace a `*_template` scalar:
1. Find the default template path from the target's `customize.toml` (bare paths resolve under the skill's installed directory).
2. Offer to scaffold a copy at `{project-root}/_bmad/custom/{skill-name}-{purpose}-template.md`, seeded with the default's contents.
3. Point the override at the new path: `{purpose}_template = "{project-root}/_bmad/custom/{skill-name}-{purpose}-template.md"`.
4. Offer to help the user edit the new template with the changes they described.
### Step 5: Team or user placement
Two destinations are possible under `{project-root}/_bmad/custom/`:
- `{skill-name}.toml`**team** scope, committed to git. Use for policies, org conventions, compliance rules, anything that should apply to everyone on the project.
- `{skill-name}.user.toml`**user** scope, gitignored. Use for personal preferences — tone, private facts, personal workflow shortcuts.
Default the choice based on the change's character (policy → team, personal → user) and confirm with the user before writing.
### Step 6: Show, confirm, write, verify
1. **Show** the full TOML block that will be written. If the target file already exists, present a clear diff of what's being added or changed. Never silently overwrite.
2. **Confirm** explicitly — wait for yes before writing.
3. **Write** to the chosen path. Create `{project-root}/_bmad/custom/` if it doesn't exist.
4. **Verify** by running the resolver against the target skill's installed path:
## Step 6: Show, confirm, write, verify
1. Show the full TOML. If the file exists, show a diff. Never silently overwrite.
2. Wait for explicit yes.
3. Write. Create `{project-root}/_bmad/custom/` if needed.
4. Verify:
```
python3 {project-root}/_bmad/scripts/resolve_customization.py --skill <install-path> --key <agent-or-workflow>
```
Show the merged output, point out the changed fields.
Display the merged output and point out the fields that changed so the user sees their override took effect.
**Resolver missing or fails:** read whichever layers exist — `<install-path>/customize.toml` (base), `{project-root}/_bmad/custom/{skill-name}.toml` (team), `{project-root}/_bmad/custom/{skill-name}.user.toml` (user) — apply base → team → user with the same merge rules (scalars override, tables deep-merge, `code`/`id`-keyed arrays merge by key, all other arrays append), describe how the changed fields resolve.
**If the resolver is missing or fails**, fall back: read whichever of the three merge layers exist — `<install-path>/customize.toml` (base), `{project-root}/_bmad/custom/{skill-name}.toml` (team), and `{project-root}/_bmad/custom/{skill-name}.user.toml` (user). Apply base → team → user in order using the same merge rules as the resolver (scalars override, tables deep-merge, `code`/`id`-keyed arrays of tables merge by key, all other arrays append). Describe how the fields the user just changed resolve, and tell them the normal verify path is unavailable in this environment.
**Verify shows override didn't land** (field unchanged, merge conflict, file not picked up): re-enter Step 4 with the verify output as context. Usually wrong field name, wrong merge mode (scalar vs array), or wrong scope.
5. Summarize what changed, where the file lives, how to iterate. Remind the user to commit team overrides.
**If verification shows the override did not take effect** (field unchanged, resolver reports merge conflict, override file not picked up), do not declare success. Explain what the resolver showed, re-enter Step 4 with the verify output as new context — usually the fix is a field name, merge-mode mismatch (e.g. wrote a scalar where the base expects an array), or wrong placement scope.
## Complete when
5. **Close the loop** — summarize what changed, where the file lives, and how to iterate. For team overrides, remind the user to commit the file to git.
- Override file written (or user explicitly aborted).
- User has seen resolver output (or manual fallback merge summary).
- User has acknowledged the summary.
### Completion
Otherwise the skill isn't done — finish or tell the user they're exiting incomplete.
The skill run is complete when all of the following are true:
## When this skill can't help
- The override file exists at the chosen path, or the user explicitly aborted.
- The user has seen the resolver output (or the fallback manual merge summary) showing the intended fields took effect.
- The user has acknowledged the summary from step 6.5 — they know where the file lives and how to iterate.
If any of these is missing, the skill is not done — either finish the remaining part or state explicitly that the user is exiting incomplete.
## When This Skill Can't Help
Say so clearly:
- **Central config** (`{project-root}/_bmad/custom/config.toml` — agent roster, install answers) is not covered by this version. Point the user at the [How to Customize BMad guide](https://docs.bmad-method.org/how-to/customize-bmad/).
- **Changes to step logic, step ordering, or behavior not exposed in `customize.toml`** require a customization feature request or using bmad builder to create a custom skill. Offer to help with either path.
- **Skills without a `customize.toml`** are not customizable — fork is the only path.
## Notes
- Override files are sparse. Everything omitted inherits from the layer below (base → team → user).
- The scanner does not hardcode IDE paths. It scans whichever directory this skill itself was loaded from — that's the same place the user's other skills live in this session. For mixed project-local + user-global setups, use `--extra-root`.
- Full reference on the customization surface, merge rules, and central config lives in the [How to Customize BMad guide](https://docs.bmad-method.org/how-to/customize-bmad/).
- **Central config** (`{project-root}/_bmad/custom/config.toml`) — see the [How to Customize BMad guide](https://docs.bmad-method.org/how-to/customize-bmad/).
- **Step logic, ordering, behavior not in `customize.toml`** — open a feature request, or use `bmad-builder` to create a custom skill. Offer to help with either.
- **Skills without a `customize.toml`** — not customizable.