From 65d8f39de36ed9d1de47b1fdb6201eb3c55628eb Mon Sep 17 00:00:00 2001 From: Brian Madison Date: Sun, 30 Aug 2026 23:06:15 -0500 Subject: [PATCH] fix(builders): pass --project-root to the customization resolver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Core's resolve_customization.py inferred the project root when the flag was absent, and for a skill installed under the user's home that inference walked up to ~ — where a user-level install's ~/_bmad made home look like the project. Team overrides in the real project were silently ignored: no error, no warning, just shipped defaults. The resolver itself is fixed in BMAD-METHOD#2802. This is the hardening half, and it matters more here than in the other modules: three of the six files are the generator templates the agent and workflow builders stamp into every new skill, so the omission was seeding itself into everything anyone builds from here on. The builders' own activation steps and the make-a-skill-customizable recipe are covered too. The recipe runs from the project directory with a relative path, so it passes "$PWD" rather than the {project-root} placeholder the templates use. No behaviour change where the inference already landed correctly. The flag has always existed, so new skill text works against an old resolver and old text against the new one. Refs bmad-code-org/BMAD-METHOD#2796 Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01L8Hyqmp2giAVgEAnB49zEQ --- docs/how-to/make-a-skill-customizable.md | 1 + skills/bmad-agent-builder/SKILL.md | 2 +- skills/bmad-agent-builder/assets/SKILL-template-bootloader.md | 2 +- skills/bmad-agent-builder/assets/SKILL-template.md | 2 +- skills/bmad-workflow-builder/SKILL.md | 2 +- skills/bmad-workflow-builder/assets/SKILL-template.md | 2 +- 6 files changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/how-to/make-a-skill-customizable.md b/docs/how-to/make-a-skill-customizable.md index 41a0645..5816caf 100644 --- a/docs/how-to/make-a-skill-customizable.md +++ b/docs/how-to/make-a-skill-customizable.md @@ -119,6 +119,7 @@ Run the resolver directly to confirm your override takes effect: ```bash uv run _bmad/scripts/resolve_customization.py \ --skill /path/to/built/skill \ + --project-root "$PWD" \ --key workflow.on_complete ``` diff --git a/skills/bmad-agent-builder/SKILL.md b/skills/bmad-agent-builder/SKILL.md index 38758be..8e7be2a 100644 --- a/skills/bmad-agent-builder/SKILL.md +++ b/skills/bmad-agent-builder/SKILL.md @@ -27,7 +27,7 @@ The builder produces agents along one gradient surfaced as feature decisions, no ## On Activation -1. **Resolve customization.** Run `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key agent` and apply the resolved `{agent.*}` values throughout the session. On failure, read `{skill-root}/customize.toml` directly and use defaults. Then execute each entry in `{agent.activation_steps_prepend}` in order, and treat every entry in `{agent.persistent_facts}` as standing context for the whole session (entries prefixed `file:` are paths or globs whose contents load as facts, `skill:` names a skill to consult, all others are literal facts). +1. **Resolve customization.** Run `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --project-root {project-root} --key agent` and apply the resolved `{agent.*}` values throughout the session. On failure, read `{skill-root}/customize.toml` directly and use defaults. Then execute each entry in `{agent.activation_steps_prepend}` in order, and treat every entry in `{agent.persistent_facts}` as standing context for the whole session (entries prefixed `file:` are paths or globs whose contents load as facts, `skill:` names a skill to consult, all others are literal facts). 2. **Detect intent.** If `--headless` or `-H` is present, set `{headless_mode}=true` for every sub-prompt; this makes the builder non-interactive and is not the Pulse Mode a built autonomous agent runs at its own runtime. Otherwise read the invocation for whether the user wants to Create, Edit, or Analyze, and which agent they mean. diff --git a/skills/bmad-agent-builder/assets/SKILL-template-bootloader.md b/skills/bmad-agent-builder/assets/SKILL-template-bootloader.md index ef8115c..e961fd0 100644 --- a/skills/bmad-agent-builder/assets/SKILL-template-bootloader.md +++ b/skills/bmad-agent-builder/assets/SKILL-template-bootloader.md @@ -55,7 +55,7 @@ The full discipline (what goes where, the two-tier flow from session log to MEMO {if-customizable} ### Resolve the Agent Block -Run: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key agent` +Run: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --project-root {project-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. diff --git a/skills/bmad-agent-builder/assets/SKILL-template.md b/skills/bmad-agent-builder/assets/SKILL-template.md index 12bd12e..3f086f1 100644 --- a/skills/bmad-agent-builder/assets/SKILL-template.md +++ b/skills/bmad-agent-builder/assets/SKILL-template.md @@ -42,7 +42,7 @@ description: { skill-description } # [4-6 word summary]. [trigger phrases] {if-customizable} ### Step 1: Resolve the Agent Block -Run: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key agent` +Run: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --project-root {project-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. diff --git a/skills/bmad-workflow-builder/SKILL.md b/skills/bmad-workflow-builder/SKILL.md index 0f4cfc4..e1bfc8b 100644 --- a/skills/bmad-workflow-builder/SKILL.md +++ b/skills/bmad-workflow-builder/SKILL.md @@ -17,7 +17,7 @@ Act as a skill-building partner who turns a half-formed idea in the user's head ## On Activation -1. **Resolve customization.** Run `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow` and apply the resolved `{workflow.*}` values throughout the session. On failure, read `{skill-root}/customize.toml` directly and use defaults. Then execute each entry in `{workflow.activation_steps_prepend}` in order, and treat every entry in `{workflow.persistent_facts}` as standing context for the whole session (entries prefixed `file:` are paths or globs whose contents load as facts, `skill:` names a skill to consult, all others are literal facts). +1. **Resolve customization.** Run `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --project-root {project-root} --key workflow` and apply the resolved `{workflow.*}` values throughout the session. On failure, read `{skill-root}/customize.toml` directly and use defaults. Then execute each entry in `{workflow.activation_steps_prepend}` in order, and treat every entry in `{workflow.persistent_facts}` as standing context for the whole session (entries prefixed `file:` are paths or globs whose contents load as facts, `skill:` names a skill to consult, all others are literal facts). 2. **Detect intent.** If `--headless` or `-H` is present, set `{headless_mode}=true` for every sub-prompt. Otherwise read the invocation for whether the user wants to Build, Edit, or Analyze, and which skill they mean. diff --git a/skills/bmad-workflow-builder/assets/SKILL-template.md b/skills/bmad-workflow-builder/assets/SKILL-template.md index 183cb99..71b5edf 100644 --- a/skills/bmad-workflow-builder/assets/SKILL-template.md +++ b/skills/bmad-workflow-builder/assets/SKILL-template.md @@ -49,7 +49,7 @@ Write it once; do not restate it lower down.} 2. Resume check. Look for an existing `.memlog.md` in the run folder. If one is found, read it once to rebuild state and continue append-only; otherwise initialize a new memlog with `uv run {project-root}/_bmad/scripts/memlog.py init --path /.memlog.md`. -3. Resolve the `workflow` block: run `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`. If the script fails, merge these three files yourself in base → team → user order — `{skill-root}/customize.toml`, `{project-root}/_bmad/custom/{skill-name}.toml`, `{project-root}/_bmad/custom/{skill-name}.user.toml` — where scalars override, tables deep-merge, arrays of tables keyed by `code`/`id` replace matching entries and append new ones, and all other arrays append. Reference resolved values as `{workflow.}` everywhere below; never hardcode a path beside a declared scalar. +3. Resolve the `workflow` block: run `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --project-root {project-root} --key workflow`. If the script fails, merge these three files yourself in base → team → user order — `{skill-root}/customize.toml`, `{project-root}/_bmad/custom/{skill-name}.toml`, `{project-root}/_bmad/custom/{skill-name}.user.toml` — where scalars override, tables deep-merge, arrays of tables keyed by `code`/`id` replace matching entries and append new ones, and all other arrays append. Reference resolved values as `{workflow.}` everywhere below; never hardcode a path beside a declared scalar. ## {Body}