diff --git a/AGENTS.md b/AGENTS.md index 7f378a2d..615106a3 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -17,6 +17,7 @@ This repository contains reusable AI coding workflows that can be installed glob - **implement** — Story-to-code workflow (ingest, plan, revise, code, validate, publish, respond) - **kcs** — KCS Solution article workflow (gather, draft, validate, handoff) - **prd** — Requirements-to-PRD workflow (ingest, clarify, draft, revise, publish, respond) +- **ux-design** — UX design workflow (ingest, research, prototype, evaluate, handoff, revise, publish, respond) - **rebase-stack** — Rebase a stacked-branch chain with conflict guidance, per-branch validation, and push (start, continue, validate, push) - **sizing** — Pre-cycle Feature sizing with T-shirt sizes and team effort breakdowns (ingest, assess, apply) - **skill-reviewer** — Meta-workflow that audits AI skill directories @@ -69,7 +70,7 @@ _shared/ validation-gate.md # Pre-commit build/test/lint discovery gate (used by bugfix) ``` -Recipes are self-contained, parameterized procedures that workflows reference via relative path (e.g., `../../_shared/recipes/self-review-gate.md` from `skills/`). Workflows may also reference shared files from `guidelines.md`, `templates/`, `prompts/`, `scripts/`, and other behavioral markdown — all such references count as consumers for the shared-file cascade (see Workflow Versioning). The **prd** and **design** workflows use the provenance recipes on `/draft`, `/revise`, `/respond` (capture) and `/publish` plus docs-sync paths (render). See `_shared/provenance-schema.md` for the published footer format. +Recipes are self-contained, parameterized procedures that workflows reference via relative path (e.g., `../../_shared/recipes/self-review-gate.md` from `skills/`). Workflows may also reference shared files from `guidelines.md`, `templates/`, `prompts/`, `scripts/`, and other behavioral markdown — all such references count as consumers for the shared-file cascade (see Workflow Versioning). The **prd** and **design** workflows use the provenance recipes on `/draft`, `/revise`, `/respond` (capture) and `/publish` plus docs-sync paths (render). The **ux-design** workflow uses them on `/handoff`, `/revise`, `/respond` (capture) and `/publish` plus `/respond` (render). See `_shared/provenance-schema.md` for the published footer format. ### File Reference Conventions @@ -183,6 +184,7 @@ ai-workflows/ │ ├── prompts/ │ └── scripts/ ├── triage/ +├── ux-design/ ├── install.sh # Installer with auto-discovery ├── uninstall.sh # Removal script ├── AGENTS.md # AI assistant guidance (this file) diff --git a/README.md b/README.md index b6b5dbd7..8e4dc622 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,9 @@ Reusable AI coding workflows a team member can install globally or per-project, - **Skill Reviewer** -- Meta-workflow that audits AI skill directories against eight quality dimensions. See [skill-reviewer/README.md](skill-reviewer/README.md). +- **UX Design** -- UX design workflow: ingest a feature request, conduct user research, generate prototypes, run heuristic evaluation, and produce a validated design handoff for the `ui-design` workflow. + See [ux-design/README.md](ux-design/README.md). + ## How It Works Each workflow is a directory with a `SKILL.md` (the mandatory entry point), optional phase skills under `skills/`, and optional command wrappers under `commands/` -- all plain markdown, no IDE-specific syntax. Some workflows also include a `skills/controller.md` for phase dispatch, but this is an optional pattern. The installer auto-discovers every directory that contains a `SKILL.md`. diff --git a/_shared/recipes/capture-provenance-event.md b/_shared/recipes/capture-provenance-event.md index 236a6e6f..a1e94006 100644 --- a/_shared/recipes/capture-provenance-event.md +++ b/_shared/recipes/capture-provenance-event.md @@ -1,6 +1,6 @@ --- name: capture-provenance-event -version: 0.1.1 +version: 0.1.2 --- # Recipe: Capture Provenance Event @@ -11,9 +11,9 @@ phase mutates the planning document. See `../provenance-schema.md`. | Parameter | Required | Description | |-----------|----------|-------------| -| WORKFLOW | Yes | `prd` or `design` | +| WORKFLOW | Yes | `prd`, `design`, or `ux-design` | | ISSUE_KEY | Yes | Full Jira issue key including project prefix (e.g., `PROJ-1234`, not `1234`) | -| PHASE | Yes | `draft`, `revise`, or `respond` | +| PHASE | Yes | `draft`, `revise`, or `respond` (ux-design also uses `handoff`) | | AUTHORING_MODE | Yes | `skill` (default for phase skills) or `manual` | ## Procedure diff --git a/_shared/recipes/render-provenance-footer.md b/_shared/recipes/render-provenance-footer.md index de7154d7..e55256a3 100644 --- a/_shared/recipes/render-provenance-footer.md +++ b/_shared/recipes/render-provenance-footer.md @@ -1,6 +1,6 @@ --- name: render-provenance-footer -version: 0.1.1 +version: 0.1.2 --- # Recipe: Render Provenance Footer @@ -11,7 +11,7 @@ Render the durable `## Provenance` footer into a docs-repo markdown file before | Parameter | Required | Description | |-----------|----------|-------------| -| WORKFLOW | Yes | `prd` or `design` | +| WORKFLOW | Yes | `prd`, `design`, or `ux-design` | | ISSUE_KEY | Yes | Full Jira issue key including project prefix (e.g., `PROJ-1234`, not `1234`) | | TARGET_FILE | Yes | Absolute path to the docs-repo file about to be committed | | ALLOW_MISSING | No | Set to `yes` only after the user explicitly declines provenance | diff --git a/_shared/scripts/provenance.py b/_shared/scripts/provenance.py index 0a292c85..09c04b4f 100755 --- a/_shared/scripts/provenance.py +++ b/_shared/scripts/provenance.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -"""Capture and render provenance for prd/design planning document workflows. +"""Capture and render provenance for prd/design/ux-design planning documents. Exit codes: 0: Success (capture or render completed) @@ -23,9 +23,29 @@ WORKFLOW_DOCS = { "prd": "03-prd.md", "design": "03-design.md", + "ux-design": "05-handoff.md", } -AUTHORING_PHASES = frozenset({"draft", "revise", "respond", "manual-edit"}) +# The phase that legitimately originates each workflow's document. prd/design +# originate from a template-checked /draft; ux-design assembles its handoff spec +# in /handoff (there is no template-from-origin step), so `handoff` is its +# origin. A first event other than this marks the phase history as untracked. +ORIGIN_PHASE = { + "prd": "draft", + "design": "draft", + "ux-design": "handoff", +} + +AUTHORING_PHASES = frozenset( + {"draft", "handoff", "revise", "respond", "manual-edit"} +) + +# Per-workflow valid phases (for validation in capture_event) +WORKFLOW_PHASES = { + "prd": frozenset({"draft", "revise", "respond", "manual-edit", "commit"}), + "design": frozenset({"draft", "revise", "respond", "manual-edit", "commit"}), + "ux-design": frozenset({"handoff", "revise", "respond", "manual-edit", "commit"}), +} DRIFT_FIELDS = ( "workflow_version", @@ -56,10 +76,18 @@ COMMIT_ONLY_NOTE = ( "> Authoring phases not recorded this session (commit-time snapshot only)." ) -ORIGIN_UNTRACKED_NOTE = ( - "> This document's phase history does not include an initial /draft — " - "structure was not verified against the template from origin." -) +def origin_untracked_note(workflow: str | None = None) -> str: + origin = ORIGIN_PHASE.get(workflow, "draft") + # ux-design has no template step; its /handoff assembles from scratch + if workflow == "ux-design": + return ( + f"> This document's phase history does not include an initial /{origin} — " + "structure was not verified from origin." + ) + return ( + f"> This document's phase history does not include an initial /{origin} — " + "structure was not verified against the template from origin." + ) def repo_root(start: Path) -> Path | None: @@ -260,12 +288,15 @@ def provenance_kind(events: list[dict[str, Any]]) -> str: return "session" -def origin_untracked(events: list[dict[str, Any]]) -> bool: +def origin_untracked( + events: list[dict[str, Any]], workflow: str | None = None +) -> bool: if not events: return False if provenance_kind(events) == "commit_only": return False - return events[0].get("phase") != "draft" + origin = ORIGIN_PHASE.get(workflow, "draft") + return events[0].get("phase") != origin def capture_event( @@ -274,6 +305,14 @@ def capture_event( phase: str, authoring_mode: str, ) -> None: + # Validate phase is valid for this workflow + valid_phases = WORKFLOW_PHASES.get(workflow) + if valid_phases and phase not in valid_phases: + raise ValueError( + f"Phase '{phase}' is not valid for workflow '{workflow}'. " + f"Valid phases: {', '.join(sorted(valid_phases))}" + ) + ai_root = ai_workflows_root() ws_root = workspace_root() path = provenance_path(workflow, issue) @@ -352,6 +391,7 @@ def build_metrics_payload(data: dict[str, Any]) -> dict[str, Any]: last = events[-1] if events else {} drift = data.get("drift", {}) kind = provenance_kind(events) + workflow = data.get("workflow", "unknown") return { "schema_version": 1, "provenance_kind": kind, @@ -368,7 +408,7 @@ def build_metrics_payload(data: dict[str, Any]) -> dict[str, Any]: {event.get("authoring_mode", "skill") for event in events} ), "context_changed": drift.get("context_changed", False), - "origin_untracked": origin_untracked(events), + "origin_untracked": origin_untracked(events, workflow), } @@ -403,9 +443,9 @@ def build_footer(data: dict[str, Any]) -> str: if len(phases) > 1: lines.append(f"Phases: {', '.join(phases)}") - if origin_untracked(events): + if origin_untracked(events, workflow): lines.append("") - lines.append(ORIGIN_UNTRACKED_NOTE) + lines.append(origin_untracked_note(workflow)) lines.append("") lines.append(metrics_comment) @@ -491,7 +531,9 @@ def render_footer(workflow: str, issue: str, target: Path, *, allow_missing: boo def main() -> int: - parser = argparse.ArgumentParser(description="PRD/design provenance helper") + parser = argparse.ArgumentParser( + description="PRD/design/ux-design provenance helper" + ) sub = parser.add_subparsers(dest="command", required=True) capture = sub.add_parser("capture", help="Append a provenance event") @@ -500,7 +542,7 @@ def main() -> int: capture.add_argument( "--phase", required=True, - choices=["draft", "revise", "respond", "manual-edit", "commit"], + choices=["draft", "handoff", "revise", "respond", "manual-edit", "commit"], ) capture.add_argument( "--authoring-mode", diff --git a/_shared/scripts/test_provenance.py b/_shared/scripts/test_provenance.py index 7086d17f..bad41aec 100644 --- a/_shared/scripts/test_provenance.py +++ b/_shared/scripts/test_provenance.py @@ -107,6 +107,46 @@ def test_origin_untracked_false_when_all_events_are_commit(self) -> None: self.assertEqual(provenance.provenance_kind(events), "commit_only") self.assertFalse(provenance.origin_untracked(events)) + def test_origin_untracked_false_for_ux_design_handoff_first(self) -> None: + # ux-design originates its document in /handoff (not /draft), so a + # handoff-first log is a tracked origin and must NOT be flagged. + events = [{"phase": "handoff"}, {"phase": "revise"}] + self.assertFalse(provenance.origin_untracked(events, "ux-design")) + + def test_origin_untracked_true_for_ux_design_revise_first(self) -> None: + # ux-design entered at /revise with no prior /handoff is untracked. + events = [{"phase": "revise"}] + self.assertTrue(provenance.origin_untracked(events, "ux-design")) + + def test_origin_untracked_true_for_prd_handoff_first(self) -> None: + # 'handoff' is not prd's origin phase, so a handoff-first prd log is + # still untracked -- the per-workflow origin must not leak across. + events = [{"phase": "handoff"}] + self.assertTrue(provenance.origin_untracked(events, "prd")) + + def test_origin_untracked_note_names_workflow_origin_phase(self) -> None: + ux_note = provenance.origin_untracked_note("ux-design") + self.assertIn("/handoff", ux_note) + # ux-design has no template step, so note should not mention "template" + self.assertNotIn("template", ux_note) + + prd_note = provenance.origin_untracked_note("prd") + self.assertIn("/draft", prd_note) + self.assertIn("template", prd_note) # prd/design DO have templates + + self.assertIn("/draft", provenance.origin_untracked_note()) + + def test_workflow_phase_validation_rejects_invalid_combinations(self) -> None: + # prd/design don't have 'handoff' phase + with self.assertRaises(ValueError) as cm: + provenance.capture_event("prd", "TEST-123", "handoff", "skill") + self.assertIn("not valid for workflow 'prd'", str(cm.exception)) + + # ux-design doesn't have 'draft' phase + with self.assertRaises(ValueError) as cm: + provenance.capture_event("ux-design", "TEST-456", "draft", "skill") + self.assertIn("not valid for workflow 'ux-design'", str(cm.exception)) + def test_build_metrics_payload_flags_origin_untracked(self) -> None: data = { "workflow": "prd", diff --git a/design/SKILL.md b/design/SKILL.md index d75938a3..fdc4968f 100644 --- a/design/SKILL.md +++ b/design/SKILL.md @@ -1,6 +1,6 @@ --- name: design -version: 0.9.0 +version: 0.9.1 description: >- Design-and-decompose workflow that takes a PRD, researches the problem space, drafts a technical design document with a requirement-anchored testplan, diff --git a/install.sh b/install.sh index 1bc2c953..641049c7 100755 --- a/install.sh +++ b/install.sh @@ -131,6 +131,70 @@ ensure_repo_linked() { echo " Linked $INSTALL_DIR -> $REPO_DIR" } +UXD_REPO="https://github.com/rh-uxd/ai-helpers.git" +UXD_SHA="ad44b9c92c89730da5191487d0ff82af09b41366" +UXD_DIR="${HOME}/.uxd-ai-skills" +UXD_PLUGINS=(uxd-workshop) + +# Install UXD AI Skills via git clone + symlinks (AI-agnostic; works for all +# tools). Called at the end of each install target when ux-design is in scope. +install_uxd_skills() { + local skills_dir="$1" + + # Only install if ux-design is in the workflow set being installed + local has_ux_design=false + for wf in "${WORKFLOWS[@]}"; do + [[ "$wf" == "ux-design" ]] && has_ux_design=true + done + "$has_ux_design" || return 0 + + if [[ ! -d "$UXD_DIR" ]]; then + echo " Cloning UXD AI Skills repo (${UXD_SHA:0:7})..." + git clone "$UXD_REPO" "$UXD_DIR" 2>/dev/null || { + echo " Error: could not clone UXD AI Skills repo — ux-design workflow requires it" >&2 + echo " Check network access to github.com and re-run install." >&2 + return 1 + } + git -C "$UXD_DIR" checkout "$UXD_SHA" 2>/dev/null || { + echo " Error: could not check out UXD AI Skills commit ${UXD_SHA:0:7}" >&2 + return 1 + } + else + # Existing install: make sure it is on the pinned SHA. Fetch first in case + # the local clone predates the pinned commit; a fetch failure is non-fatal + # only when the commit is already present locally. + if ! git -C "$UXD_DIR" cat-file -e "${UXD_SHA}^{commit}" 2>/dev/null; then + echo " Fetching UXD AI Skills updates (${UXD_SHA:0:7})..." + git -C "$UXD_DIR" fetch origin 2>/dev/null || { + echo " Error: could not fetch UXD AI Skills commit ${UXD_SHA:0:7}" >&2 + echo " Check network access to github.com and re-run install." >&2 + return 1 + } + fi + git -C "$UXD_DIR" checkout "$UXD_SHA" 2>/dev/null || { + echo " Error: could not check out UXD AI Skills commit ${UXD_SHA:0:7}" >&2 + return 1 + } + fi + + for plugin in "${UXD_PLUGINS[@]}"; do + local plugin_skills="${UXD_DIR}/plugins/${plugin}/skills" + [[ -d "$plugin_skills" ]] || continue + for skill_dir in "${plugin_skills}"/*/; do + [[ -d "$skill_dir" ]] || continue + local skill_name + skill_name="$(basename "$skill_dir")" + local target="${skills_dir}/${skill_name}" + if [[ -e "$target" && ! -L "$target" ]]; then + echo " Warning: ${target} exists and is not a symlink; skipping" >&2 + continue + fi + ln -sfn "$skill_dir" "$target" + echo " Linked ${target} -> ${skill_dir} (uxd)" + done + done +} + install_shared() { local target_dir="$1" if [[ ! -d "${INSTALL_DIR}/_shared" ]]; then @@ -203,6 +267,7 @@ install_cursor() { echo " Linked ${SKILLS_DIR}/${wf} -> ${INSTALL_DIR}/${wf} ($SCOPE)" done generate_cursor_commands "$CMDS_DIR" + install_uxd_skills "$SKILLS_DIR" } install_claude() { @@ -277,6 +342,7 @@ install_claude() { echo " Removed stale commands symlink ${CMDS_DIR}/${wf} ($SCOPE)" fi done + install_uxd_skills "$SKILLS_DIR" } install_gemini() { @@ -292,6 +358,7 @@ install_gemini() { ln -sfn "${INSTALL_DIR}/${wf}" "${SKILLS_DIR}/${wf}" echo " Linked ${SKILLS_DIR}/${wf} -> ${INSTALL_DIR}/${wf} ($SCOPE)" done + install_uxd_skills "$SKILLS_DIR" } # Offer a daily systemd --user notifier (Linux desktop). Default: no. diff --git a/prd/SKILL.md b/prd/SKILL.md index b8f1a057..4e23ff38 100644 --- a/prd/SKILL.md +++ b/prd/SKILL.md @@ -1,6 +1,6 @@ --- name: prd -version: 0.9.0 +version: 0.9.1 description: >- Requirements-to-PRD workflow that ingests requirements from Jira, clarifies ambiguities through iterative Q&A, drafts a Product Requirements Document, diff --git a/triage/SKILL.md b/triage/SKILL.md index 6c1988be..93c58f2a 100644 --- a/triage/SKILL.md +++ b/triage/SKILL.md @@ -1,6 +1,6 @@ --- name: triage -version: 0.5.0 +version: 0.5.1 description: >- Bulk-triage unresolved Jira bugs with AI-driven recommendations and an interactive HTML report. Scan also loads recently resolved bugs for regression diff --git a/ux-design/README.md b/ux-design/README.md new file mode 100644 index 00000000..b3d92040 --- /dev/null +++ b/ux-design/README.md @@ -0,0 +1,211 @@ +# UX Design Workflow + +A UX design workflow that takes a `[UX]` story through discovery, user +research, prototyping, and heuristic evaluation to produce a validated +design handoff artifact for the `ui-design` workflow. `/ingest` follows the +story's references to load the PRD, design document, and sibling stories from +shared locations, so the design is grounded in the feature's real personas, +non-functional requirements, and technical constraints. + +## Phase Flow + +```mermaid +graph TD + ingest([ingest]) --> research + ingest --> prototype + research --> prototype + prototype --> evaluate + evaluate -->|iterate| prototype + evaluate -->|ready| handoff + handoff --> revise + handoff --> publish + revise --> publish + publish --> respond +``` + +Research is conditional — skip directly to `/prototype` if the researcher +already has validated data or well-understood user needs. + +## Prerequisites + +| Tool | Required | Purpose | +|------|----------|---------| +| Jira access (MCP or CLI) | For `/ingest` | Fetch the `[UX]` story, its Design Reference, and sibling stories | +| Docs repo (published PRD + design doc) | For `/ingest` | Load the PRD and design document the design must honor | +| UXD skills (`uxd-workshop`) | Required | Prototype generation, heuristic evaluation, discovery, handoff | +| `python3` on PATH | For `/evaluate` (Standard/Full) | `uxd-prototype-evaluate` helper scripts | + +`/ingest` loads all upstream inputs from **shared** locations (the published +docs repo and Jira) — never from another workflow's private `.artifacts/`. +Missing inputs are recorded as gaps, not fabricated; `/handoff`'s feasibility +check marks its findings "unverified" when the design document was unavailable. + +## Phases + +| Phase | Command | Purpose | Artifact(s) | +|-------|---------|---------|-------------| +| Ingest | `/ingest` | Load PRD + design doc + sibling stories, frame the problem, identify user groups, survey landscape | `01-discovery.md` | +| Research | `/research` | Conduct user research, synthesize findings | `02-research.md` | +| Prototype | `/prototype` | Generate design prototypes from research | `03-prototype/` | +| Evaluate | `/evaluate` | Heuristic evaluation and usability assessment | `04-evaluation.md` | +| Handoff | `/handoff` | Produce implementation-ready design spec | `05-handoff.md` | +| Revise | `/revise` | Incorporate stakeholder feedback | `05-handoff.md` (updated) | +| Publish | `/publish` | Push handoff spec to docs repo for review | `06-pr-description.md`, `publish-metadata.json`, PR in docs repo | +| Respond | `/respond` | Address PR reviewer comments | Updated `05-handoff.md` | + +## Typical Flow + +```text +/ingest EDM-1234 + → follows the [UX] story's Design Reference to load the PRD, design + document, and sibling stories from the docs repo and Jira + → frames the problem, identifies user groups + → surveys competitive landscape + → writes .artifacts/ux-design/EDM-1234/01-discovery.md + +/research (conditional — skip if you have data) + → conducts user research + → synthesizes findings into themed insights + → documents persona-specific needs + → writes 02-research.md + +/prototype + → generates design prototypes informed by research + → writes 03-prototype/ (files + prototype-notes.md) + +/evaluate + → runs heuristic evaluation against prototype + → writes 04-evaluation.md + → loops back to /prototype if critical issues found + +/handoff + → synthesizes all artifacts into implementation spec + → maps UI elements to design system components + → annotates data requirements per UI element + → documents persona-specific views + → reality-checks the design against the technical design (final vision + vs. MVP/phase-1 split when constraints require it) + → writes 05-handoff.md + +/publish + → pushes 05-handoff.md to docs repo + → opens PR for team review + +/respond + → addresses PR review comments + → updates 05-handoff.md as needed +``` + +## Artifacts + +All artifacts are stored in `.artifacts/ux-design/{issue-key}/`. + +```text +.artifacts/ux-design/EDM-1234/ + 01-discovery.md (problem framing, user groups, landscape) + 02-research.md (research findings, insights, recommendations) + 03-prototype/ (mirrored skill output + design rationale) + prototype-notes.md (design decisions, user stories covered) + prototype/ (generated prototype files, from the skill) + 04-evaluation.md (heuristic eval report, readiness assessment) + 04-eval-raw/ (raw skill reports, mirrored from the eval skills) + 05-handoff.md (implementation spec, component mapping, AC) + 06-pr-description.md (generated PR body for /publish) + publish-metadata.json (PR tracking: number, URL, branch, head SHA) + provenance.json (authoring provenance log) +``` + +## Handoff Contract + +`05-handoff.md` is the primary artifact consumed by the `ui-design` workflow. +It contains: + +- **Component mapping** — UI elements mapped to design system components +- **Interaction specs** — every user interaction documented +- **State enumeration** — empty, loading, error, populated, responsive +- **Data annotations** — what data each UI element needs (with gaps flagged) +- **Persona-specific views** — where user groups interact differently +- **Acceptance criteria** — testable, traced to research findings +- **Feasibility and phasing** — design reality-checked against the technical + design, with a final-vision/MVP split when constraints require it +- **Research context** — why decisions were made + +## UXD Marketplace Skills + +This workflow requires skills from the +[UXD AI Skills marketplace](https://github.com/rh-uxd/ai-helpers). +These skills are a hard dependency — phases that use them will stop and prompt +you to run `./install.sh` if they are missing. + +`install.sh` installs them **AI-agnostically**: it clones the `rh-uxd/ai-helpers` +repo (pinned to a specific commit) and symlinks each skill into the skills +directory for your AI tool (Claude Code, Cursor, or Gemini). The skills are +installed and invoked by **bare name** (`uxd-discovery`, `uxd-prototype-create`, +…), *not* through Claude Code's `/uxd-workshop:` plugin-marketplace +namespace — the bare-name form is the one that resolves across all three tools. + +| Skill | Plugin | Used by | +|-------|--------|---------| +| `uxd-discovery` | `uxd-workshop` | `/ingest` | +| `uxd-prototype-create` | `uxd-workshop` | `/prototype` | +| `uxd-research-heuristic-eval` | `uxd-workshop` | `/evaluate` | +| `uxd-evaluate-design-heuristics` | `uxd-workshop` | `/evaluate` | +| `uxd-prototype-evaluate` | `uxd-workshop` | `/evaluate` (Standard/Full depth) | +| `uxd-design-handoff` | `uxd-workshop` | `/handoff` | + +`uxd-prototype-create` reads Figma links directly, so the workflow does not +invoke `uxd-figma-read` separately (`install.sh` still symlinks it if you want to +use it standalone). + +**Runtime note:** the script-backed skills (`uxd-prototype-create` and +`uxd-prototype-evaluate`) run Python helpers via the `${CLAUDE_SKILL_DIR}` +environment variable, which only Claude Code sets. Under Cursor or Gemini it is +unset, so `/prototype` and `/evaluate` resolve the scripts from the deterministic +install path (`${HOME}/.uxd-ai-skills/plugins/uxd-workshop/skills/`) and +substitute it inline. If **neither** the variable nor that path resolves to a +real `scripts/` directory (or a helper is missing), the phase stops and reports +the error rather than silently downgrading a Standard/Full evaluation to Quick. +This `${CLAUDE_SKILL_DIR}` workaround is the one runtime-specific wrinkle, and it +would be removed by an upstream change to how the skills resolve their scripts. +The remaining skills use no runtime-specific mechanisms. + +## Directory Structure + +```text +ux-design/ +├── SKILL.md # Workflow entry point +├── guidelines.md # Behavioral rules and guardrails +├── README.md # This file +├── skills/ +│ ├── controller.md # Phase dispatcher and transitions +│ ├── ingest.md # Frame problem, identify user groups +│ ├── research.md # Conduct user research +│ ├── prototype.md # Generate design prototypes +│ ├── evaluate.md # Heuristic evaluation +│ ├── handoff.md # Design-to-implementation spec +│ ├── revise.md # Incorporate stakeholder feedback +│ ├── publish.md # Push to docs repo PR +│ └── respond.md # Address PR review comments +└── commands/ + ├── ingest.md # /ingest command + ├── research.md # /research command + ├── prototype.md # /prototype command + ├── evaluate.md # /evaluate command + ├── handoff.md # /handoff command + ├── revise.md # /revise command + ├── publish.md # /publish command + └── respond.md # /respond command +``` + +## Getting Started + +```bash +# Install the workflow +./install.sh claude --workflows ux-design + +# Or install all workflows +./install.sh all +``` + +Then in your project, run `/ingest` with a Jira issue key or feature +description to begin. diff --git a/ux-design/SKILL.md b/ux-design/SKILL.md new file mode 100644 index 00000000..af178306 --- /dev/null +++ b/ux-design/SKILL.md @@ -0,0 +1,27 @@ +--- +name: ux-design +version: 0.1.0 +description: >- + UX design workflow that takes a [UX] story through discovery, + prototyping, and heuristic evaluation to produce a validated design + handoff artifact for implementation. Ingest loads the PRD, design + document, and sibling stories from shared locations so the design is + grounded in real personas, non-functional requirements, and technical + constraints. + Activated by commands: /ingest, /research, /prototype, /evaluate, /handoff, /revise, /publish, /respond. +--- +# UX Design Workflow Orchestrator + +## Quick Start + +1. If the user invoked a specific command (e.g., `/prototype`, `/evaluate`), + read `commands/{command}.md` and follow it. +2. Otherwise, read `skills/controller.md` to load the workflow controller: + - If the user provided a Jira issue key or URL, execute the `/ingest` phase + - Otherwise, execute the first phase the user requests + +If a step fails or produces unexpected output, stop and report the error to +the user. Do not advance to the next phase. Offer to retry the failed step or +escalate. + +For principles, hard limits, and escalation rules, see `guidelines.md`. diff --git a/ux-design/commands/evaluate.md b/ux-design/commands/evaluate.md new file mode 100644 index 00000000..36717d0f --- /dev/null +++ b/ux-design/commands/evaluate.md @@ -0,0 +1,11 @@ +--- +name: ux-design:evaluate +description: "Run heuristic evaluation and usability assessment against prototypes" +--- +# /evaluate + +Read `../skills/controller.md` and follow it. + +Dispatch the **evaluate** phase. Context: + +$ARGUMENTS diff --git a/ux-design/commands/handoff.md b/ux-design/commands/handoff.md new file mode 100644 index 00000000..bcc1747d --- /dev/null +++ b/ux-design/commands/handoff.md @@ -0,0 +1,11 @@ +--- +name: ux-design:handoff +description: "Synthesize all research into an implementation-ready handoff spec" +--- +# /handoff + +Read `../skills/controller.md` and follow it. + +Dispatch the **handoff** phase. Context: + +$ARGUMENTS diff --git a/ux-design/commands/ingest.md b/ux-design/commands/ingest.md new file mode 100644 index 00000000..94fec413 --- /dev/null +++ b/ux-design/commands/ingest.md @@ -0,0 +1,11 @@ +--- +name: ux-design:ingest +description: "Frame the problem, identify user groups, and survey the competitive landscape" +--- +# /ingest + +Read `../skills/controller.md` and follow it. + +Dispatch the **ingest** phase. Context: + +$ARGUMENTS diff --git a/ux-design/commands/prototype.md b/ux-design/commands/prototype.md new file mode 100644 index 00000000..a33cfc1b --- /dev/null +++ b/ux-design/commands/prototype.md @@ -0,0 +1,11 @@ +--- +name: ux-design:prototype +description: "Generate design prototypes informed by research findings" +--- +# /prototype + +Read `../skills/controller.md` and follow it. + +Dispatch the **prototype** phase. Context: + +$ARGUMENTS diff --git a/ux-design/commands/publish.md b/ux-design/commands/publish.md new file mode 100644 index 00000000..e33088cb --- /dev/null +++ b/ux-design/commands/publish.md @@ -0,0 +1,11 @@ +--- +name: ux-design:publish +description: "Push the handoff spec as a GitHub PR for external review" +--- +# /publish + +Read `../skills/controller.md` and follow it. + +Dispatch the **publish** phase. Context: + +$ARGUMENTS diff --git a/ux-design/commands/research.md b/ux-design/commands/research.md new file mode 100644 index 00000000..277d60d8 --- /dev/null +++ b/ux-design/commands/research.md @@ -0,0 +1,11 @@ +--- +name: ux-design:research +description: "Conduct user research, gather data, and synthesize findings into insights" +--- +# /research + +Read `../skills/controller.md` and follow it. + +Dispatch the **research** phase. Context: + +$ARGUMENTS diff --git a/ux-design/commands/respond.md b/ux-design/commands/respond.md new file mode 100644 index 00000000..45468bbf --- /dev/null +++ b/ux-design/commands/respond.md @@ -0,0 +1,11 @@ +--- +name: ux-design:respond +description: "Fetch and address reviewer comments on the handoff spec PR" +--- +# /respond + +Read `../skills/controller.md` and follow it. + +Dispatch the **respond** phase. Context: + +$ARGUMENTS diff --git a/ux-design/commands/revise.md b/ux-design/commands/revise.md new file mode 100644 index 00000000..aee8d5b0 --- /dev/null +++ b/ux-design/commands/revise.md @@ -0,0 +1,11 @@ +--- +name: ux-design:revise +description: "Incorporate stakeholder feedback into the handoff spec" +--- +# /revise + +Read `../skills/controller.md` and follow it. + +Dispatch the **revise** phase. Context: + +$ARGUMENTS diff --git a/ux-design/guidelines.md b/ux-design/guidelines.md new file mode 100644 index 00000000..b723a580 --- /dev/null +++ b/ux-design/guidelines.md @@ -0,0 +1,117 @@ +# UX Design Workflow Guidelines + +## Principles + +- The handoff spec represents the **team's** agreed UX approach, not the AI's + interpretation. Always confirm before finalizing content. +- Trace every design decision back to a research finding or user direction. + Do not invent user needs or fabricate evidence. +- **Evidence over assumption.** When research data is unavailable, say so + explicitly. "We don't have data on this" is valuable — silence is not. +- **Precision over verbosity.** A concise, well-structured handoff gets better + reviews. Cover everything that matters; don't pad it. +- Preserve the researcher's terminology and domain language. Do not rewrite + their findings into generic UX jargon. +- Prototypes are conversation starters, not final designs. A rough prototype + the researcher can react to is more valuable than a polished one they can't. +- Heuristic evaluation supplements — never replaces — real user testing. + AI-driven evaluation catches systematic issues; only humans catch context- + dependent usability problems. The handoff spec must note the evaluation + method and flag when real user testing has not been conducted. +- **Research is conditional.** Not every feature needs a dedicated research + phase. `/research` is recommended when user needs are unclear or unvalidated. + Skip to `/prototype` if the researcher already has validated data. + +## Hard Limits + +- No auto-advancing between phases. Always wait for the researcher. +- No fabricated research findings. Every insight must trace to data the + researcher provided or desk research the AI performed with citations. +- No storing PII in artifacts. User interview data must be anonymized before + inclusion. Use role-based labels ("User P1", "Admin P2"), not names. +- No publishing artifacts without explicit researcher approval. +- No skipping the human gate between phases. Present findings, get confirmation. +- No committing to `main` directly. Use feature branches for `/publish`. +- **No personal names in generated content.** Replace references to individuals + from Jira tickets, interview notes, or other source material with role-based + descriptions ("the fleet admin reported…", "a participant noted…"). Author + metadata fields are exempt — they identify the document author, not + referenced individuals. +- **No scope reduction.** Never silently defer design decisions to "v2" or + mark states as "future enhancement" to reduce scope. If scope won't fit + a single research cycle, propose a split — don't quietly drop it. + +## Safety + +- Show your work before finalizing. After each phase, present artifacts for + review — do not assume they are ready. +- Flag assumptions explicitly. If research data doesn't cover something and + you filled it in, mark it clearly as an assumption. +- Indicate confidence levels on recommendations. Distinguish between findings + backed by multiple data sources (HIGH) and single-source observations (LOW). +- Before `/publish`, confirm the target repository, branch, and PR details + with the researcher. + +## Quality + +- Artifacts must be structured for both human reading and machine consumption. + Use consistent markdown headings and table formats — downstream workflows + (ui-design, ui-implement) parse these artifacts programmatically. +- The handoff spec must be detailed enough for a developer to implement without + additional design consultation. If a developer would need to ask a question, + the answer belongs in the spec. +- Heuristic evaluation findings must include severity ratings and specific + remediation guidance — not just observations. +- Acceptance criteria must be **behavioral outcomes** (what the system does, + testable from outside), not activities or implementation details. +- The Data Annotations and Persona-Specific Views sections of the handoff spec + are required, not optional. If all user groups interact identically, say so + explicitly. If no UI element has data uncertainty, say so explicitly. Do not + omit these sections. + +## Escalation + +Stop and request human guidance when: + +- Research reveals contradictory user needs with no clear resolution +- The scope appears too broad for a single research cycle (suggest splitting) +- Prototype feedback is ambiguous or contradictory +- Heuristic evaluation reveals critical accessibility violations that may + require architectural changes +- The researcher's domain expertise is needed to interpret data +- Confidence in a design recommendation is low + +## Artifact Persistence and Isolation + +- All workflow artifacts MUST be stored under `.artifacts/ux-design/{issue-key}/` +- NEVER read from another workflow's `.artifacts/` directory (`.artifacts/prd/`, + `.artifacts/design/`, etc.) — those are private working directories, not + interfaces +- Shared inputs MUST come from published locations: + - Jira issues (read-only) + - Published docs repository (PRD, design doc, clarifications) + - `.artifacts/config.json` (shared repo configuration) + - Project files (AGENTS.md, CLAUDE.md, design system docs) +- When a downstream workflow needs this workflow's output, it reads from the + published docs repository (via `/publish`), not from `.artifacts/ux-design/` + +## Shell Command Safety + +When instructing the AI to interpolate values into shell commands (e.g., Jira +titles, branch names, user input): + +- Always quote interpolated values with double quotes +- Never pass unvalidated free-form text (e.g., Jira issue summaries) as + command-line flags unquoted +- Validate values match expected patterns before interpolation when possible + +Example: `git commit -m "${title}"` not `git commit -m $title` + +## Working With the Project + +This workflow gets deployed into different projects. Respect the target project: + +- Read and follow the project's own `AGENTS.md` or `CLAUDE.md` files +- Adopt the project's conventions for document formatting if they exist +- Use the project's design system and component library for prototyping +- Use the configured docs repository for `/publish` operations diff --git a/ux-design/skills/controller.md b/ux-design/skills/controller.md new file mode 100644 index 00000000..42976e70 --- /dev/null +++ b/ux-design/skills/controller.md @@ -0,0 +1,239 @@ +--- +name: controller +description: Top-level workflow controller that manages phase transitions for UX design — discovery, user research, prototyping, evaluation, handoff, revision, publication, and review response. +--- + +# UX Design Workflow Controller + +You are the workflow controller. Your job is to manage the ux-design workflow +by executing phases and handling transitions between them. + +## Phases + +1. **Ingest** (`/ingest`) — `ingest.md` + Follow the `[UX]` story's references to load the PRD, design document, and + sibling stories from shared locations; frame the problem, identify user + groups, and survey the competitive landscape. Produces the discovery + artifact, grounded in the feature's real personas, NFRs, and technical + design. + +2. **Research** (`/research`) — `research.md` + Conduct user research — interviews, surveys, analytics, desk research. + Synthesize findings into insights and design recommendations. Conditional: + recommended when user needs are unclear or unvalidated; skippable if the + researcher already has validated research data. + +3. **Prototype** (`/prototype`) — `prototype.md` + Generate design prototypes informed by discovery and research findings. + Iterative — loops with `/evaluate`. + +4. **Evaluate** (`/evaluate`) — `evaluate.md` + Run heuristic evaluation and usability assessment against prototypes. + Iterative — loops back to `/prototype` or advances to `/handoff`. + +5. **Handoff** (`/handoff`) — `handoff.md` + Synthesize all prior artifacts into an implementation-ready spec with + component mapping, interaction specs, data annotations, persona-specific + views, and acceptance criteria — reality-checked against the technical + design, with a final-vision/MVP split when constraints require it. + +6. **Revise** (`/revise`) — `revise.md` + Incorporate stakeholder feedback into the handoff spec. Repeatable. + +7. **Publish** (`/publish`) — `publish.md` + Push the handoff spec as a PR to the docs repo for external review. + +8. **Respond** (`/respond`) — `respond.md` + Fetch and address PR reviewer comments on the published handoff spec. + +## Workspace + +All work happens in the **source repo** — the researcher needs codebase +context to make informed design decisions. Planning artifacts live in +`.artifacts/ux-design/{issue-key}/` (gitignored). + +### Artifact directory + +All working artifacts are stored in `.artifacts/ux-design/{issue-key}/` +within the source repo: + +| Artifact | File | Written by | +|----------|------|------------| +| Discovery brief | `01-discovery.md` | `/ingest` | +| Research findings | `02-research.md` | `/research` | +| Prototype files | `03-prototype/` | `/prototype` | +| Prototype notes | `03-prototype/prototype-notes.md` | `/prototype` | +| Evaluation report | `04-evaluation.md` | `/evaluate` | +| Implementation handoff | `05-handoff.md` | `/handoff` | +| Provenance log | `provenance.json` | `/handoff`, `/revise`, `/respond` | +| PR description | `06-pr-description.md` | `/publish` | +| Publish metadata | `publish-metadata.json` | `/publish` | + +## How to Execute a Phase + +1. **Announce** the phase to the user: *"Starting /prototype."* +2. **Locate** the skill file — read and follow + `../../_shared/recipes/phase-override-resolution.md` with + WORKFLOW=`ux-design`, PHASE_FILE=`{phase}.md`. +3. **Read** the resolved skill file +4. **Execute** the skill's steps — the user should see your progress +5. When the skill is done, it will tell you to report findings and + re-read this controller. Do that — then use "Recommending Next Steps" + below to offer options. +6. Present the skill's results and your recommendations to the user +7. **Stop and wait** for the user to tell you what to do next. + +## Recommending Next Steps + +After each phase completes, present the user with **options** — not just one +next step. Use the typical flow as a baseline, but adapt to what actually +happened. + +### Typical Flow + +```text +ingest → [research] → prototype → evaluate → (iterate? → prototype) or → handoff → revise → publish → respond +``` + +Research is in brackets because it is conditional — not every feature needs +a dedicated research phase. Skip to `/prototype` if the researcher already +has validated data or well-understood user needs. + +### What to Recommend + +**Continuing forward:** + +- `/ingest` completed → recommend `/research` if user needs are unclear or + unvalidated; recommend `/prototype` directly if the researcher has + sufficient research data +- `/research` completed → recommend `/prototype` to explore design directions +- `/prototype` completed → recommend `/evaluate` (always — never skip evaluation) +- `/evaluate` completed (no critical issues) → recommend `/handoff` +- `/evaluate` completed (critical issues) → recommend `/prototype` to iterate +- `/handoff` completed → recommend `/revise` if the researcher wants + stakeholder feedback, or `/publish` to push the spec to the docs repo +- `/revise` completed → recommend `/publish` (or another `/revise` round) +- `/publish` completed → recommend sharing the PR with reviewers, then + `/respond` when comments arrive +- `/respond` completed → recommend another `/respond` round if new comments + arrive, or the workflow is done + +**When to recommend `/research`:** + +After `/ingest` completes, recommend `/research` when: +- The discovery brief surfaces significant unknowns about user needs +- The researcher doesn't have existing interviews, surveys, or analytics +- Competing design directions exist and research would break the tie +- The strategic decisions in the discovery brief require user data to resolve + +When the researcher already has validated research data or well-understood +user needs, recommend `/prototype` directly. + +**Iteration tracking:** + +- Track the number of prototype→evaluate cycles +- After 3 cycles, explicitly ask: "We've iterated 3 times. Ready for handoff, or continue refining?" +- The researcher decides — no hard cap + +**Looping back:** + +- `/research` reveals the problem framing is wrong → suggest revisiting `/ingest` +- `/prototype` reveals research gaps → suggest additional `/research` work +- `/evaluate` reveals fundamental design problems → suggest `/prototype` with specific changes +- `/handoff` reveals missing interaction specs → loop back to refine the prototype + +**Skipping:** + +- `/research` is always skippable — go directly to `/prototype` if the + researcher has sufficient domain knowledge or existing research data +- If the researcher already has a validated design, they may start at `/handoff` +- Phase entry requirements are listed below + +### Phase Entry + +Researchers can enter at any phase if they bring the prerequisite artifact: + +| Phase | Requires | +|-------|----------| +| `/ingest` | Jira issue key or feature description | +| `/research` | `01-discovery.md` (or equivalent problem framing) | +| `/prototype` | `01-discovery.md` + `02-research.md` (or equivalent; research skippable) | +| `/evaluate` | `03-prototype/` (prototype to evaluate). Standard/Full depth also needs the skill `{ID}` recorded in `03-prototype/prototype-notes.md`, and the mirrored native layout under `03-prototype/` so `.artifacts/{ID}/` can be recreated | +| `/handoff` | `04-evaluation.md` (or researcher confirms design is ready) | +| `/revise` | `05-handoff.md` | +| `/publish` | `05-handoff.md` | +| `/respond` | `publish-metadata.json` (PR must exist) | + +If a prerequisite artifact is missing, tell the researcher which phase +produces it and offer to run that phase first. + +### How to Present Options + +Lead with your top recommendation, then list alternatives briefly: + +```text +Recommended next step: /prototype — generate design prototypes based on +the approved research findings. + +Other options: +- /handoff — if you already have a validated design and want to skip prototyping +``` + +## Starting the Workflow + +Before dispatching any phase, check if the project has its own `AGENTS.md` +or `CLAUDE.md`. If so, read it — it may contain project-specific conventions +or design system guidance that affects how the workflow operates. + +When the user provides a Jira issue key or URL: +1. Execute the **ingest** phase +2. After ingestion, present results and wait + +If the user invokes a specific command (e.g., `/evaluate`), execute that +phase directly — don't force them through earlier phases. + +## Error Handling + +If any phase fails (Jira MCP errors, skill unavailability, file errors): + +1. **Stop immediately.** Do not advance to the next phase. +2. **Report the error** to the user with the specific error message. +3. **Offer options:** retry the failed step, skip the phase (if optional), + or escalate. + +Do not fabricate results when a tool call fails. Do not silently continue +past errors. Recovery must not advance to a later phase — report the error, +re-read this controller, and wait for user direction. + +## Context Management + +When the AI detects that its own output quality is degrading (e.g., it +misses details, repeats itself, or loses track of earlier decisions), +consider spawning the next phase as a subagent with a fresh context window. +This is self-monitoring by the AI, not something a human operator watches. +Load the subagent with the skill file for the phase being executed, the +relevant artifact files from `.artifacts/ux-design/{issue-key}/`, and the +project's `AGENTS.md`/`CLAUDE.md`. + +**Important:** Spawning a subagent does not bypass the human gate between +phases. Even when a subagent completes a phase artifact, always present it +to the researcher for confirmation before advancing to the next phase per +the "Never auto-advance" rule below. + +This is a recommendation, not a requirement — not all AI runtimes support +subagent spawning. When subagent support is unavailable, manage context by +keeping phases short and relying on the artifact files to carry state between +phases. + +## Rules + +- **Never auto-advance.** Always wait for the researcher between phases. +- **Recommendations come from this file, not from skills.** Skills report + findings; this controller decides what to recommend next. +- **Evaluation before handoff.** Never recommend `/handoff` unless + `/evaluate` has been run or the researcher explicitly skips it. +- **Skills are required.** The `uxd-workshop` skills are a hard dependency. + If a skill is unavailable, the phase stops and directs the researcher + to run `./install.sh`. +- **Research data is the researcher's.** The AI organizes and synthesizes + but does not fabricate or extrapolate beyond what the data supports. diff --git a/ux-design/skills/evaluate.md b/ux-design/skills/evaluate.md new file mode 100644 index 00000000..06fd5a95 --- /dev/null +++ b/ux-design/skills/evaluate.md @@ -0,0 +1,422 @@ +--- +name: evaluate +description: Heuristic evaluation and usability assessment of prototypes. +--- + +# Evaluate — Heuristic Evaluation + +Run systematic heuristic evaluation against the prototype to identify +usability issues before real user testing. AI-driven evaluation catches +systematic issues; only humans catch context-dependent problems. + +## Dependencies + +This phase requires the `uxd-workshop` skills. If any required skill is +not available, stop and tell the researcher to run `./install.sh` to set up +the uxd-workshop skills before proceeding. + +## Prerequisites + +Read `.artifacts/ux-design/{issue-key}/03-prototype/prototype-notes.md` +for design decisions and open questions. If `prototype-notes.md` doesn't +exist, tell the researcher that `/prototype` should run first and stop. + +Also read `.artifacts/ux-design/{issue-key}/01-discovery.md` for user group +context and problem framing. + +If `.artifacts/ux-design/{issue-key}/02-research.md` exists, read it for +user needs and insights — these inform impact descriptions in the evaluation +findings and the cross-reference step below. + +## Process + +### Step 1: Choose Evaluation Depth (Interactive) + +Ask the researcher what depth of evaluation is appropriate: + +| Depth | What it covers | Skills run | +|-------|---------------|-----------| +| **Quick** | Multi-evaluator heuristic inspection only (three independent AI evaluators surface usability violations against the chosen framework). No design scoring, no simulated usability. | `uxd-research-heuristic-eval` (Step 2) | +| **Standard** | Quick + structured design-heuristics scoring (accessibility, visual hierarchy, content, state coverage, goal alignment) + simulated usability testing with personas and 4-8 task scenarios, severity-ranked. | Steps 2, 3, 4 (`--depth standard`) | +| **Full** | Standard + desirability study (word association, emotional response mapping, desirability score 1-10). | Steps 2, 3, 4 (`--depth full`) | + +Use Quick for early iterations and rapid feedback, Standard for most +evaluations, and Full for the final evaluation before handoff. + +Default to **Standard** unless the researcher specifies otherwise. + +**Naming caution:** this workflow's Quick/Standard/Full tier is *not* the same +thing as `uxd-prototype-evaluate`'s own `--depth quick|standard|full`. The +workflow tier decides *which skills run* (Quick runs no `uxd-prototype-evaluate` +at all); the skill's `--depth` only tunes that one skill once it does run. When +this phase runs `uxd-prototype-evaluate` (Standard/Full), it passes +`--depth standard` or `--depth full` accordingly (Step 4) — don't confuse the +two scales. + +If the selected depth requires tools that are unavailable, stop and tell +the researcher to run `./install.sh` before proceeding. + +### Step 2: Heuristic Evaluation + +This is the primary evaluation tool — tested with an eval suite. It uses three +independent AI-simulated evaluators: +- **Evaluator A:** Visual inspection +- **Evaluator B:** Task flow analysis +- **Evaluator C:** Edge cases and accessibility + +Findings are reconciled across evaluators and tagged by agreement level +(Unanimous, Majority, Single). Evaluators report **violations only** — they do +not make design recommendations. + +**Framework selection first.** Ask the researcher which heuristic framework to +use before running the skill — do not default silently. Available frameworks: +- Nielsen's 10 Usability Heuristics +- Shneiderman's 8 Golden Rules +- ISO 9241-110 Interaction Principles +- Gerhardt-Powals' Cognitive Engineering Principles + +**Produce the evaluation input first.** `uxd-research-heuristic-eval` inspects +screenshots, a URL, or a text description — **not** Figma links or raw HTML file +paths. So before invoking it, turn the prototype into something the skill can +see: + +- **Standalone HTML** (`03-prototype/prototype/`): serve it and pass the URL. + From the prototype directory, start a local server, e.g. + `python3 -m http.server 8000` (run from + `.artifacts/ux-design/{issue-key}/03-prototype/prototype/`), then pass + `http://localhost:8000/.html`. Stop the server when the skill finishes. +- **Screenshots** (any mode, or when a server can't run): capture one image per + key screen/state (empty, loading, error, populated) into + `04-eval-raw/screenshots/` — via a browser automation tool if available, or + ask the researcher to export them — and pass that directory. +- **Workspace mode:** the prototype runs inside the codebase; serve or run the + app per the project's own instructions and pass the URL, or use screenshots. + +**Screenshots are mandatory at Standard/Full depth.** A served URL alone +satisfies *this* step (Step 2), but Step 3's `uxd-evaluate-design-heuristics` +requires **screenshots specifically** and will stop and ask if none are provided +(it evaluates visual context and does not accept a URL). So whenever the chosen +depth is Standard or Full, capture the screenshots into `04-eval-raw/screenshots/` +now — even if you also serve a URL for Step 2 — so Step 3 has its required input +and can't block mid-phase after `uxd-prototype-evaluate` scratch is already set +up. At Quick depth (Step 2 only) a URL alone is sufficient. + +**Gate — no fabricated input.** If you cannot produce the required input — +a URL *or* screenshots at Quick depth, and **screenshots** at Standard/Full depth +(e.g. an unattended run with no browser/serving capability and no exported +images) — **stop and tell the researcher** what is needed. Do not run any skill +against a Figma link or a raw file path, and do not describe the prototype from +memory in place of real input — either would produce an evaluation of something +other than the prototype. + +**Invocation.** Run the skill in agent-operated mode so its own researcher gate +is deferred to this workflow's single combined gate in Step 7. + +The `--project` path must be relative to the source-repository root. If the +skill execution might have changed directory, explicitly change back to the +source-repository root before invoking, then use the relative path: + +```bash +REPO_ROOT=$(git rev-parse --show-toplevel) || { echo "Failed to find repository root"; exit 1; } +cd "$REPO_ROOT" +uxd-research-heuristic-eval "" \ + --framework "" --review none \ + --project ".artifacts/ux-design/{issue-key}/04-eval-raw" +``` + +`--review none` requires `--framework` (it activates the skill's Mode B), so +always pass the framework the researcher chose. With `--review none` the skill +emits an **Unreviewed Draft** with AI-*suggested* severities and skips its own +review gate — this is intentional. We do **not** run two researcher gates; the +single human gate is Step 7 below, over the combined findings from all methods. + +`--project` directs the skill's `.md`/`.html` reports to +`.artifacts/ux-design/{issue-key}/04-eval-raw/` (otherwise it writes them to +the current working directory). Read that report in Step 6 to fold the findings +into `04-evaluation.md`. + +### Step 3: Design Heuristics Scoring (Standard and Full depth only) + +Run the `uxd-evaluate-design-heuristics` skill for structured scoring +across dimensions: + +- Accessibility compliance +- Visual hierarchy and scannability +- Content and microcopy clarity +- State coverage (empty, loading, error, populated) +- Goal alignment + +**Input: the screenshots captured in Step 2.** This skill requires +**screenshots** (it evaluates visual context and, unlike +`uxd-research-heuristic-eval`, does not accept a served URL); it stops and asks +if none are given. Pass it the `04-eval-raw/screenshots/` directory produced in +Step 2. Since Step 2's gate makes screenshots mandatory at Standard/Full depth, +they are already present; if for any reason they are not, capture them (or ask +the researcher to export them) before invoking — do not run this skill against a +URL or from memory. + +**Output is returned inline — there is no report file.** This skill is a pure +LLM skill (no `scripts/`, no `--project` flag): it *returns* the Pass/Fail +verdict, per-dimension scores (1-5), and critical issues directly (its `report` +flag, default `true`, adds the full write-up to the same returned output, it does +not write a file). Nothing lands on disk, so there is nothing to mirror or clean +up here. Capture the returned scores and critical issues in memory and fold them +into `04-evaluation.md` in Step 6. + +### Step 4: Simulated Usability Assessment (Standard and Full depth only) + +Skip this step at Quick depth. + +`uxd-prototype-evaluate` reads its inputs from the **native skill layout**, +`.artifacts/{ID}/`, not from our `03-prototype/` directory. It reads different +files by mode: +- **Standalone mode:** the prototype files in `.artifacts/{ID}/prototype/`, + `.artifacts/{ID}/rfe-snapshot.md`, and `.artifacts/{ID}/metadata.json`. +- **Workspace mode:** `.artifacts/{ID}/changeset.md` and + `.artifacts/{ID}/workspace-analysis.json` (plus `metadata.json`). + +If you invoke it without staging these, it silently finds nothing and produces +wrong or unevaluable results. Before running it: + +1. Read the **skill prototype ID** (`{ID}`) recorded in + `.artifacts/ux-design/{issue-key}/03-prototype/prototype-notes.md`. +2. Ensure `.artifacts/{ID}/` contains the skill's expected layout. In a + continued session only our mirror under `03-prototype/` remains (Step 3 of + `/prototype` removes the native copy), so recreate it. The mirror preserves + the native layout, so this is a structure-preserving copy of whichever set + applies: + - **Standalone:** `03-prototype/prototype/` → `.artifacts/{ID}/prototype/`; + `03-prototype/rfe-snapshot.md` → `.artifacts/{ID}/rfe-snapshot.md`; + `03-prototype/metadata.json` → `.artifacts/{ID}/metadata.json` + - **Workspace:** `03-prototype/changeset.md` → `.artifacts/{ID}/changeset.md`; + `03-prototype/workspace-analysis.json` → + `.artifacts/{ID}/workspace-analysis.json`; + `03-prototype/metadata.json` → `.artifacts/{ID}/metadata.json` + - Copy `03-prototype/reviews/summary.md` back to `.artifacts/{ID}/reviews/` + too if it exists from a prior evaluation (so refinement can find it). +3. Invoke the skill with the ID and matching depth: + +``` +/uxd-prototype-evaluate {ID} --depth {standard|full} +``` + +- **Standard:** Rubric scoring + simulated usability testing with personas + and task scenarios, severity-ranked issues (S1 critical through S4 + enhancement) +- **Full:** Standard + desirability study + +The skill writes its outputs under `.artifacts/{ID}/` (`reviews/summary.md`, +`report-usability.md`, and for Full `report-desirability.md`) and a +`pipeline-report.html` at the **`.artifacts/` root** — both *outside* our +namespace. Read those in Step 6 to fold results into `04-evaluation.md`, then: + +- **Mirror the canonical outputs into our namespace:** copy + `.artifacts/{ID}/reviews/summary.md` → `03-prototype/reviews/summary.md` + (refinement re-reads this), `report-usability.md` and any + `report-desirability.md` → `04-eval-raw/`, and `.artifacts/pipeline-report.html` + → `04-eval-raw/pipeline-report.html`. +- **Clean up skill scratch (artifact isolation).** Once mirrored, remove the + native `.artifacts/{ID}/` and the stray `.artifacts/pipeline-report.html` so + nothing is left outside `.artifacts/ux-design/` (`AGENTS.md` rule). A later + session recreates `.artifacts/{ID}/` from the mirror as in step 2 above. + +This skill's usability dimension also evaluates against Nielsen's heuristics, +which overlaps with Step 2 when the researcher chose Nielsen there. The overlap +is intentional — two independent passes (one violation-focused, one task/persona +-focused) raise confidence in findings both flag. Note convergent findings as +higher-confidence in Step 6 rather than deduplicating them away. + +**Runtime note:** `uxd-prototype-evaluate` runs Python helper scripts via +`python3 ${CLAUDE_SKILL_DIR}/scripts/...`. `CLAUDE_SKILL_DIR` is set by Claude +Code; under Cursor or Gemini it is unset. Before the skill runs those helpers, +check it (`printenv CLAUDE_SKILL_DIR`). If it is empty, resolve the skill's +directory from the deterministic install path +`${HOME}/.uxd-ai-skills/plugins/uxd-workshop/skills/uxd-prototype-evaluate` and +substitute that path inline for every `${CLAUDE_SKILL_DIR}` in the command +(e.g. `CLAUDE_SKILL_DIR= python3 /scripts/