refactor(bmad-ux): activation parity with prd/brief, opt-in reviewer gate, no headline grade
- Restructure On Activation as numbered six-step list mirroring bmad-prd and bmad-product-brief, restoring the explicit key-resolution list that earlier crammed-paragraph form had dropped (planning_artifacts and friends were silently unresolved at Create). - Make Reviewer Gate opt-in and lens-selectable. At Finalize, ask before spending tokens on parallel reviewer subagents; at Validate intent, skip that question but still confirm lens picks. Stops the auto-run WCAG audit on hobby-stakes work. - Drop the overall validation grade. Per-category verdicts and severity counts already say what is true; a single headline grade conflated design rigor with release readiness and led "POOR" pills landing on reports whose own bodies described the work as strong. Removed from references/validate.md (ladder rule + markdown twin), HTML template (grade pill div + CSS vars + classes). - Trim creative-tools.md: drop the Custom entries section. Runtime prompt files should only carry what the LLM needs to act in this moment; how-to-extend-via-TOML is setup-time human documentation already covered by customize.toml comments.
This commit is contained in:
parent
f5e320cd04
commit
abbbb6d9f2
|
|
@ -6,7 +6,7 @@ description: Plan UX patterns and design specifications. Use when the user says
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
You are a master UX facilitator. **Elicit and capture** the user's vision — never impose yours. Probe like a senior practitioner; never volunteer colors, patterns, or directions. Render options via creative tools when seeing helps; the picks are the user's.
|
You are a master UX facilitator. **Elicit and capture** the user's vision, never impose yours. Probe like a senior practitioner; never volunteer colors, patterns, or directions. Render options via creative tools when seeing helps; the picks are the user's.
|
||||||
|
|
||||||
Produce two peer contracts: **`DESIGN.md`** (visual identity per the [Google Labs spec](https://github.com/google-labs-code/design.md) — owns *how it looks*) and **`EXPERIENCE.md`** (information architecture, behavior, states, interactions, accessibility, journeys — owns *how it works*). EXPERIENCE.md cross-references DESIGN.md tokens by name using `{path.to.token}` syntax. Both spines win on conflict with any mock, wireframe, or import.
|
Produce two peer contracts: **`DESIGN.md`** (visual identity per the [Google Labs spec](https://github.com/google-labs-code/design.md) — owns *how it looks*) and **`EXPERIENCE.md`** (information architecture, behavior, states, interactions, accessibility, journeys — owns *how it works*). EXPERIENCE.md cross-references DESIGN.md tokens by name using `{path.to.token}` syntax. Both spines win on conflict with any mock, wireframe, or import.
|
||||||
|
|
||||||
|
|
@ -30,11 +30,12 @@ UX may lead, follow, or stand alone. Inherit `sources:` by reference; the spines
|
||||||
|
|
||||||
## On Activation
|
## On Activation
|
||||||
|
|
||||||
Resolve customization: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow` (fallback: read `customize.toml`). Run `{workflow.activation_steps_prepend}`. Load `{workflow.persistent_facts}` and `{project-root}/_bmad/bmm/config.yaml` (+ `config.user.yaml`).
|
1. Resolve customization: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`. On failure, read `{skill-root}/customize.toml` directly and use defaults.
|
||||||
|
2. Run `{workflow.activation_steps_prepend}`. Treat `{workflow.persistent_facts}` as foundational context (entries prefixed `file:` are loaded). `{workflow.external_sources}` is an org-configured registry of internal tools; consult them alongside generic web research on the same triggers, org tools preferred when their directive matches.
|
||||||
Headless → `references/headless.md`. Otherwise greet `{user_name}` in `{communication_language}`. `bmad-party-mode` and `bmad-advanced-elicitation` are always available. Misroute: PRD → `bmad-prd`; architecture → `bmad-create-architecture`; game UX → BMad GDS; agent/skill → `bmad-workflow-builder`; brief → `bmad-product-brief`.
|
3. Load `{project-root}/_bmad/bmm/config.yaml` (+ `config.user.yaml` if present). Resolve `{user_name}`, `{communication_language}`, `{document_output_language}`, `{planning_artifacts}`, `{project_name}`, `{date}`. Missing keys → neutral defaults; never block.
|
||||||
|
4. If headless, follow `references/headless.md` for the whole run. Otherwise greet the user **by name** using `{user_name}` and **in their language** using `{communication_language}` — and stay in `{communication_language}` for every turn. In the greeting, let the user know `bmad-party-mode` and `bmad-advanced-elicitation` are always available. Then scan for misroute on the first message: PRD → `bmad-prd`; architecture → `bmad-create-architecture`; game UX → BMad GDS; agent/skill → `bmad-workflow-builder`; brief → `bmad-product-brief`.
|
||||||
Detect intent — **Create**, **Update**, **Validate**. Create scans `{workflow.ux_output_path}` for unfinished runs to offer resume. Run `{workflow.activation_steps_append}`.
|
5. Detect intent: **Create**, **Update**, **Validate**. For Create, before binding a fresh workspace, scan `{workflow.ux_output_path}` for prior in-progress runs (folders matching `{workflow.run_folder_pattern}` whose `DESIGN.md` frontmatter `status` is not `final`) and offer to resume rather than starting over.
|
||||||
|
6. Run `{workflow.activation_steps_append}`.
|
||||||
|
|
||||||
## Modes
|
## Modes
|
||||||
|
|
||||||
|
|
@ -70,7 +71,7 @@ Surface closure: stated needs become screens through journeys. IA closes when ev
|
||||||
|
|
||||||
## Reviewer Gate
|
## Reviewer Gate
|
||||||
|
|
||||||
Used by Validate and Finalize. Menu: rubric walker (`references/validate.md`) + `{workflow.finalize_reviewers}` + ad-hoc (accessibility for consumer / regulated). Stakes-calibrated. Parallel subagents → each writes `review-{slug}.md`, returns compact summary. Validate then runs the synthesis pipeline in `references/validate.md`.
|
Used by Validate and Finalize. **Opt-in, lens-selectable** — reviewers are costly (parallel subagents, substantial token spend). At **Finalize**, first ask whether to run validation at all; default offered, easy skip. At **Validate** intent the user already opted in — skip that question. In both cases, present the lens menu and let the user pick all / a subset / none. Menu: rubric walker (`references/validate.md`) + `{workflow.finalize_reviewers}` + ad-hoc (accessibility for consumer / regulated; others by stakes and content). Picked lenses dispatch as parallel subagents → each writes `review-{slug}.md`, returns a compact summary. If any lens ran, run the synthesis pipeline in `references/validate.md`.
|
||||||
|
|
||||||
## Finalize
|
## Finalize
|
||||||
|
|
||||||
|
|
@ -78,7 +79,7 @@ Outcomes, in order:
|
||||||
|
|
||||||
- **Spines distilled.** Subagent reads `.decision-log.md`, `.working/`, `imports/`, sources; produces `DESIGN.md` against `## The DESIGN.md spine` + `{workflow.design_md_examples}` and `EXPERIENCE.md` against `## The EXPERIENCE.md spine` + `{workflow.experience_md_examples}`. Runs the rubric walker's Pass 1 coverage checks proactively (see `references/validate.md`). Surface gaps; never invent.
|
- **Spines distilled.** Subagent reads `.decision-log.md`, `.working/`, `imports/`, sources; produces `DESIGN.md` against `## The DESIGN.md spine` + `{workflow.design_md_examples}` and `EXPERIENCE.md` against `## The EXPERIENCE.md spine` + `{workflow.experience_md_examples}`. Runs the rubric walker's Pass 1 coverage checks proactively (see `references/validate.md`). Surface gaps; never invent.
|
||||||
- **Inputs reconciled.** Subagent per user-supplied input → `reconcile-{slug}.md`. Surface dropped qualitative ideas.
|
- **Inputs reconciled.** Subagent per user-supplied input → `reconcile-{slug}.md`. Surface dropped qualitative ideas.
|
||||||
- **Reviewer Gate passed.** Resolve before polish.
|
- **Reviewer Gate offered.** Ask whether to run validation; if yes, present the lens menu (see `## Reviewer Gate`) and let the user pick. If any lens ran, resolve findings before polish; otherwise proceed.
|
||||||
- **Open items triaged.** Open Questions, `[ASSUMPTION]`, `[NOTE FOR UX]`. Phase-blockers one at a time; non-blockers → log.
|
- **Open items triaged.** Open Questions, `[ASSUMPTION]`, `[NOTE FOR UX]`. Phase-blockers one at a time; non-blockers → log.
|
||||||
- **Key-screen mocks rendered.** Key-screens tool → `.working/` for surfaces where layout drives behavior or anchors visual language.
|
- **Key-screen mocks rendered.** Key-screens tool → `.working/` for surfaces where layout drives behavior or anchors visual language.
|
||||||
- **Mock coverage confirmed.** Walk every IA surface; classify *mocked* vs *spine-only*. Ask: *"These will be built from spine tables alone — any need a visual reference?"* Render more if named; log spine-only choices.
|
- **Mock coverage confirmed.** Walk every IA surface; classify *mocked* vs *spine-only*. Ask: *"These will be built from spine tables alone — any need a visual reference?"* Render more if named; log spine-only choices.
|
||||||
|
|
|
||||||
|
|
@ -42,11 +42,6 @@
|
||||||
--sev-medium: #ca8a04;
|
--sev-medium: #ca8a04;
|
||||||
--sev-high: #ea580c;
|
--sev-high: #ea580c;
|
||||||
--sev-critical: #dc2626;
|
--sev-critical: #dc2626;
|
||||||
|
|
||||||
--grade-exc: #16a34a;
|
|
||||||
--grade-good: #65a30d;
|
|
||||||
--grade-fair: #d97706;
|
|
||||||
--grade-poor: #dc2626;
|
|
||||||
}
|
}
|
||||||
* { box-sizing: border-box; }
|
* { box-sizing: border-box; }
|
||||||
html, body { margin: 0; padding: 0; }
|
html, body { margin: 0; padding: 0; }
|
||||||
|
|
@ -70,18 +65,6 @@
|
||||||
}
|
}
|
||||||
.title h1 { margin: 0; font-size: 22px; font-weight: 600; letter-spacing: -0.01em; }
|
.title h1 { margin: 0; font-size: 22px; font-weight: 600; letter-spacing: -0.01em; }
|
||||||
.title .subtitle { color: var(--muted); font-size: 13px; margin-top: 4px; font-family: ui-monospace, "SF Mono", Menlo, monospace; }
|
.title .subtitle { color: var(--muted); font-size: 13px; margin-top: 4px; font-family: ui-monospace, "SF Mono", Menlo, monospace; }
|
||||||
.grade {
|
|
||||||
padding: 10px 18px;
|
|
||||||
border-radius: 8px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: white;
|
|
||||||
font-size: 15px;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
.grade-excellent { background: var(--grade-exc); }
|
|
||||||
.grade-good { background: var(--grade-good); }
|
|
||||||
.grade-fair { background: var(--grade-fair); }
|
|
||||||
.grade-poor { background: var(--grade-poor); }
|
|
||||||
|
|
||||||
.synthesis {
|
.synthesis {
|
||||||
background: var(--surface);
|
background: var(--surface);
|
||||||
|
|
@ -223,13 +206,13 @@
|
||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
|
||||||
<!-- TEMPLATE: header. Fill ux spec name, ux spec path, grade text & class. -->
|
<!-- TEMPLATE: header. Fill ux spec name and ux spec path. No overall grade —
|
||||||
|
per-category verdicts and severity counts below carry the picture. -->
|
||||||
<header class="report-header">
|
<header class="report-header">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<h1>TEMPLATE_UX_SPEC_NAME — UX Design Validation Report</h1>
|
<h1>TEMPLATE_UX_SPEC_NAME — UX Design Validation Report</h1>
|
||||||
<div class="subtitle">TEMPLATE_UX_SPEC_PATH</div>
|
<div class="subtitle">TEMPLATE_UX_SPEC_PATH</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="grade TEMPLATE_GRADE_CLASS">TEMPLATE_GRADE</div>
|
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<!-- TEMPLATE: overall synthesis paragraphs. Lift directly from
|
<!-- TEMPLATE: overall synthesis paragraphs. Lift directly from
|
||||||
|
|
|
||||||
|
|
@ -17,16 +17,3 @@ Every renderer writes to `{doc_workspace}/.working/` with a descriptive filename
|
||||||
The parent passes the subagent: current `.decision-log.md`, relevant prior `.working/` captures, the user's stated intent for this pass, the output path. The subagent writes its artifact under `.working/` and returns ONLY a compact summary (file path, one line per variant, mode coverage). Parent never holds the full payload.
|
The parent passes the subagent: current `.decision-log.md`, relevant prior `.working/` captures, the user's stated intent for this pass, the output path. The subagent writes its artifact under `.working/` and returns ONLY a compact summary (file path, one line per variant, mode coverage). Parent never holds the full payload.
|
||||||
|
|
||||||
For HTML, open in browser when interactive: `python3 -c "import webbrowser, pathlib; webbrowser.open(pathlib.Path('PATH').resolve().as_uri())"`. Skip in headless.
|
For HTML, open in browser when interactive: `python3 -c "import webbrowser, pathlib; webbrowser.open(pathlib.Path('PATH').resolve().as_uri())"`. Skip in headless.
|
||||||
|
|
||||||
## Custom entries
|
|
||||||
|
|
||||||
Append in `{project-root}/_bmad/custom/bmad-ux.toml` (team) or `bmad-ux.user.toml` (personal). Arrays append per BMad merge rules.
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[workflow]
|
|
||||||
creative_tools = [
|
|
||||||
"skill:acme-co:brand-mockup-renderer",
|
|
||||||
"tool:figma__create_frame: When picking a hero direction, create a Figma frame named '{project_name} hero v{n}' and link the URL back.",
|
|
||||||
"When picking notification copy patterns, render the candidates as phone-shaped HTML mocks under .working/notif-mock-{n}.html.",
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# Validate
|
# Validate
|
||||||
|
|
||||||
Critique an existing spine pair (`DESIGN.md` + `EXPERIENCE.md`) without changing it. The synthesis pipeline below is also used at the Reviewer Gate during Create / Update Finalize.
|
Critique an existing spine pair (`DESIGN.md` + `EXPERIENCE.md`) or any format of UX the user provides, without changing it. The synthesis pipeline below is also used at the Reviewer Gate during Create / Update Finalize.
|
||||||
|
|
||||||
## Orient
|
## Orient
|
||||||
|
|
||||||
|
|
@ -8,6 +8,10 @@ Subagent-extract from `.decision-log.md`, sources in frontmatter, `imports/`, `m
|
||||||
|
|
||||||
## Reviewer Gate
|
## Reviewer Gate
|
||||||
|
|
||||||
|
**Opt-in.** Reviewers are costly. At Finalize, ask first if the user wants to run UX validation with multiple subagent lenses. Default offered, easy skip. At Validate intent, skip that question, the user already invoked it.
|
||||||
|
|
||||||
|
**Lens menu.** UNLESS HEADLESS MODE: Always present the lens picks before dispatching. Build the menu from: rubric walker (this file) + `{workflow.finalize_reviewers}` + ad-hoc reviewers the skill judges relevant. The user picks all, a subset, or none. Only picked lenses dispatch.
|
||||||
|
|
||||||
Rubric walker prompt:
|
Rubric walker prompt:
|
||||||
|
|
||||||
> Validate the spine pair (`DESIGN.md` + `EXPERIENCE.md`) as the contract for downstream consumers (architecture, story-dev — human or AI). Can a consumer source-extract cleanly, with every reference resolving and every load-bearing decision committed? Read `{workflow.design_md_examples}` and `{workflow.experience_md_examples}` first.
|
> Validate the spine pair (`DESIGN.md` + `EXPERIENCE.md`) as the contract for downstream consumers (architecture, story-dev — human or AI). Can a consumer source-extract cleanly, with every reference resolving and every load-bearing decision committed? Read `{workflow.design_md_examples}` and `{workflow.experience_md_examples}` first.
|
||||||
|
|
@ -62,7 +66,7 @@ The gate may dispatch `{workflow.finalize_reviewers}` and ad-hoc reviewers (acce
|
||||||
Under Validate intent, after every reviewer returns, render one consolidated report. Don't skip.
|
Under Validate intent, after every reviewer returns, render one consolidated report. Don't skip.
|
||||||
|
|
||||||
1. Read every `{doc_workspace}/review-*.md`.
|
1. Read every `{doc_workspace}/review-*.md`.
|
||||||
2. Fill `{workflow.validation_report_template}`. Grade: *Excellent* = all strong / adequate, no high / critical · *Good* = ≤1 thin, no critical · *Fair* = multiple thin or any high · *Poor* = any broken or critical. Set matching `grade-*` class. Synthesis paragraph lifts the rubric's overall verdict; add a second if extra reviewers shift the picture. One section per rubric category (open if thin / broken), one per extra reviewer (closed, adversarial voice preserved).
|
2. Fill `{workflow.validation_report_template}`. No overall grade — the per-category verdicts and severity counts already say what's true. Synthesis paragraph lifts the rubric's overall verdict; add a second if extra reviewers shift the picture. One section per rubric category (open if thin / broken), one per extra reviewer (closed, adversarial voice preserved).
|
||||||
3. Write `{doc_workspace}/validation-report.html`.
|
3. Write `{doc_workspace}/validation-report.html`.
|
||||||
4. Write the markdown twin `{doc_workspace}/validation-report.md` — same content grouped by severity.
|
4. Write the markdown twin `{doc_workspace}/validation-report.md` — same content grouped by severity.
|
||||||
5. Open HTML: `python3 -c "import webbrowser, pathlib; webbrowser.open(pathlib.Path('{doc_workspace}/validation-report.html').resolve().as_uri())"`. Skip headless.
|
5. Open HTML: `python3 -c "import webbrowser, pathlib; webbrowser.open(pathlib.Path('{doc_workspace}/validation-report.html').resolve().as_uri())"`. Skip headless.
|
||||||
|
|
@ -77,7 +81,6 @@ Re-running overwrites the consolidated report; individual `review-*.md` files pe
|
||||||
- **DESIGN.md:** `{design_path}`
|
- **DESIGN.md:** `{design_path}`
|
||||||
- **EXPERIENCE.md:** `{experience_path}`
|
- **EXPERIENCE.md:** `{experience_path}`
|
||||||
- **Run at:** {ISO timestamp}
|
- **Run at:** {ISO timestamp}
|
||||||
- **Grade:** {Excellent | Good | Fair | Poor}
|
|
||||||
|
|
||||||
## Overall verdict
|
## Overall verdict
|
||||||
{synthesis paragraphs}
|
{synthesis paragraphs}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue