Design playbook
Skill Bandersnatch0x/design-playbook/packages/design-playbook/skills/design-playbook
Orchestrate outcome-first Design I/O for product UI. Use when building or revising a page, dashboard, list, or settings surface from a short ask, or recirculating a failed design review through declarations and evidence.From its SKILL.md
npx -y skills add Bandersnatch0x/design-playbook --skill design-playbookAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
3 things to look at
- 25 days oldThe repository was created 25 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
21.3 KB, ~5.0k tokens by cl100k_base, as published. Nobody here has run it
design-playbook
Design I/O — same process every run: inject declarations (what good is), run contracts (how work enters the pipeline), recirculate failures to the declaration that owns them.
Not a style library. For palettes/type catalogs use other packs; here the product pipeline and acceptance are the product.
Run contract
Keep each control in one authoritative place:
| Control | Single source | Required content |
|---|---|---|
| Goal | spec L1 | User-visible outcome, target user and scene, non-goals |
| Success | spec L6 | Observable pass/fail criteria; every top-level L6 item is Given -> When -> Then |
| Evidence | spec L6 + evaluator ledger | Exactly one L6.<n> ledger row per criterion; planning-only uses declaration coverage, implementation uses rendered states, interaction/test results, and applicable code checks |
| Stop | this orchestrator | Pass; smallest missing decision; unavailable required evidence or authority; repeated blocker |
| Confirm | this orchestrator + user decision | Any consequential action not already authorized |
Answer, review, diagnose, and plan requests end with findings or a plan. Build and fix requests continue through in-scope local edits and the most relevant available validation. Ask the smallest question only when the answer changes the goal, scope, platform, success criteria, or authority; otherwise record a conservative assumption in L1.
Pause for explicit confirmation before an external, destructive, costly, or scope-expanding action that the request did not already authorize. This includes adding a dependency, changing an API/backend/data contract, deploying or publishing, and accepting a blocking finding. When required evidence or authority is unavailable, stop with the exact blocker and the smallest next decision. If the same blocking finding survives two repair -> re-evaluate cycles without new evidence, stop recirculating and report it.
Steps
Stage-list mirror (monorepo maintainers only): repo-root
scripts/run_status.py→STAGESmirrors this section's steps and artifact filenames for status/resume narration. Not shipped with the installable plugin package (packages/design-playbook/). Plugin users ignore this pointer. If you add/remove a step or change an artifact filename here, update that monorepo table.
Do in order. Data flow:
design-baseline? → reference-intake? → ux-spec? → plan? → (native-craft?) → ui-picker → (preview*) → fill → craft-guard → (observe*) → ui-evaluator
?= conditional entry/route*= run only when the matching MCP tool is available (preview_prototypefor preview,execute_capture_planfor observe); otherwise skip- When you skip a step, say so in one line — step name + reason + how to enable, with the gate label when one applies. Matters most for
preview*/observe*adapter absence, e.g.-> preview*: adapter absent, skipped (G5 not triggered; enable via packages/design-playbook/mcp/preview/ or host MCP). Other conditional skips may use the same shape; entry lines are optional (keep output lean). Narration only — not a run-contract control. - Do not code a pretty shell until the active step’s completion criterion is met
1. Entry routing
SSOT for this decision is this skill only (not commands/design-io.md).
- Existing-product UI build/fix (meaningful first-party pages/components/theme/styles already exist) and no usable verified baseline binding under
.scratch/<run>/design-baseline/state.json→ step 1A.design-baseline - Reference materials present (screenshot, design file path, URL, or product/brand analogy) and no usable
.scratch/<run>/reference/contract.md→ step 2.reference-intake - Missing
spec(no usable six-layerspec.mdfor this run) → step 3.ux-spec - Spec present → step 4. plan (do not re-run
ux-specunless structural conflict forces it) - No meaningful existing UI, or no UI mutation in scope → skip
design-baselinewith one-line narration - No reference materials → skip
reference-intakewith one-line narration
1A. design-baseline (existing-product UI only)
Invoke design-baseline before reference intake or specification work. Call the deep module prepare → (user confirm/waive) → confirm as needed; immediately before Fill call verify. Discover and validate project DESIGN.md; if missing or incomplete, generate only run-local DESIGN.draft.md + evidence.json from first-party UI evidence and wait for confirmation before a durable write.
Gate artifact is only .scratch/<run>/design-baseline/state.json (schema: design-baseline/v1). A valid existing baseline becomes status: ready with decision.kind: existing. A generated draft requires confirm(..., "accept") (ready + accepted) or explicit confirm(..., "waive", reason=...) (waived). needs_confirmation and ambiguous block Fill. A draft alone is not authority.
Done when: design-baseline's own completion criteria hold (that skill is SSOT). Smoke: state.json exists; candidate conflicts and stale source hashes are exposed by prepare/verify; status is ready or waived; no valid baseline was silently replaced.
2. reference-intake (when reference materials present)
Invoke reference-intake. Produce .scratch/<run>/reference/contract.md + manifest.json (ADR-0011).
Done when: reference-intake's own completion criteria hold (that skill is SSOT). Smoke: sources inventoried; observed vs inferred labeled; Keep/Change/Do not copy present for product-analogy, third-party URL, and third-party screenshot/design; license/brand risks recorded. Does not write spec.md or a decision report.
Then continue to 3. ux-spec (or 4. plan when spec already exists).
3. ux-spec (when spec is missing)
Invoke ux-spec. Produce six-layer spec.md. When .scratch/<run>/reference/contract.md exists, ux-spec must read it first (functional constraints, non-goals, always/ask/never) — do not wait for plan.
Done when: ux-spec's own completion criteria hold (that skill is SSOT). Smoke: L1–L6 present; L5 substantive, not "show loading"; every top-level L6 item uses ordered Given -> When -> Then, names its evidence, and names the capture seed where the proof is a runtime state; reference constraints folded when a contract exists.
Then continue to 4. plan.
4. plan (pipeline step — pure orchestration)
Not a run-contract control and not a machine gate. Does not become Goal / Success / Evidence / Stop / Confirm SSOT.
Write a light handoff at .scratch/<run>/plan.md (required on disk). When .scratch/<run>/reference/contract.md exists, the handoff must point to it (path only; do not paste the full contract) and fold its functional constraints into the description→spec map and its visual cues/exclusions into the ui-picker input pack. Minimum three blocks:
- 本次 run 范围 — pointers to L2 / scenes / non-goals (do not copy L1–L6 wholesale)
- 用户描述 → spec 映射 — which L1/L2/L6 this ask touches; unmapped items → conservative assumptions
- ui-picker 输入包 — scene hints, constraints, explicit exclusions
禁止: paste the full spec; pre-write a decision report inside plan.
描述 × spec 分轨:
- Structural conflict (L1 outcome, L6 criteria, platform/permission/data contract, overturned non-goal) → stop; revise
ux-specor user Confirm of an exception recorded in plan - Presentation preference (scene density, region weight, component role preference without L6 change) → put in the ui-picker input pack;
ui-pickerdecides - Unmapped description → mapping table as conservative assumption; do not silently edit L1
Done when: plan.md exists with the three blocks; ui-picker can consume the input pack without re-deriving scope from chat.
5. Shell → conditional native-craft → ui-picker
Native desktop order: ux-spec → native-craft → ui-picker → fill → craft-guard → ui-evaluator. (Conditional entry ? and optional adapters preview*/observe* are shown in the full sequence above, step 0.)
- Invoke native-craft only for an explicit native-desktop target or a request for native-feel. Web and mobile Web skip
native-craft; a Web UI that merely resembles a desktop admin tool is still Web. - If the target platform is unclear, ask once before choosing the route. Do not assume native desktop.
- For native desktop, require the native decision gate and render-surface seam before invoking ui-picker. If
native-craftcannot load or does not produce them, stop and report what is missing; do not silently choose a Web shell. - Pass the decision gate and seam to ui-picker as required shell context. The caller does not reconstruct or reinterpret them.
Invoke ui-picker. Map scene → template + component semantics. Read its references/ only as that skill directs. When .scratch/<run>/reference/contract.md exists, pass its visual cues / exclusions (via plan input pack and/or direct path) into ui-picker.
Done when: ui-picker's own completion criteria hold (that skill is SSOT). Smoke: the decision report names scene, density, template, regions, components, and risks; coding has not started before that report exists. For native desktop, it also consumes the declared render-surface seam.
ui-picker stops at the decision report — it has no preview step.
6. preview* (optional external MCP adapter)
After the decision report exists, probe MCP tools/list for preview_prototype.
- Absent → skip preview; go to Fill (current behavior). No preview artifacts required.
- Present → run the preview loop in this orchestrator (not inside
ui-picker):- Host agent generates a disposable prototype HTML (structure-semantics floor: readable scene, named template regions, key component roles as placeholders). Path under
.scratch/<run>/preview/round-{n}.html. - Call
preview_prototypewithpath(preferred) orhtml, plussummary,round,report_ref(current decision report), optionaloptions. - Adapter shows the prototype, collects feedback, applies the feedback floor (ADR-0008: non-empty feedback, OR ≥1 anchor with non-empty selector + non-empty comment), writes confirm/log under
.scratch/<run>/preview/. A confirm that fails the floor is written withconfirmed: false+floor_failurereason — it does not count as a confirm. - On “需要修改” (or
confirmed: falsefrom a floor failure): append feedback topreview/log.md, revise the decision report in place (mark round), generate next prototype; same blocker two repair rounds without new evidence → stop the loop and report. - On confirmed: the tool's
confirmed=trueis not authoritative on its own — the confirm record must also carryfloor_pass: true. Proceed to Fill only with the confirmed + floor-passed decision report (+ plan pointers).
- Host agent generates a disposable prototype HTML (structure-semantics floor: readable scene, named template regions, key component roles as placeholders). Path under
Native desktop: still run Web preview when the adapter exists; coverage is render-surface seam and above only. Note that limitation once in preview/log.md. Do not skip preview solely because the route is native (skip only when the adapter is missing).
Hard boundary: never copy preview/round-*.html, preview-only assets, fake data shells, reference/assets/, or reference/example.html (or any other file under .scratch/<run>/reference/) into the Fill source tree. Fill consumes report + spec semantics, not prototype or reference media files.
Re-Fill signal (preview after Fill already exists): if a Fill surface (code under the host tree or filled-ui.*) already exists and a later preview round revises the decision report (new round, structural/component change absorbed into decision-report.md), you must re-Fill (or explicitly record user acceptance that the existing Fill already matches the new report) before observe* / ui-evaluator. Do not run observe against a Fill that predates the current confirmed report. Log the re-Fill (or acceptance) once in preview/log.md.
Done when: either preview was skipped (no adapter), or a confirm-round-*.json with confirmed: true and floor_pass: true matches the current decision report (G5 when validate_run.py is given --preview-dir / --decision-report). A confirmed record without floor_pass fails G5 — empty/garbage feedback is a silent false-pass that must not reach Fill. When Fill already existed, the re-Fill signal above is satisfied.
7. Fill
Implement structure from the decision report + spec + confirmed project DESIGN.md when bound. Prefer project tokens: visual values via var(--*); missing tokens → gaps.log (or project equivalent), not raw hex/px/ms.
Hard boundary (design baseline): for existing-product UI work, do not enter Fill unless design_baseline.verify(project_root, run_root) succeeds with status ready (bound path + sha256) or waived (non-empty reason). A draft alone is not authority.
Hard boundary (reference): never copy .scratch/<run>/reference/assets/, reference/example.html, or third-party brand media inventoried by reference-intake into the host Fill tree. Honor Do not copy via report + spec only.
If a reused host component conflicts with spec L5, record the conflict and recirculate to spec via the authoritative map in ui-evaluator before choosing a minimal patch or explicit acceptance.
Load on demand (only if the fill needs them):
- domain / risk / sensitive fields →
ui-picker/references/domain.md - token roles / gaps →
ui-picker/references/design.md - component pairs →
ui-picker/references/components.md
Done when: with a codebase — main flow renders and every L5 state named in the spec has a concrete UI path (not a blank region); planning-only — every L5 state has a named concrete UI landing, no blank region.
8. Craft → craft-guard
Invoke craft-guard. Apply loading tiers, motion purpose, hierarchy, CJK type. For native desktop, craft-guard owns shared UI above the render-surface seam and defers to native-craft below it. If a finding crosses the seam, split it into separate point-backs to the owning declarations.
Done when: craft-guard's own completion criteria hold (that skill is SSOT). Smoke: every wait/fail path maps to a loading tier; every animation states its purpose; L4 interactive-zone affordance resolved; residual issues handed to ui-evaluator with source craft.
9. observe* (optional external MCP adapter)
After craft, probe MCP tools/list for execute_capture_plan.
- Absent → skip;
ui-evaluatorledgerobservedstays free-text (current behavior). G6 not triggered. - Present → for each L6 criterion whose proof is a runtime state, run the evidence loop in this orchestrator (not inside any skill):
- Derive a capture plan from L6
Given -> When -> Then(in memory, not on disk):Given/When→state+actions;Then→ required proof (already in the ledgerrequiredfield). Do not add or remove verification intent; L6 wins on conflict. - Execute: call
execute_capture_plan({url, type, state, actions, artifact_path}). The provider returns{artifact, observed_state, result, error, written_path}and never sees the criterion. Preferwritten_path(absolute) when locating the file; if it points outside.scratch/<run>/, fixDESIGN_PLAYBOOK_RUN_ROOT/ cwd before binding.artifact_pathmust start withevidence/(e.g.,evidence/empty-state.png, notempty-state.png) — the provider resolves it under<run_root>/evidence/and refuses absolute paths,..segments, or anything that escapes that subtree (mcp/evidence/server.py_resolve_artifact_path); a bare filename is rejected because it would land outside the evidence subtree. - Bind (orchestrator owns the manifest; provider never writes it). After each successful or failed capture, immediately append one line to
.scratch/<run>/evidence/manifest.jsonl— do not batch-rewrite the file at the end. Rules:observed_state/result/error: copy the provider return verbatim. If the provider returnsunknown, writeunknown— never overwrite with the requestedstate(request intent lives only undercapture.state).- Embedded capture snapshot: store the full call parameters used (
urlincluding query string,type,state,actions,artifact_path). Omit nothing that would be needed to re-run the capture. ts: wall-clock of this capture's completion (ISO-8601). Distinct captures must not share one batch timestamp.- Also record: criterion ref,
artifact(run-root-relative), optionalartifact_sha256, optionalwritten_pathfrom the provider.
- Manual provider: when no ecosystem provider is present but a human operates + screenshots to
artifact_path, write the same-format manifest entry (capture.provider: "manual");observed_stateis what the human actually saw, not the planned label.
- Derive a capture plan from L6
- v1 capture types:
screenshot/a11y tree/interaction trace.
Capture surface (url choice — honesty, not a machine gate):
-
Prefer the live host — running Fill surface (dev server route / real app URL) that implements the decision report.
-
Semantic mirror (static HTML / fixture that only looks like Fill) is allowed only when the live host is unavailable or unsafe. Then all of:
- every manifest entry's capture snapshot includes
note(or equivalent) withsurface: mirrorand a one-line reason; - ui-evaluator must emit a finding (severity at least low) that observe used a mirror,
source=observe* seam(or preview*/observe* seam), and the fix is "re-capture on live host when available"; - do not claim G6/process Pass as proof that the Fill tree was runtime-verified.
- every manifest entry's capture snapshot includes
-
Mirror
data-state(recommended): when using a semantic mirror, set the page state the provider can read soobserved_stateis not forced tounknown. The evidence adapter readsbody[data-state]or[data-state](seemcp/evidence/server.py_read_observed_state). Example:<body data-state="empty"> <!-- empty-state UI for L6 empty criterion --> </body>Prefer one root marker that matches the capture plan's
stateintent. Still never inventobserved_statein the manifest — copy the provider return verbatim (unknown stays unknown).
Evidence is captured, not judged — copy provider returns verbatim here; pass/fail authority is the evaluator's (step 9 / ui-evaluator). Full authority model (three ledgers: spec names what to prove, manifest what happened, evaluator what it means): SSOT ui-evaluator step 2.
Done when: either observe was skipped (no provider, ledger observed free-text), or each runtime-proven criterion has a manifest entry whose artifact exists (G6 when validate_run.py is given --evidence-dir); and if any capture used a mirror surface, the point-back includes the required mirror finding.
10. Accept → ui-evaluator
Invoke ui-evaluator. Issues must point back to a declaration.
Done when: the report includes the criterion-shaped evidence ledger (criterion / required / observed / result) and findings as issue / source / fix / severity; the authoritative verdict completion criterion in ui-evaluator is met; and you show the user a short run artifact index (paths under .scratch/<run>/) so declaration products are discoverable — at minimum: design-baseline/ (if triggered), reference/ (if any), spec.md, plan.md, decision-report.md, preview/ (if any), Fill surface path, evidence/ (if any), point-back.md. One block is enough; do not only leave paths buried in tool logs.
Machine seam (optional local check): python scripts/validate_run.py <spec.md> <point-back.md> [--preview-dir <preview/>] [--decision-report <report>] [--evidence-dir <evidence/>] [--run-root <run>].
Recirculate
When a finding has no owner or you need the observable -> declaration routing, use the authoritative recirculate map in ui-evaluator (do not duplicate it here). Fix only the owning layer, then resume from the step that consumes it.
Contracts on this pipeline
| Contract | Skill |
|---|---|
| Discover/validate/generate the project visual baseline | design-baseline |
| Reference intake (observed/inferred + Keep/Change/Do not copy) | reference-intake |
| Write the functional declaration | ux-spec |
| Choose shell + component meaning | ui-picker |
| Craft / feedback quality | craft-guard |
| Native-feel desktop declaration (render seam + conventions) | native-craft |
| Acceptance + point-back critique | ui-evaluator |
plan, preview*, and observe* are orchestrator steps (plus optional external MCPs for preview and observe), not rows in this table. design-baseline? is a conditional existing-product orchestrator gate (ADR-0012); reference-intake? is a conditional skill step (ADR-0011), not a machine gate.
Slash (installed plugin, namespaced): /design-playbook:design-io · /design-playbook:ux-spec · /design-playbook:ui-review.
With claude --plugin-dir the same command files apply under the plugin namespace.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.