Resolve workflow customization. Run:
python3 {project-root}/_bmad/scripts/resolve_customization.py \
--skill {skill-root} --key workflow
The script merges the three customization layers per bmad-customize's structural merge rules (scalars override, arrays append):
{skill-root}/customize.toml — bundled defaults
_bmad/custom/<skill-name>.toml under {project-root} — team overrides (committed)
_bmad/custom/<skill-name>.user.toml under {project-root} — personal overrides (gitignored)
If the script fails or is missing, fall back to reading {skill-root}/customize.toml directly — the bundled defaults are an empty string for each path scalar.
Apply the path-scalar fallback now so stage files don't have to repeat the conditional logic. For each of the three scalars, if the merged value is empty or absent, use the bundled default:
{skillTemplatePath} ← workflow.skill_template_path if non-empty, else assets/skill-template.md
{registryResolutionPath} ← workflow.registry_resolution_path if non-empty, else references/registry-resolution.md
{batchOutputPath} ← workflow.batch_output_path if non-empty, else {skills_output_folder}/_batch/
{onCompleteCommand} ← workflow.on_complete if non-empty, else empty (no-op — step 6 §3 skips the hook invocation entirely)
Stash all four as workflow-context variables. Stage files reference {skillTemplatePath} / {registryResolutionPath} / {batchOutputPath} / {onCompleteCommand} directly — no conditional at the usage site. Empty-string overrides cleanly fall through to the bundled default; non-empty values let orgs swap in house-style copies (custom template, registry chain, batch output dir) or wire in a post-completion hook (git-add, register, notify) without forking the skill.
Apply the array surfaces so the declared overrides are not silent no-ops: execute each entry in workflow.activation_steps_prepend in order now; treat every entry in workflow.persistent_facts as standing context for the whole run (file:-prefixed entries are paths or globs whose contents load as facts — the bundled default loads any project-context.md); then, after activation completes and before the first stage runs, execute each entry in workflow.activation_steps_append in order.