@hegemonart/get-design-done 1.36.1 → 1.36.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,14 +5,14 @@
5
5
  },
6
6
  "metadata": {
7
7
  "description": "Get Design Done — 5-stage agent-orchestrated design pipeline with 9 connections, handoff-first workflow, bidirectional Figma write-back, 22+ specialized agents, queryable knowledge layer (intel store, dependency analysis, learnings extraction), and a self-improvement loop (reflector, frontmatter + budget feedback, global-skills layer). v1.20.0 ships the SDK foundation: gdd-state MCP server (11 typed tools), lockfile-safe STATE.md mutations, event stream, and resilience primitives (jittered-backoff, rate-guard, error-classifier, iteration-budget) for rate-limit + 429 + context-overflow recovery. Full CI/CD pipeline (Node 22/24 × Linux/macOS/Windows) and release automation (auto-tag + GitHub Release + release-time smoke test).",
8
- "version": "1.36.1"
8
+ "version": "1.36.3"
9
9
  },
10
10
  "plugins": [
11
11
  {
12
12
  "name": "get-design-done",
13
13
  "source": "./",
14
14
  "description": "Agent-orchestrated 5-stage design pipeline: Brief → Explore → Plan → Design → Verify. 22+ specialized agents, 9 connections (Figma, Refero, Preview, Storybook, Chromatic, Figma Writer, Graphify, Pinterest, Claude Design), Claude Design handoff, bidirectional Figma write-back, and a queryable intel store (.design/intel/) for dependency and learnings queries. Standalone commands: style, darkmode, compare, figma-write, graphify, handoff, analyze-dependencies, skill-manifest, extract-learnings. Embeds NNG heuristics, WCAG thresholds, typographic systems, motion framework, and anti-pattern catalog. Ships with a full CI/CD pipeline (Node 22/24 × Linux/macOS/Windows) and release automation. Optimization layer (v1.0.4.1, retroactive): gdd-router + gdd-cache-manager skills, PreToolUse budget-enforcer hook, tier-aware agent frontmatter, lazy checker gates, streaming synthesizer, /gdd:warm-cache + /gdd:optimize commands, and cost telemetry at .design/telemetry/costs.jsonl — targeting 50-70% per-task token-cost reduction with no quality-floor regression. v1.20.0 SDK foundation: gdd-state MCP server (11 typed tools), lockfile-safe STATE.md mutations, event stream at .design/telemetry/events.jsonl, resilience primitives (jittered-backoff, rate-guard, error-classifier, iteration-budget) with rate-limit + 429 + context-overflow recovery, and TypeScript toolchain.",
15
- "version": "1.36.1",
15
+ "version": "1.36.3",
16
16
  "author": {
17
17
  "name": "hegemonart"
18
18
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "get-design-done",
3
3
  "short_name": "gdd",
4
- "version": "1.36.1",
4
+ "version": "1.36.3",
5
5
  "description": "Agent-orchestrated 5-stage design pipeline: Brief → Explore → Plan → Design → Verify. 22+ specialized agents, 9 connections (Figma, Refero, Preview, Storybook, Chromatic, Figma Writer, Graphify, Pinterest, Claude Design), handoff-first workflow via Claude Design bundles, bidirectional Figma write-back (annotations, Code Connect), queryable intel store (`.design/intel/`) for O(1) design surface lookups, and self-improvement loop (reflector agent, frontmatter + budget feedback, global-skills layer at `~/.claude/gdd/global-skills/`). Standalone commands: style, darkmode, compare, figma-write, graphify, handoff, analyze-dependencies, skill-manifest, extract-learnings, reflect, apply-reflections. Embeds NNG heuristics, WCAG thresholds, typographic systems, motion framework, and anti-pattern catalog. Ships with a full CI/CD pipeline (Node 22/24 × Linux/macOS/Windows, lint + schema + frontmatter + stale-ref + shellcheck + gitleaks + injection-scan + blocking size-budget) and release automation (auto-tag + GitHub Release + release-time smoke test). Optimization layer (v1.0.4.1, retroactive): gdd-router + gdd-cache-manager skills, PreToolUse budget-enforcer hook, tier-aware agent frontmatter, lazy checker gates, streaming synthesizer, /gdd:warm-cache + /gdd:optimize commands, and cost telemetry at .design/telemetry/costs.jsonl — targeting 50-70% per-task token-cost reduction with no quality-floor regression. v1.20.0 SDK foundation: gdd-state MCP server (11 typed tools), lockfile-safe STATE.md mutations, event stream at .design/telemetry/events.jsonl, resilience primitives (jittered-backoff, rate-guard, error-classifier, iteration-budget) with rate-limit + 429 + context-overflow recovery, and TypeScript toolchain. v1.27.7 ships gdd-mcp (Phase 27.7): 12 read-only MCP tools for sub-3s priming. v1.28.0 (Phase 28): Foundational References Tier 2 — 5 new reference files (color-theory, composition, proportion-systems, i18n, contrast-advanced), 2 verifier i18n probes + 1 explore i18n-readiness probe, 12 additive cross-link insertions across 10 existing references, 2 orthogonal audit-scoring lens-tags (composition_alignment + i18n_readiness).",
6
6
  "author": {
7
7
  "name": "hegemonart",
package/CHANGELOG.md CHANGED
@@ -4,6 +4,49 @@ All notable changes to get-design-done are documented here. Versions follow [sem
4
4
 
5
5
  ---
6
6
 
7
+ ## [1.36.3] - 2026-06-01
8
+
9
+ ### Phase 36.3 — Knowledge Tier-3: Conversational UI — completes Phase 36
10
+
11
+ Third and **FINAL** sub-phase of the split **Phase 36 (Knowledge Tier 3)** — completing it marks the **parent Phase 36 COMPLETE** (domain packs 36.1 + motion-tool verification 36.2 + conversational UI 36.3 all shipped). Conversational UI was zero-coverage even though it's a real surface (chatbot empty-states, voice flow design, prompt-as-UX). **No new pillar, no new runtime dependency, no new egress** (reference markdown + an agent-prompt enum addition).
12
+
13
+ ### Added
14
+
15
+ - **`reference/conversational-ui.md`** — voice-flow patterns (no-input / no-match reprompts, confirmation, human handoff), multi-turn dialogue (context carryover, slot-filling, repair), prompt-as-UX (the assistant persona/tone/boundaries as a versioned design artifact), chatbot empty-states + suggested replies, voice-first onboarding, and error recovery + accessibility (transcripts/captions). Carries a `## Detection signals` section + an `## Audit checklist`. Registered in `reference/registry.json` (`type: heuristic`, `phase: 36.3`; 149 → 150). CLI/REPL UX is out of scope this phase.
16
+ - **`agents/design-context-builder.md`** — Step 0E gains a **7th** project type `conversational` (enum 6 → 7). It routes to `design-executor` (a chat widget / voice-app card is still rendered code) **and loads `reference/conversational-ui.md`** for the interaction patterns. Detection from brief keywords (chatbot, voice, assistant, conversational) + `package.json` deps (`botpress`, `rasa`, `dialogflow`, `actions-on-google`, `ask-sdk-core`, `botframework`). The first six project types remain the Phase-34 rendered-output set; `conversational` is the Phase-36.3 interaction-surface type on the same axis.
17
+
18
+ ### Notes
19
+
20
+ - **No new runtime dependency, no new egress.** Detection is the agent matching keywords/deps; no code, no network.
21
+ - 6-manifest lockstep at **v1.36.3** + `OFF_CADENCE_VERSIONS.add('1.36.3')` + the 25 live-pinned `manifests-version.txt` baselines forward-propagated 1.36.2 → 1.36.3.
22
+ - Inventory relock: registry-diff 149 → 150, tarball golden 669 → 670 (+`reference/conversational-ui.md`). No new connection/skill/agent dir. `design-verifier.md` deliberately untouched (it is at its 700-line cap; conversational verify rides the normal web path).
23
+ - **This completes the parent Phase 36 (Knowledge Tier 3) — domain packs + motion-tool verification + conversational UI.**
24
+
25
+ ---
26
+
27
+ ## [1.36.2] - 2026-06-01
28
+
29
+ ### Phase 36.2 — Knowledge Tier-3: Motion-Tool Verification (Lottie + Rive)
30
+
31
+ Second sub-phase of the split **Phase 36**. Motion existed as a *principle* (Phase 18) but not as a *verifiable artifact* — Lottie/Rive ship animation exports + state machines and GDD never opened them. 36.2 adds a pure motion validator + two optional connections + a verify-time agent. **No new runtime dependency, no new egress** (pure `JSON.parse` + file checks; the Lottie player / Rive runtime are opt-in). Every motion finding is a **warning, never a blocker** (motion is creative, not contractually broken).
32
+
33
+ ### Added
34
+
35
+ - **`scripts/lib/motion/validate-motion.cjs`** — a pure, dependency-free (zero `require`) motion validator. `validateLottie(json, {bytes, budgetBytes})` checks frame-rate sanity, non-positive duration, layer count, embedded-asset bloat, and the perf budget (rules `MO-PARSE/FR/DUR/LAYERS/IMG/BUDGET`); `motionBudget` is the shared byte-cap check; `riveHeader` is the `.riv` magic-byte sanity. Deterministic.
36
+ - **`connections/lottie.md`** — file-probe connection for Lottie JSON exports; static floor = `validateLottie`; the live player is opt-in; degrade-to-static → code-only.
37
+ - **`connections/rive.md`** — file-probe connection for Rive `.riv` exports. `.riv` is binary, so the deep state-machine graph (unreachable states, no-exit loops) needs the opt-in Rive runtime; the pure-JS floor is size + the `RIVE` header + a manual-review advisory.
38
+ - **`agents/motion-verifier.md`** — at verify time, discovers Lottie/Rive exports, runs `validate-motion.cjs`, enforces a perf budget (`motion_budget_kb`, fallback 200 KB), and WARNs. Reads-only.
39
+ - **`agents/design-verifier.md`** — Phase 4E motion hook (gate on exports → delegate to `motion-verifier` → degrade-to-noop).
40
+ - **`connections/connections.md`** + onboarding — 19 → 21 (Lottie + Rive Active rows, `verify` capability-matrix entries, file probes, value-prop + setup matrix).
41
+
42
+ ### Notes
43
+
44
+ - **No new runtime dependency, no new egress.** The pure validator never opens the network; the Lottie player + Rive runtime are maintainer-supplied opt-ins (the print-render precedent).
45
+ - 6-manifest lockstep at **v1.36.2** + `OFF_CADENCE_VERSIONS.add('1.36.2')` + the 24 live-pinned `manifests-version.txt` baselines forward-propagated 1.36.1 → 1.36.2.
46
+ - Inventory relock: connection-list 27 → 29, phase-20 agent-list + frontmatter-snapshot += `motion-verifier`, onboarding → 21, tarball golden 665 → 669 (+4). Registry unchanged (no new `reference/` doc).
47
+
48
+ ---
49
+
7
50
  ## [1.36.1] - 2026-06-01
8
51
 
9
52
  ### Phase 36.1 — Knowledge Tier-3: Domain Packs (finance + healthcare + gaming + civic)
package/README.md CHANGED
@@ -154,6 +154,14 @@ Links a design cycle to a **Linear** or **Jira** ticket and keeps them in sync (
154
154
 
155
155
  Four industry-specific design-pattern packs at [`reference/domains/`](reference/domains/) — **finance** (data-table density, trading-UI color semantics, Reg-T/MiFID II disclosure, PCI-DSS masking, number-formatting precision), **healthcare** (HIPAA PHI isolation, audit-trail-as-UI, WCAG 2.1 AAA, medical-data viz), **gaming** (HUD/diegetic taxonomy, vestibular + photosensitive safety, ESRB/PEGI age-gates, controller/touch input adaptation), and **civic** (Section 508 + WCAG 2.1 AA floor, multi-language gov forms, Plain Writing Act, USWDS). The [`design-context-builder`](agents/design-context-builder.md) auto-detects the domain from brief keywords + `package.json` dependencies (`@stripe/`, `fhir`, `@react-three/fiber`, `@uswds/uswds`, …) and loads the matching pack into downstream context; [`design-auditor`](agents/design-auditor.md) folds each pack's audit checklist into the relevant pillar. Additive knowledge — no new pillar, no new runtime dependency. First sub-phase of Phase 36 (Motion-tool verification + Conversational UI follow).
156
156
 
157
+ ### Motion-tool verification (v1.36.2)
158
+
159
+ GDD now opens the motion **exports** a project ships. The pure, dependency-free [`validate-motion`](scripts/lib/motion/validate-motion.cjs) checks a **Lottie** JSON for frame-rate sanity, non-positive duration, embedded-asset bloat, and a perf budget (`MO-*` rules); for **Rive** `.riv` (binary) it does size + a `RIVE`-header sanity, and surfaces the state-machine graph (unreachable states, no-exit loops) when the opt-in Rive runtime is present. The [`motion-verifier`](agents/motion-verifier.md) agent runs at verify time ([`connections/lottie.md`](connections/lottie.md) / [`connections/rive.md`](connections/rive.md)) and **WARNs — never blocks** (motion is creative). **No new runtime dependency** — the Lottie player and Rive runtime are opt-in. Second sub-phase of Phase 36.
160
+
161
+ ### Conversational UI (v1.36.3)
162
+
163
+ [`reference/conversational-ui.md`](reference/conversational-ui.md) closes a zero-coverage surface: voice flows + chatbots. It codifies voice-flow reprompts (no-input / no-match → human handoff), multi-turn dialogue (context carryover, slot-filling, repair), **prompt-as-UX** (the assistant's persona/tone/boundaries as a versioned design artifact), chatbot empty-states + suggested replies, voice-first onboarding, and error recovery + accessibility. [`design-context-builder`](agents/design-context-builder.md) detects a `conversational` project type (brief keywords + chatbot/voice deps like `botpress` / `dialogflow` / `actions-on-google` / `ask-sdk-core`) and loads the pack into context. **No new runtime dependency.** This is the **final sub-phase of Phase 36 — which is now complete** (domain packs + motion-tool verification + conversational UI).
164
+
157
165
  ### Previous releases
158
166
 
159
167
  - **v1.26.0** — Headless Model Resolver (per-runtime tier→model map, `resolved_models` router field, per-runtime price tables, `reasoning-class` runtime-neutral alias).
@@ -218,7 +218,7 @@ Proceed to Step 0E regardless of whether Step 0D ran or was skipped.
218
218
 
219
219
  Detect the **project type** so the pipeline routes the brief to the correct executor. Reuse the Step 0C / Step 1 grep/glob idiom (file reads only, < 1 second, no skip condition).
220
220
 
221
- **Enum (6 values — D-06, the full set):** `web` (DEFAULT) · `native-ios` · `native-android` · `flutter` · `email` · `print`.
221
+ **Enum (7 values — D-06 + 36.3):** `web` (DEFAULT) · `native-ios` · `native-android` · `flutter` · `email` · `print` · `conversational`. (The first six are the Phase-34 *rendered-output* set; `conversational` is the Phase-36.3 *interaction-surface* type — a chat/voice UI is still rendered code, so it routes to `design-executor` but loads the conversational patterns.)
222
222
 
223
223
  **Detection signals + precedence** (first match wins; brief overrides — if the user explicitly says "iOS app" / "Android app" / "Flutter app" / "email" / "newsletter" / "email template" / "print" / "PDF" / "print-ready" / "brochure" / "flyer" / "poster", honor that):
224
224
 
@@ -228,10 +228,11 @@ ls *.xcodeproj Package.swift 2>/dev/null # → native-ios (when no pu
228
228
  ls build.gradle build.gradle.kts settings.gradle 2>/dev/null # → native-android (when no pubspec)
229
229
  ls **/*.mjml email/ emails/ templates/email 2>/dev/null # → email (email-template signals)
230
230
  ls **/*.print.css print/ templates/print 2>/dev/null # → print (print-output signals: a print stylesheet / print-template dir)
231
+ grep -lE '"(botpress|@botpress/|rasa|dialogflow|@google-cloud/dialogflow|actions-on-google|ask-sdk-core|botframework-webchat|@microsoft/botframework)"' package.json 2>/dev/null # → conversational (chatbot/voice-assistant deps)
231
232
  ls package.json 2>/dev/null # → web (default; also the fallback when none match)
232
233
  ```
233
234
 
234
- Precedence: an explicit brief override (the user says "email" / "newsletter" / "email template", or "print" / "PDF" / "print-ready" / "brochure" / "flyer" / "poster") wins like the other brief-overrides; otherwise `pubspec.yaml` (flutter) > `*.xcodeproj`/`Package.swift` (native-ios) > `build.gradle*`/`settings.gradle` (native-android) > `.mjml` files / an `email/` templates directory (email) > a print stylesheet (`*.print.css`) / a `print/` templates directory (print) > `package.json` / none (web — DEFAULT).
235
+ Precedence: an explicit brief override (the user says "email" / "newsletter" / "email template", or "print" / "PDF" / "print-ready" / "brochure" / "flyer" / "poster", or "chatbot" / "voice app" / "Alexa skill" / "conversational" / "assistant") wins like the other brief-overrides; otherwise `pubspec.yaml` (flutter) > `*.xcodeproj`/`Package.swift` (native-ios) > `build.gradle*`/`settings.gradle` (native-android) > `.mjml` files / an `email/` templates directory (email) > a print stylesheet (`*.print.css`) / a `print/` templates directory (print) > chatbot/voice deps (`botpress`/`rasa`/`dialogflow`/`actions-on-google`/`ask-sdk-core`/`botframework`) (conversational) > `package.json` / none (web — DEFAULT).
235
236
 
236
237
  **Routing table** (project type → executor — one row per type, trivially appendable):
237
238
 
@@ -243,10 +244,11 @@ Precedence: an explicit brief override (the user says "email" / "newsletter" / "
243
244
  | flutter | flutter-executor |
244
245
  | email | email-executor |
245
246
  | print | pdf-executor |
247
+ | conversational | design-executor (loads `reference/conversational-ui.md`) |
246
248
 
247
249
  <!-- Phase 34 output types complete: native (34.1: native-ios/native-android/flutter) + email (34.2) + print (34.3). Print is the FINAL Phase-34 output type — no further Phase-34 output types; the enum + routing table above are the full set. (34.1/34.2 kept this seam OPEN for the next type; 34.3 ties it off.) -->
248
250
 
249
- Record the detected type in DESIGN-CONTEXT.md as a `<project_type>` line (e.g. `<project_type>native-ios</project_type>`) so downstream stages route correctly. The native specifics (token→theme bridge) live in `reference/native-platforms.md`; the email specifics (table layout, inline styles, MSO/dark-mode constraints) live in `reference/email-design.md`; the print specifics (the `@page` box model, bleed/crop marks, CMYK awareness, font embedding, 300dpi raster) live in `reference/print-design.md` — do not inline any of them here.
251
+ Record the detected type in DESIGN-CONTEXT.md as a `<project_type>` line (e.g. `<project_type>native-ios</project_type>`) so downstream stages route correctly. The native specifics (token→theme bridge) live in `reference/native-platforms.md`; the email specifics (table layout, inline styles, MSO/dark-mode constraints) live in `reference/email-design.md`; the print specifics (the `@page` box model, bleed/crop marks, CMYK awareness, font embedding, 300dpi raster) live in `reference/print-design.md`; the conversational specifics (voice-flow reprompts, multi-turn dialogue, prompt-as-UX, chatbot empty-states, error recovery) live in `reference/conversational-ui.md` — do not inline any of them here.
250
252
 
251
253
  Proceed to Step 1 regardless of outcome.
252
254
 
@@ -368,6 +368,12 @@ When `<project_type>` is a **no-DOM target** — `native-ios`/`native-android`/`
368
368
 
369
369
  ---
370
370
 
371
+ ## Phase 4E — Motion Verification (when Lottie/Rive exports present)
372
+
373
+ **Gate + delegate:** when a Lottie (`*.json` with the `v`/`fr`/`layers` signature, or a `lottie-web` dep) or Rive (`*.riv`, or `@rive-app`) export is found, **delegate to `agents/motion-verifier.md`** — it runs the pure `scripts/lib/motion/validate-motion.cjs` (Lottie MO-* rules + perf budget; `.riv` size + `RIVE` header; Rive state-machine reachability when the runtime is present) and folds a `## Motion verification` block into DESIGN-VERIFICATION.md. None present → `motion verification: skipped.` **WARN, never block (D-02)** — motion findings are warnings unless a `must_have` requires them. Probe + degrade: `connections/lottie.md` / `connections/rive.md`.
374
+
375
+ ---
376
+
371
377
  ## Phase 4C — paper.design Canvas Screenshots (when paper-design: available)
372
378
 
373
379
  **Gate:** Skip this entire Phase 4C block if `paper-design` is `not_configured` or `unavailable` in STATE.md `<connections>`. Print: `paper.design canvas screenshots: skipped.`
@@ -0,0 +1,88 @@
1
+ ---
2
+ name: motion-verifier
3
+ description: Verify-time check for Lottie + Rive motion exports. Discovers exported animations, runs the pure scripts/lib/motion/validate-motion.cjs on Lottie (frame-rate / duration / embedded-asset / perf-budget), checks size + the RIVE magic header on .riv, and surfaces state-machine concerns (unreachable states, no-exit loops) when the Rive runtime is present. WARNs — never blocks (motion is creative, not contractually broken). Degrades to the static validator + a manual-review advisory when no player/runtime is configured.
4
+ tools: Read, Bash, Grep, Glob
5
+ color: green
6
+ default-tier: sonnet
7
+ tier-rationale: "Mechanical validation of exported animation artifacts via a deterministic pure helper + file checks; no design judgment — sonnet-tier, not an Opus plan."
8
+ size_budget: M
9
+ size_budget_rationale: "Honest tier sized to the ~130-line body (M cap 300). The agent states the discover → validate-Lottie → check-Rive → perf-budget → WARN flow and DELEGATES per-tool probe + degrade detail to connections/lottie.md + connections/rive.md and the rule semantics to scripts/lib/motion/validate-motion.cjs (the print-renderer→validate-print-css precedent)."
10
+ parallel-safe: true
11
+ typical-duration-seconds: 30
12
+ reads-only: true
13
+ writes: []
14
+ ---
15
+
16
+ @reference/shared-preamble.md
17
+
18
+ # motion-verifier
19
+
20
+ ## Role
21
+
22
+ At verify time, open the motion **exports** a project ships (Lottie JSON, Rive `.riv`) and surface motion-quality + performance concerns the 7-pillar code audit cannot see — frame-rate sanity, duration, embedded-asset bloat, bundle budget, and (for Rive) state-machine reachability. Motion exists as a *principle* (Phase 18); this agent makes it a *verifiable artifact*.
23
+
24
+ **Hard rule (D-02): WARN, never block.** Every finding is a warning in `DESIGN-VERIFICATION.md`, never a `<blocker>` — motion is creative, not contractually broken. The single exception: a `must_have` that *explicitly* requires motion verification (then a failed check escalates to that must_have).
25
+
26
+ ## When invoked
27
+
28
+ The verify stage (`agents/design-verifier.md`) delegates here **only when** Lottie/Rive exports are present (per `connections/lottie.md` / `connections/rive.md` probes). No exports → this agent does not run. The probes + the three-value `<connections>` schema live in those two connection specs — do not duplicate them here.
29
+
30
+ ## Step 1 — Discover motion exports
31
+
32
+ ```bash
33
+ # Lottie: JSON files carrying the Lottie signature (top-level v / fr / layers), or a lottie dep
34
+ find . -name "*.json" -not -path "*/node_modules/*" -not -path "*/.git/*" 2>/dev/null | head -50
35
+ grep -rEl '"(lottie-web|@lottiefiles/|lottie-react)"' package.json 2>/dev/null
36
+ # Rive: binary .riv exports, or an @rive-app dep
37
+ find . -name "*.riv" -not -path "*/node_modules/*" 2>/dev/null | head -50
38
+ grep -rE '@rive-app|rive-react' package.json 2>/dev/null
39
+ ```
40
+
41
+ For each candidate `*.json`, confirm the Lottie signature before validating (a `package.json` is not a Lottie). The validator does this check itself (returns `MO-PARSE` for non-Lottie), so it is safe to pass any JSON.
42
+
43
+ ## Step 2 — Validate Lottie (deterministic, always available)
44
+
45
+ Run the **pure** validator `scripts/lib/motion/validate-motion.cjs` — zero dependencies, no player, no network:
46
+
47
+ ```bash
48
+ node -e "const {validateLottie}=require('./scripts/lib/motion/validate-motion.cjs');const fs=require('fs');const f=process.argv[1];const bytes=fs.statSync(f).size;const r=validateLottie(fs.readFileSync(f,'utf8'),{bytes,budgetBytes:BUDGET});console.log(JSON.stringify(r))" path/to/animation.json
49
+ ```
50
+
51
+ Map each returned warning to a verify finding (all WARN):
52
+
53
+ | Rule | Meaning |
54
+ |------|---------|
55
+ | `MO-PARSE` | not valid JSON / not a Lottie document |
56
+ | `MO-FR` | frame rate outside the sane 1–120 range |
57
+ | `MO-DUR` | non-positive duration (`op <= ip`) |
58
+ | `MO-LAYERS` | very high layer count — review runtime cost |
59
+ | `MO-IMG` | embedded raster asset(s) — prefer external/optimized images |
60
+ | `MO-BUDGET` | bundle exceeds the KB cap (see Step 4) |
61
+
62
+ The validator also returns `info` (fr, layers, durationSeconds, embeddedAssets) — narrate it in the report.
63
+
64
+ ## Step 3 — Check Rive (`.riv` is binary — be honest, D-04)
65
+
66
+ Pure JS cannot parse the `.riv` state-machine graph. The static floor is:
67
+
68
+ - **`riveHeader(bytes)`** — confirm the file begins with the ASCII magic `RIVE` (a corrupt/mislabelled export fails this).
69
+ - **`motionBudget(bytes, budgetBytes)`** — the same perf-budget check as Lottie (Step 4).
70
+
71
+ **Deep state-machine validation** — no unreachable states, no infinite loops without an exit transition — requires the **Rive runtime** (`@rive-app/canvas` / the Rive CLI), which is opt-in / maintainer-supplied (per `connections/rive.md`). When it is present, enumerate the file's state machines + inputs and flag unreachable states / no-exit loops as WARN. When it is absent, emit a **manual-review advisory**: "Rive runtime not configured — open the `.riv` in the Rive editor/runtime and confirm every state is reachable and every loop has an exit." Never block on its absence.
72
+
73
+ ## Step 4 — Performance budget
74
+
75
+ Read the cap from `.design/config.json` → `motion_budget_kb` (fallback **200 KB**, `DEFAULT_BUDGET_BYTES`). Pass `budgetBytes = motion_budget_kb * 1024` to the validator / `motionBudget`. An over-budget export is an `MO-BUDGET` warning, not a blocker.
76
+
77
+ ## Degrade behavior
78
+
79
+ - No Lottie player / no Rive runtime → the pure `validate-motion.cjs` (Lottie) + size/header (Rive) is the deterministic floor; then a code-only review of how the animation is loaded/triggered. Never blocks (D-03).
80
+ - No motion exports at all → this agent is not invoked.
81
+
82
+ ## Record
83
+
84
+ Emit a `## Motion verification` section for `DESIGN-VERIFICATION.md`: per-file findings (file → rules → detail), the `info` narration, the budget used, and the Rive advisory when applicable. Tag each finding **WARN**. Close with the completion marker:
85
+
86
+ ```
87
+ ## MOTION VERIFICATION COMPLETE
88
+ ```
@@ -2,7 +2,7 @@
2
2
 
3
3
  This directory contains connection specifications for external tools and MCPs that the get-design-done pipeline integrates with. Each connection has its own spec file. This file is the index.
4
4
 
5
- **Getting started:** run `/gdd:connections` for the interactive onboarding wizard — it probes all 19 connections, recommends setup based on your project type, and walks you through installing each one (auto-run for reversible MCP adds, copy-command for everything else). You can also run `/gdd:connections list` for a read-only status check or `/gdd:connections <name>` to jump to a single connection's setup.
5
+ **Getting started:** run `/gdd:connections` for the interactive onboarding wizard — it probes all 21 connections, recommends setup based on your project type, and walks you through installing each one (auto-run for reversible MCP adds, copy-command for everything else). You can also run `/gdd:connections list` for a read-only status check or `/gdd:connections <name>` to jump to a single connection's setup.
6
6
 
7
7
  ---
8
8
 
@@ -35,6 +35,8 @@ This directory contains connection specifications for external tools and MCPs th
35
35
  | Linear | Active | [`connections/linear.md`](connections/linear.md) | **Ticket-sync** (Team Surfaces) — `mcp__linear__*` (ToolSearch probe); bidirectional cycle↔issue; redact + `GDD_DISABLE_LINEAR` kill-switch; degrade-to-noop |
36
36
  | Jira | Active | [`connections/jira.md`](connections/jira.md) | **Ticket-sync** (Team Surfaces) — Atlassian MCP `mcp__atlassian__*` (ToolSearch probe); parity with Linear; `GDD_DISABLE_JIRA` kill-switch; degrade-to-noop |
37
37
  | Notion | Active | [`connections/notion.md`](connections/notion.md) | **Export** write-path (not a pipeline stage) — `mcp__notion__*` (ToolSearch probe); `/gdd:export --format notion`; redact + `GDD_DISABLE_NOTION` kill-switch; degrade-to-HTML |
38
+ | Lottie | Active | [`connections/lottie.md`](connections/lottie.md) | **Optional** motion verify (Lottie JSON); static floor = `validate-motion.cjs` (MO-* warnings + perf budget); player opt-in; WARN-never-block, degrade-to-static/code-only (36.2, D-02/D-03) |
39
+ | Rive | Active | [`connections/rive.md`](connections/rive.md) | **Optional** motion verify (Rive `.riv`); size + RIVE-header floor; deep state-machine graph via opt-in Rive runtime, else manual-review advisory; WARN-never-block (36.2, D-02/D-04) |
38
40
 
39
41
  ---
40
42
 
@@ -62,6 +64,8 @@ Each cell describes what the connection contributes at that pipeline stage, or `
62
64
  | Android Emulator | — | — | — | native Android code-gen target (compose-executor / emitCompose) | rendered Compose screenshot when emulator available, else degrade to code-only structural audit (D-03) | — | — | — | — |
63
65
  | Litmus | — | — | — | email render-test target (email-executor) | cross-client rendered evidence when Litmus available, else degrade to the static email-HTML validator / code-only (D-03) | — | — | — | — |
64
66
  | Print-Renderer | — | — | — | print render-test target (pdf-executor) | rendered PDF/page evidence when the print-render is available, else degrade to the static print-CSS validator / code-only (D-03) | — | — | — | — |
67
+ | Lottie | — | — | — | — | Lottie-export motion check: `validate-motion.cjs` (MO-FR/DUR/IMG/BUDGET) when present, WARN-never-block (D-02) | — | — | — | — |
68
+ | Rive | — | — | — | — | Rive-export motion check: size + RIVE-header floor; state-machine graph via opt-in runtime, else manual-review advisory; WARN (D-02/D-04) | — | — | — | — |
65
69
  | Lazyweb | — | reference search via `lazyweb_search` (**Tier 1 — free, tried first**; D-01); complements refero/pinterest | — | — | — | — | — | — | — |
66
70
  | Mobbin | — | reference search via mobbin tools (**Tier 2 — paid, mobile/flow-level**; D-01); complements refero/lazyweb | — | — | — | — | — | — | — |
67
71
  | Slack | — | — | — | — | — | — | — | verify-fail/audit-pass/ship → Slack webhook (routed, redacted, degrade-to-noop; D-04/D-05) | — |
@@ -0,0 +1,126 @@
1
+ # Lottie — Connection Specification
2
+
3
+ This file is the connection specification for the Lottie motion-export check within the get-design-done pipeline. It lives in `connections/` alongside the other connection specs (the closest analog is `connections/print-renderer.md`, the verify-stage rendered-proof connection for the `print` project type). See the connection index for the full connection capability matrix (the Lottie row is added at the 36.2 Wave-B wiring plan).
4
+
5
+ ---
6
+
7
+ Lottie is a JSON animation format (Bodymovin / lottie-web). This connection is the **verify stage's motion check for Lottie exports** — the animation analog of the print-render. Its pipeline role: after a design exports a Lottie `*.json` bundle, the verify stage runs the **pure static validator** to surface structural and perf problems the JSON carries (bad frame rate, zero-length duration, layer/asset bloat, oversized bundle), and — **when a live player is configured** — renders actual playback to catch what the JSON alone cannot show. It narrates the result in plain English in `DESIGN-VERIFICATION.md`. It is consumed at verify time by the `motion-verifier` agent.
8
+
9
+ **Key relationship to the static validator:** the live Lottie player is the *rendered* complement to the *static* validator `scripts/lib/motion/validate-motion.cjs`. The static validator deterministically parses the Lottie JSON (zero dependencies) and checks constraint **classes** via `validateLottie(json, {bytes, budgetBytes})` — returning `{ok, warnings:[{rule,detail}], info}` with rules `MO-PARSE` (not valid JSON / not a Lottie document) / `MO-FR` (frame rate outside the sane 1-120 range) / `MO-DUR` (non-positive duration, `op <= ip`) / `MO-LAYERS` (layer count high, runtime cost) / `MO-IMG` (embedded raster `data:` assets bloat the bundle) / `MO-BUDGET` (bundle exceeds the KB cap, shared with `motionBudget`). A live player checks the **rendered output** — what actually plays. The player is **optional** — its absence is a quality reduction, not a blocking error (D-02).
10
+
11
+ ---
12
+
13
+ ## Setup
14
+
15
+ **Prerequisites:**
16
+
17
+ - **STATIC FLOOR — the pure validator (always available):** `scripts/lib/motion/validate-motion.cjs` is pure and dependency-free (D-01) — zero `require`, no Lottie runtime, deterministic (hermetic tests). It needs **no player and no network**. It parses the Lottie JSON and emits the `MO-*` warnings. This is the floor and it is always present.
18
+ - **OPTIONAL — a live Lottie player (opt-in, maintainer-supplied):** to render *actual playback*, a player is needed — `lottie-web` driven in headless Chrome, or `@lottiefiles/lottie-player`. This is opt-in; like the print-render, prefer a no-external-package path where possible, and where a player IS needed it is supplied by the maintainer in the verify stage — never installed by the pipeline.
19
+
20
+ Per **D-01** there is **NO bundled `lottie-web` / `@lottiefiles/*` dependency** and **no live playback in the default `npm test`** — the pure validator carries the whole hermetic test surface. A live player is an optional, opt-in enhancement the maintainer wires up in the verify stage when one is present.
21
+
22
+ **Verification:**
23
+
24
+ ```bash
25
+ node -e "require('./scripts/lib/motion/validate-motion.cjs').validateLottie" 2>/dev/null && echo "static validator OK"
26
+ ```
27
+
28
+ ---
29
+
30
+ ## Why the Lottie check is useful
31
+
32
+ Motion breakage is largely invisible to code review, and rendered breakage is invisible to the static validator. A Lottie bundle can be well-formed JSON and still ship problems: a frame rate of `0` or `240` (the `MO-FR` band is 1-120), a zero-length or reversed timeline (`op <= ip`, `MO-DUR`), hundreds of layers that tank runtime on low-end devices (`MO-LAYERS`), or a 4MB bundle because a designer baked full-resolution PNGs into the JSON as inline `data:` URIs (`MO-IMG` + `MO-BUDGET`). The static validator catches all of these deterministically, from the JSON alone, with no player.
33
+
34
+ The static validator checks constraint **classes**; it cannot play the animation. A live player renders the **actual** timeline, so playback-only defects — an expression that throws at runtime, a mask that clips wrong, a marker that never fires — surface as observable output rather than a broken animation shipped to production.
35
+
36
+ ---
37
+
38
+ ## When to use the Lottie check
39
+
40
+ **Verify stage:** After a design exports a Lottie `*.json`, run the static validator `validateLottie(json, {bytes, budgetBytes})` — always — to surface the `MO-*` warnings, and run a live player **when available** to capture rendered playback. The verify stage narrates the delta and notes it in `DESIGN-VERIFICATION.md`.
41
+
42
+ The Lottie check is **not** used at generation time. Exporting or hand-authoring a Lottie JSON needs no player, no `lottie-web` runtime, and no network — the pure validator runs anywhere Node runs.
43
+
44
+ ---
45
+
46
+ ## Availability Probe
47
+
48
+ The Lottie connection is discovered by a **file-based** probe (NOT ToolSearch): look for Lottie export artifacts and/or a player dependency.
49
+
50
+ **Step LO1 — Lottie artifact / player presence:**
51
+
52
+ ```bash
53
+ # (a) any JSON files at all?
54
+ find . -name "*.json" -not -path "*/node_modules/*" | head
55
+
56
+ # (b) does one carry the Lottie signature — top-level v, fr, and a layers[] array?
57
+ node -e 'const j=require(process.argv[1]); process.exit(j&&typeof j==="object"&&"v" in j&&"fr" in j&&Array.isArray(j.layers)?0:1)' ./path/to/export.json && echo "Lottie export found"
58
+
59
+ # (c) is a player declared as a dependency?
60
+ grep -E '"(lottie-web|@lottiefiles/[^"]+|lottie-react)"' package.json
61
+ ```
62
+
63
+ - A Lottie export (signature match) OR a player dependency is found → proceed to Step LO2
64
+ - Neither a Lottie artifact nor a player → `lottie: not_configured` (skip all Lottie steps; nothing to verify)
65
+
66
+ **Step LO2 — player capability check:**
67
+
68
+ - A Lottie export is present (or a player is declared) and verification can proceed → `lottie: available` (the static validator alone is enough to be `available` — it is the floor)
69
+ - A player is declared but errors when invoked (missing headless Chrome, broken `@lottiefiles/*` install) → `lottie: unavailable` (fall back to the static validator)
70
+
71
+ **Write the Lottie status to `.design/STATE.md` `<connections>` immediately after probing** — the three-value schema the other connections use (`available` / `unavailable` / `not_configured`).
72
+
73
+ ---
74
+
75
+ ## Fallback Behavior
76
+
77
+ When the Lottie player is `not_configured` or `unavailable`, the verify stage degrades gracefully — no error is raised.
78
+
79
+ **verify stage (the `motion-verifier` agent):**
80
+
81
+ - `lottie: unavailable` → skip rendered playback; **degrade** to the pure validator `scripts/lib/motion/validate-motion.cjs` (the `MO-PARSE/FR/DUR/LAYERS/IMG/BUDGET` warnings), then a **code-only** review of the Lottie JSON structure; note in `DESIGN-VERIFICATION.md`: "Lottie playback skipped — no live player; verified via the static motion validator + a code-only review."
82
+ - `lottie: not_configured` → same as unavailable; note: "Lottie playback skipped — no player configured; verified via the static validator + a code-only review. (A live player — lottie-web in headless Chrome / @lottiefiles/lottie-player — is an opt-in enhancement.)"
83
+
84
+ **Graceful degradation required:** the pipeline must continue when the player is unavailable. Missing rendered-playback data is a **quality reduction, not a blocking error** (D-02 — motion is creative, not contractually broken; the player is an enhancement, never hard-required). The pure validator is always available and is the deterministic floor; the live player is the rendered ceiling on top of it.
85
+
86
+ **WARN, never block (D-02):** every motion finding — every `MO-*` warning and every playback observation — is recorded as a **warning** in `DESIGN-VERIFICATION.md`, **never** a `<blocker>`. The motion-verifier does NOT append a blocker for a missing Lottie connection or for any `MO-*` warning. The single exception: if a `must_have` explicitly requires motion verification, THEN — and only then — an unmet motion requirement may escalate to a blocker.
87
+
88
+ ---
89
+
90
+ ## STATE.md Integration
91
+
92
+ Every stage that probes the Lottie connection writes the result to `.design/STATE.md` under the `<connections>` section:
93
+
94
+ ```xml
95
+ <connections>
96
+ figma: available
97
+ preview: available
98
+ lottie: not_configured
99
+ </connections>
100
+ ```
101
+
102
+ **Status values:**
103
+
104
+ | Value | Meaning |
105
+ |---|---|
106
+ | `available` | A Lottie export is present (or a player is declared) and verification can proceed — the static validator alone satisfies this |
107
+ | `unavailable` | A player is declared but the playback call errored (no headless Chrome, broken `@lottiefiles/*` install) — degrade to the static validator |
108
+ | `not_configured` | No Lottie artifacts and no player dependency — there is nothing to verify |
109
+
110
+ The verify stage re-probes at stage entry (exports and player availability can change between sessions). If STATE.md already carries a `lottie:` status from a prior stage in the SAME session, that status can be trusted for the rest of that session.
111
+
112
+ ---
113
+
114
+ ## Caveats and Pitfalls
115
+
116
+ 1. **The live player is an enhancement, not a requirement.** Its absence degrades to the static validator + a code-only review and never blocks the pipeline (D-02). Do not gate a motion export on rendered playback.
117
+
118
+ 2. **Every motion finding is a warning.** Motion is creative, not contractually broken (D-02). A `MO-FR` / `MO-LAYERS` / `MO-IMG` warning informs the designer; it does not fail the build. Only an explicit `must_have` for motion verification can escalate a finding to a blocker.
119
+
120
+ 3. **The budget is a shared, configurable cap.** `MO-BUDGET` fires only when the caller passes `opts.bytes` (the on-disk size); the cap is `opts.budgetBytes` or the 200 KB `DEFAULT_BUDGET_BYTES` fallback (D-05, when config carries no `motion_budget_kb`). `motionBudget(bytes, budgetBytes)` is shared by the Lottie and Rive paths — keep the unit math (KB = bytes / 1024) consistent.
121
+
122
+ 4. **The signature gate is strict.** `validateLottie` only proceeds when the JSON has top-level `v`, `fr`, AND a `layers[]` array; anything else returns a single `MO-PARSE` warning ("not a Lottie document"). The file probe must use the same three-key signature so the connection does not misfire on unrelated `*.json` files.
123
+
124
+ 5. **No bundled player dependency.** Do NOT add `lottie-web` / `@lottiefiles/*` / `lottie-react` to `package.json` to make this connection work — the player is opt-in and the maintainer supplies it. The default `npm test` stays hermetic and runs only the pure validator (D-01).
125
+
126
+ 6. **Do NOT edit the connection index here.** The Lottie connection's Active-Connections entry and Capability-Matrix row are added by the 36.2 Wave-B wiring plan, not by this spec (the disjointness pattern `print-renderer.md` uses).
@@ -0,0 +1,122 @@
1
+ # Rive — Connection Specification
2
+
3
+ This file is the connection specification for the Rive motion-export check within the get-design-done pipeline. It lives in `connections/` alongside the other connection specs (the closest analog is [`connections/print-renderer.md`](print-renderer.md), the verify-stage RENDERED proof for the `print` project type, and its sibling `connections/lottie.md` covers the JSON-vector motion format). See the connection index for the full connection capability matrix (the Rive row is added at the 36.2 Wave-B wiring plan).
4
+
5
+ ---
6
+
7
+ Rive is the **verify stage's motion check for Rive exports** — interactive animations Rive ships as **binary `.riv` files** that bundle **state machines** (states, transitions, inputs) rather than a linear timeline. Its pipeline role: after a design surface produces a `.riv` artifact, the verify stage uses this connection — **when the Rive runtime is available** — to enumerate the file's state machines and surface graph hazards the static floor cannot see (unreachable states, loops with no exit transition), and narrates the result in plain English. It is consumed at verify time by the `motion-verifier` agent.
8
+
9
+ **Key relationship to the static floor:** `.riv` is a **binary** format, so **pure JavaScript cannot parse the state-machine graph** without the Rive runtime. The static floor in `scripts/lib/motion/validate-motion.cjs` is therefore deliberately narrow — it provides [`riveHeader(headerBytes)`](../scripts/lib/motion/validate-motion.cjs) (a cheap magic-byte sanity check: every `.riv` file begins with the ASCII magic `RIVE`) and `motionBudget(bytes, budgetBytes)` (the shared KB-cap perf-budget check that also backs the Lottie path, rule `MO-BUDGET`). The **deep state-machine validation** the ROADMAP wants — no unreachable states, every loop has an exit transition — lives *above* that floor and needs the Rive runtime. This connection is the **runtime ceiling** on top of the deterministic header+budget floor; its absence is a quality reduction, not a blocking error (D-04).
10
+
11
+ ---
12
+
13
+ ## Setup
14
+
15
+ **Prerequisites:**
16
+
17
+ - **PRIMARY — the Rive runtime:** `@rive-app/canvas`, `@rive-app/react-canvas`, or the Rive CLI. When present, the runtime loads the `.riv` file, enumerates its state machines + inputs, and lets the agent walk the transition graph to check reachability and exit conditions. No bundled dependency is required to *probe*; the runtime is opt-in — prefer a built-in / no-external-package path where possible, and where the runtime IS needed it is maintainer-supplied (never installed by the pipeline).
18
+ - **ALTERNATIVE — header + budget floor only:** where no Rive runtime is available, `scripts/lib/motion/validate-motion.cjs` still runs `riveHeader` (magic-byte sanity) and `motionBudget` (the KB cap) on the raw bytes. This is the documented pure-JS path and needs no dependency at all.
19
+
20
+ Per **D-01** there is **NO bundled `@rive-app/*` (or `rive-react` / Rive CLI) dependency** and **no live state-machine walk in the default `npm test`** — the deep graph check is an optional, opt-in enhancement the maintainer wires up in the verify stage when the Rive runtime is present. The header+budget floor stays hermetic and dependency-free (D-06).
21
+
22
+ **Verification:**
23
+
24
+ ```bash
25
+ node -e "require('@rive-app/canvas')" 2>/dev/null && echo "rive-runtime ok" || command -v rive 2>/dev/null
26
+ ```
27
+
28
+ ---
29
+
30
+ ## Why Rive is useful
31
+
32
+ State-machine breakage is invisible to both code review and the binary header floor. A `.riv` file can pass `riveHeader` (correct magic), sit comfortably under the `motionBudget` KB cap, and still ship broken: a state nobody can transition into (an **unreachable state** — dead art that never plays), or a loop of transitions with **no exit condition** (the machine spins forever and the input that should release it was never wired). Neither hazard is a malformed file, so a magic-byte + size check cannot catch them — they are properties of the *transition graph*, and the graph is locked inside the binary.
33
+
34
+ The header floor checks that the bytes are a plausible `.riv` and fit the budget; it cannot read the graph. With the Rive runtime present, this connection loads the actual file, enumerates state machines and inputs, and walks transitions so unreachable states and exit-less loops surface as a verify-time warning rather than a frozen or never-firing animation in production.
35
+
36
+ ---
37
+
38
+ ## When to use Rive
39
+
40
+ **Verify stage:** After a design surface produces a `.riv` artifact, run this connection — when the Rive runtime is available — to enumerate state machines + inputs and check that every state is reachable and every loop has an exit transition. The verify stage narrates the delta and notes it in `DESIGN-VERIFICATION.md`.
41
+
42
+ This connection is **not** used at generation time. Producing or hand-editing a `.riv` needs no runtime from the pipeline, and the header+budget floor never gates generation — generation stays runtime-free (D-01/D-06). The deep graph walk is strictly a verify-time enhancement.
43
+
44
+ ---
45
+
46
+ ## Availability Probe
47
+
48
+ Rive is discovered by a **file-based** check (NOT ToolSearch): is there a `.riv` artifact to verify, and/or is the Rive runtime installed to verify it with?
49
+
50
+ **Step RV1 — Rive artifact / runtime presence:**
51
+
52
+ ```bash
53
+ find . -name "*.riv" -not -path "*/node_modules/*" 2>/dev/null | head -1
54
+ grep -qE '"(@rive-app/[a-z-]+|rive-react)"' package.json 2>/dev/null && echo "rive-dep" || true
55
+ ```
56
+
57
+ - A `.riv` file is found OR a `@rive-app/*` / `rive-react` dependency is declared → proceed to Step RV2
58
+ - Neither a `.riv` artifact nor a Rive dependency → `rive: not_configured` (skip all Rive steps)
59
+
60
+ **Step RV2 — runtime capability check:**
61
+
62
+ ```bash
63
+ node -e "require('@rive-app/canvas')" 2>/dev/null && echo "runtime ok" || command -v rive 2>/dev/null
64
+ ```
65
+
66
+ - The Rive runtime (`@rive-app/*`) or the Rive CLI loads and can enumerate state machines → `rive: available`
67
+ - A runtime is present but errors on load / cannot read the file (version mismatch, corrupt `.riv`, sandbox) → `rive: unavailable`
68
+ - A `.riv` exists but no runtime at all → `rive: available` for the **floor only** (header + budget run; the deep graph walk degrades to the manual-review advisory below)
69
+
70
+ **Write the Rive status to `.design/STATE.md` `<connections>` immediately after probing** — the three-value schema the other connections use (`available` / `unavailable` / `not_configured`).
71
+
72
+ ---
73
+
74
+ ## Fallback Behavior
75
+
76
+ When Rive is `not_configured`, or `unavailable`, or a `.riv` exists with no runtime, the verify stage degrades gracefully — no error is raised.
77
+
78
+ **verify stage (`motion-verifier` agent):**
79
+
80
+ - **No runtime (`.riv` present, runtime absent)** → skip the state-machine walk; **degrade** to the static floor in `scripts/lib/motion/validate-motion.cjs` — `riveHeader` (magic-byte sanity) + `motionBudget` (the KB cap) — then emit a documented **manual-review advisory**; note in `DESIGN-VERIFICATION.md`: "Rive state-machine check skipped — no Rive runtime; verified `.riv` header + size budget only. Manual review: open the file in the Rive editor / runtime and confirm every state is reachable and every loop has an exit transition."
81
+ - `rive: unavailable` (runtime present but errored) → same degrade to header + budget + the manual-review advisory; note: "Rive runtime present but failed to load the file — verified header + budget only; confirm reachability and loop-exit manually in the Rive editor."
82
+ - `rive: not_configured` (no `.riv`, no dependency) → skip the connection entirely; note: "No Rive artifacts — Rive motion check not applicable."
83
+
84
+ **Graceful degradation required:** the pipeline must continue when the Rive runtime is unavailable. Missing state-machine data is a **quality reduction, not a blocking error** (D-04 — the deep graph walk is an enhancement, never hard-required, mirroring the print-renderer / Lottie connections). The header+budget floor is always available and is the deterministic floor; the runtime walk is the ceiling on top of it. The verify stage does **not** append a `<blocker>` for a missing Rive runtime. If a `must_have` explicitly requires verified state-machine reachability, THEN append a blocker.
85
+
86
+ ---
87
+
88
+ ## STATE.md Integration
89
+
90
+ Every stage that probes Rive writes the result to `.design/STATE.md` under the `<connections>` section:
91
+
92
+ ```xml
93
+ <connections>
94
+ figma: available
95
+ preview: available
96
+ rive: not_configured
97
+ </connections>
98
+ ```
99
+
100
+ **Status values:**
101
+
102
+ | Value | Meaning |
103
+ |---|---|
104
+ | `available` | A `.riv` artifact or the Rive runtime is found (runtime → deep walk; floor-only → header + budget) |
105
+ | `unavailable` | A Rive runtime is present but errored loading the file (version mismatch, corrupt `.riv`, sandbox) |
106
+ | `not_configured` | No `.riv` artifacts and no `@rive-app/*` / `rive-react` dependency — Rive is not set up |
107
+
108
+ The verify stage re-probes at stage entry (runtime availability and the presence of `.riv` artifacts can change between sessions). If STATE.md already carries a `rive:` status from a prior stage in the SAME session, that status can be trusted for the rest of that session.
109
+
110
+ ---
111
+
112
+ ## Caveats and Pitfalls
113
+
114
+ 1. **The deep state-machine walk is an enhancement, not a requirement.** Its absence degrades to `riveHeader` + `motionBudget` + a manual-review advisory and never blocks the pipeline (D-04). Do not gate a Rive build on a verified transition graph.
115
+
116
+ 2. **`.riv` is binary — pure JS cannot read the graph (D-04).** `riveHeader` confirms only the `RIVE` magic bytes; it says nothing about states, transitions, or inputs. Reachability and loop-exit checks are *graph* properties locked inside the binary and require the Rive runtime. Never imply the header check validated the state machine — be honest in `DESIGN-VERIFICATION.md` about which tier ran.
117
+
118
+ 3. **WARN, never block (D-02).** Unreachable states, exit-less loops, and over-budget bundles are **warnings**, never a `<blocker>` — motion is creative, not contractually broken. The `motion-verifier` records them as advisories; only a `must_have` requiring verified reachability escalates one to a blocker.
119
+
120
+ 4. **No bundled runtime.** Do NOT add `@rive-app/canvas`, `@rive-app/react-canvas`, `rive-react`, or the Rive CLI to `package.json` to make this connection work — the runtime is opt-in and the maintainer supplies it. The default `npm test` stays hermetic and runtime-free (D-01/D-06).
121
+
122
+ 5. **Do NOT edit the connection index here.** Rive's Active-Connections row and Capability-Matrix entry are added by the 36.2 Wave-B wiring plan, not by this spec.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hegemonart/get-design-done",
3
- "version": "1.36.1",
3
+ "version": "1.36.3",
4
4
  "description": "A design-quality pipeline for AI coding agents: brief, plan, implement, and verify UI work against your design system.",
5
5
  "author": "Hegemon",
6
6
  "homepage": "https://github.com/hegemonart/get-design-done",
@@ -0,0 +1,110 @@
1
+ # Conversational UI Design Patterns
2
+
3
+ This pack covers conversational interfaces in two modes: **voice flows** (IVR, smart-speaker skills/actions, voice assistants) and **chatbot / text assistants** (in-app chat, support bots, LLM-backed copilots). GDD's design-context-builder loads this reference when it detects a conversational or voice project so downstream design and audit stages share a vocabulary. CLI / REPL / terminal UX is explicitly out of scope for this pack — those follow a different interaction model and have their own conventions.
4
+
5
+ The guidance below leans on established authorities: Google's Conversation Design guidelines, the Amazon Alexa Design Guide, and Nielsen Norman Group's research on chatbots and conversational interfaces.
6
+
7
+ ## Voice-flow patterns
8
+
9
+ A voice flow is more than its happy path. The happy path is the shortest successful route (user states a complete, in-scope request; system confirms and acts). Design quality lives in the branches around it.
10
+
11
+ | Branch | Trigger | Pattern |
12
+ |--------|---------|---------|
13
+ | No-input (NID) | User says nothing within the listen window | Escalating reprompts: 1st is a light nudge ("Which city?"), 2nd adds an example ("For example, say Berlin."), 3rd offers help or hands off. Never repeat the same words. |
14
+ | No-match (NM) | Speech recognized but no intent matched | Reflect what was heard, narrow the ask, give an example. After repeated NM, escalate to options or a human. |
15
+ | Confirmation | Action is risky, costly, or irreversible | See implicit vs explicit below. |
16
+ | Barge-in | User speaks over the prompt | Allow it — stop TTS immediately and listen. Disable only for legally required disclosures. |
17
+ | Hand-off | N consecutive failures (typically 2-3) | Route to a human, a visual fallback, or a clear "let's try later." Track the failure count across turns. |
18
+
19
+ **One-breath confirmation.** Confirm in a single short clause that the user can absorb in one breath: "Two tickets for Friday — booking now." Avoid reading back every slot verbatim; that is robotic and slow.
20
+
21
+ **Implicit vs explicit confirmation.**
22
+ - *Implicit* — fold the understood value into the next prompt ("Friday — what time?"). Use for low-risk, easily-reversed actions. It keeps the dialogue moving.
23
+ - *Explicit* — require a yes/no ("Send $200 to Sam — confirm?"). Reserve for irreversible, costly, or destructive actions (payments, deletes, sends).
24
+
25
+ **Failure escalation.** Each successive reprompt should add information (an example, then a menu, then a human). Three strikes is a common ceiling — after that, stop asking and offer an exit. A dead end ("Sorry, goodbye.") is a design failure.
26
+
27
+ ## Multi-turn dialogue rules
28
+
29
+ Multi-turn dialogue is where conversational UIs earn their name. The core obligation: remember context so the user speaks like a human, not a form.
30
+
31
+ - **Context carryover (anaphora).** Resolve references to prior turns. After "Weather in Paris?", the user says "What about tomorrow?" or "And Rome?" — carry the unstated slots (location, intent) forward. Failing this forces the user to repeat themselves and breaks the illusion of conversation.
32
+ - **Turn-taking.** Make it unambiguous whose turn it is. In voice, an earcon or a brief pause signals "your turn." In chat, a typing indicator signals the assistant is composing. Never leave the user unsure whether to speak/type.
33
+ - **Disambiguation.** When input matches more than one intent or entity, ask a tight either/or ("Did you mean the 9am or the 9pm flight?") rather than restarting. Offer at most 2-3 options by voice.
34
+ - **Slot-filling + validation.** Collect required slots one at a time when missing, but accept them all at once when volunteered ("Book a 7pm table for four" fills time + party size in one turn). Validate each slot against real constraints (date in the future, party size within limits) and reprompt only the invalid slot, not the whole request.
35
+ - **Repair.** Support correction mid-flow: "No, I said *four*, not *forty*." Detect the correction marker ("no", "I meant", "actually") and overwrite the targeted slot without discarding the rest of the context.
36
+ - **Don't over-ask.** Never re-confirm what is already certain. If the user said "tomorrow at noon," do not ask "what day?" again. Over-asking is the most common way a multi-turn flow feels broken.
37
+
38
+ ## Prompt-as-UX (system prompts as design artifacts)
39
+
40
+ For LLM-backed assistants, the `system-prompt` is a design artifact, not config. It defines the assistant's persona, tone, scope, and boundaries — and those ARE the user experience. Treat it accordingly.
41
+
42
+ - **Persona and voice are design decisions.** Warmth, formality, verbosity, use of humor, first-person vs neutral — these are chosen, documented, and kept consistent across every turn. A persona that drifts mid-conversation reads as broken.
43
+ - **The prompt is the spec for behavior.** What the assistant will and won't do, how it greets, how it refuses, how it asks for clarification — all of it is specified in the prompt. Downstream copy and flows must match it.
44
+ - **Version and review it like production copy.** The `system-prompt` belongs in source control, with diffs reviewed by design/content the same way UI strings are. A wording change to a refusal message is a UX change.
45
+ - **Refusal and limits messaging.** When the assistant can't or won't help, the decline should be in-voice, specific, and ideally redirect ("I can't process refunds here, but I can show you the refund form."). A blunt "I cannot do that" is a UX bug.
46
+ - **Consistency of voice.** Error states, confirmations, empty states, and refusals must all sound like the same persona. Audit them together, not in isolation.
47
+
48
+ ## Chatbot empty-states and entry
49
+
50
+ The opening message is the chatbot's most important screen. It does the work an empty form can't: it sets scope and teaches capability.
51
+
52
+ - **The opener states scope + capability.** "Hi — I can track orders, start a return, or check store hours. What do you need?" tells the user what's in bounds before they guess wrong. Vague openers ("How can I help?") invite out-of-scope requests the bot then fails.
53
+ - **Suggested-reply chips.** Offer 2-4 tappable starter prompts that double as a capability menu. They remove the cold-start guess and demonstrate the input format.
54
+ - **Discoverability of commands.** If the bot supports commands or shortcuts, surface them (a menu, a persistent "Help" affordance, or a slash-command hint). Hidden capabilities don't exist to users.
55
+ - **Avoid the blank-box-no-affordance trap.** A bare text input with a blinking cursor and no guidance is the #1 chatbot empty-state failure (NN/g). Always pair the input with scope-setting copy and/or chips.
56
+ - **Re-entry and history.** On return, remind the user where they left off or what the bot does — don't assume they remember the opener from last session.
57
+
58
+ ## Voice-first onboarding
59
+
60
+ Voice-first surfaces (smart speakers, headless assistants) onboard without a screen, which makes discoverability the central challenge.
61
+
62
+ - **Teach invocation.** Make the wake phrase / invocation name explicit early ("Just say 'Ask Acme to…'"). Users can't use what they can't name.
63
+ - **Teach capability by example.** Replace abstract menus with concrete sample utterances: "You can say 'add milk to my list' or 'what's on my list?'" The "you can say…" pattern is the canonical voice-discoverability tool.
64
+ - **Progressive disclosure.** Don't dump every feature in the first session. Reveal capabilities over time, contextually, as the user's needs surface.
65
+ - **Earcons and audio feedback.** Use short, distinct audio cues to mark state — listening, processing, success, error. Audio is the only "UI" the user has; consistent earcons replace visual affordances.
66
+ - **Confirm understanding audibly.** Because there's no screen to glance at, brief spoken confirmations carry the load that visual feedback would in a GUI.
67
+
68
+ ## Error recovery in voice flows
69
+
70
+ Recovery is the difference between a usable voice product and an abandoned one. The guiding rule: **never a dead end.**
71
+
72
+ - **Graceful degradation.** When confidence is low, narrow rather than fail — fall back from open prompt to a menu, from a menu to yes/no, from voice to a visual/text fallback if a screen is available.
73
+ - **Rapid, varied reprompts.** Reprompt quickly and change the wording each time. Repeating the identical prompt is the fastest way to frustrate.
74
+ - **Offer alternatives.** "I couldn't find that. Want me to search nearby instead?" keeps momentum and gives the user a next move.
75
+ - **Escalate to human / visual fallback.** After N failed turns, route to a person, send a link to a phone/companion screen, or switch channels. Honor explicit "talk to a person" requests immediately.
76
+ - **Accessibility.** Provide captions and transcripts for voice interactions; ensure chat is screen-reader-friendly with proper roles, focus management, and announced new messages. Don't gate critical actions behind audio-only or visual-only cues — offer both paths.
77
+
78
+ ## Detection signals
79
+
80
+ The design-context-builder classifies a project as conversational when it sees these signals.
81
+
82
+ **Keywords (in README, package name, docs, route/handler names):** chatbot, conversational, voice, assistant, dialogue, IVR, utterance, intent, skill, action, slot, prompt, agent, NLU.
83
+
84
+ **`package.json` dependencies:**
85
+
86
+ | Dependency | Platform |
87
+ |------------|----------|
88
+ | `botpress` / `@botpress/...` | Botpress conversational platform |
89
+ | `rasa` / `@rasa/...` | Rasa NLU / dialogue (often a Python sibling service) |
90
+ | `dialogflow` / `@google-cloud/dialogflow` | Google Dialogflow NLU |
91
+ | `actions-on-google` | Google Assistant actions |
92
+ | `ask-sdk-core` | Amazon Alexa skills |
93
+ | `botframework-webchat` / `@microsoft/botframework-*` | Microsoft Bot Framework |
94
+
95
+ Presence of any of these deps is a strong signal; keyword matches add weight. A `system-prompt` / persona file plus an LLM SDK also indicates a text assistant even without the platform deps above.
96
+
97
+ ## Audit checklist
98
+
99
+ 1. Every voice flow handles **no-input (NID)** and **no-match (NM)** with escalating reprompts that add help each time — never a dead end.
100
+ 2. Risky, costly, or irreversible actions use **explicit confirmation**; low-risk actions use implicit confirmation and don't over-confirm.
101
+ 3. **Barge-in** is allowed on standard prompts (TTS stops and listening resumes immediately), disabled only where legally required.
102
+ 4. Voice flows offer a **human / visual fallback after N failed turns** (typically 2-3) and honor explicit "talk to a person" requests.
103
+ 5. **Multi-turn context carries over** (anaphora resolved) so the user isn't forced to repeat slots already provided.
104
+ 6. **Slot validation** reprompts only the invalid slot and accepts multiple slots when volunteered in one turn.
105
+ 7. **Repair** is supported — corrections ("no, I said…") overwrite the targeted slot without losing surrounding context.
106
+ 8. The **`system-prompt` persona** (tone, scope, boundaries) is versioned and reviewed like production copy, and its voice is consistent across confirmations, errors, and refusals.
107
+ 9. **Refusal / limits messaging** is in-voice, specific, and redirects to an alternative rather than a blunt decline.
108
+ 10. The **chatbot opener states scope + capability** and offers suggested-reply chips; no blank-box-without-affordance entry state.
109
+ 11. **Voice-first onboarding** teaches invocation and capabilities by example ("you can say…") with consistent earcons for state.
110
+ 12. **Transcripts / captions** exist for voice, and chat is screen-reader-friendly (announced messages, focus management, dual audio/visual paths).
@@ -965,6 +965,13 @@
965
965
  "type": "heuristic",
966
966
  "phase": 36.1,
967
967
  "description": "Phase 36.1 Tier-3 domain pack — civic/government UI patterns: Section 508 + WCAG 2.1 AA hard floor, multi-language gov forms (EN/ES/zh-Hans), Plain Writing Act (grade 6-8), USWDS, session-timeout warnings, one-thing-per-page forms. Detection signals + Audit checklist for Step 0F + design-auditor."
968
+ },
969
+ {
970
+ "name": "conversational-ui",
971
+ "path": "reference/conversational-ui.md",
972
+ "type": "heuristic",
973
+ "phase": 36.3,
974
+ "description": "Phase 36.3 Tier-3 conversational-UI patterns (voice + chatbot): voice-flow no-input/no-match reprompts + confirmation + human handoff, multi-turn dialogue (context carryover, slot-filling, repair), prompt-as-UX (the assistant persona/tone/boundaries as a versioned design artifact), chatbot empty-states + suggested replies, voice-first onboarding, error recovery + accessibility (transcripts/captions). Carries Detection signals + an Audit checklist; loaded by design-context-builder for the conversational project type. CLI/REPL UX out of scope."
968
975
  }
969
976
  ]
970
977
  }
@@ -0,0 +1,92 @@
1
+ 'use strict';
2
+ /**
3
+ * scripts/lib/motion/validate-motion.cjs — Phase 36.2 motion-export validator.
4
+ *
5
+ * Pure + dep-free (D-01): zero `require`, no Lottie/Rive runtime. Deterministic — same
6
+ * input → same output (hermetic tests, D-06). Every finding is a WARNING, never a hard
7
+ * error (D-02: motion is creative, not contractually broken) — the caller decides whether
8
+ * a `must_have` escalates it.
9
+ *
10
+ * - validateLottie(json, {bytes?, budgetBytes?}) → {ok, warnings:[{rule,detail}], info}
11
+ * structural + perf sanity on a Lottie JSON (parsed object OR string).
12
+ * - motionBudget(bytes, budgetBytes?) → {rule:'MO-BUDGET', detail} | null (shared by Lottie + Rive)
13
+ * - riveHeader(headerBytes) → boolean (cheap .riv magic-byte sanity; the deep state-machine
14
+ * graph needs the Rive runtime — out of pure-JS reach, D-04)
15
+ *
16
+ * Rules: MO-PARSE, MO-FR, MO-DUR, MO-LAYERS, MO-IMG, MO-BUDGET.
17
+ */
18
+
19
+ const DEFAULT_BUDGET_BYTES = 200 * 1024; // 200 KB — D-05 fallback when config has no motion_budget_kb
20
+
21
+ function motionBudget(bytes, budgetBytes = DEFAULT_BUDGET_BYTES) {
22
+ if (typeof bytes !== 'number' || !isFinite(bytes) || bytes < 0) return null;
23
+ if (bytes > budgetBytes) {
24
+ return { rule: 'MO-BUDGET', detail: `motion bundle ${(bytes / 1024).toFixed(1)}KB exceeds budget ${(budgetBytes / 1024).toFixed(0)}KB` };
25
+ }
26
+ return null;
27
+ }
28
+
29
+ function validateLottie(input, opts = {}) {
30
+ let j;
31
+ if (typeof input === 'string') {
32
+ try { j = JSON.parse(input); } catch (e) {
33
+ return { ok: false, warnings: [{ rule: 'MO-PARSE', detail: 'not valid JSON' }], info: {} };
34
+ }
35
+ } else if (input && typeof input === 'object') {
36
+ j = input;
37
+ } else {
38
+ return { ok: false, warnings: [{ rule: 'MO-PARSE', detail: 'no input' }], info: {} };
39
+ }
40
+
41
+ // Lottie signature: version `v`, framerate `fr`, in/out points `ip`/`op`, `layers` array.
42
+ const isLottie = j && typeof j === 'object' && 'v' in j && 'fr' in j && Array.isArray(j.layers);
43
+ if (!isLottie) {
44
+ return { ok: false, warnings: [{ rule: 'MO-PARSE', detail: 'not a Lottie document (missing v / fr / layers)' }], info: {} };
45
+ }
46
+
47
+ const warnings = [];
48
+ const fr = Number(j.fr);
49
+ const ip = Number(j.ip);
50
+ const op = Number(j.op);
51
+ const layers = j.layers.length;
52
+
53
+ if (!(fr > 0) || fr > 120) warnings.push({ rule: 'MO-FR', detail: `frame rate ${j.fr} is outside the sane 1-120 range` });
54
+ if (!(op > ip)) warnings.push({ rule: 'MO-DUR', detail: `non-positive duration (ip=${j.ip}, op=${j.op})` });
55
+ if (layers > 200) warnings.push({ rule: 'MO-LAYERS', detail: `${layers} layers — high; review runtime cost` });
56
+
57
+ // Embedded raster assets bloat the bundle — a Lottie asset with an inline data URI in `p`.
58
+ const assets = Array.isArray(j.assets) ? j.assets : [];
59
+ const embedded = assets.filter((a) => a && typeof a.p === 'string' && /^data:/.test(a.p)).length;
60
+ if (embedded > 0) warnings.push({ rule: 'MO-IMG', detail: `${embedded} embedded raster asset(s) — prefer external / optimized images` });
61
+
62
+ // Perf budget (only when the caller supplies the on-disk byte size).
63
+ if (typeof opts.bytes === 'number') {
64
+ const b = motionBudget(opts.bytes, opts.budgetBytes);
65
+ if (b) warnings.push(b);
66
+ }
67
+
68
+ const durationFrames = op - ip;
69
+ return {
70
+ ok: warnings.length === 0,
71
+ warnings,
72
+ info: {
73
+ fr,
74
+ layers,
75
+ durationFrames,
76
+ durationSeconds: fr > 0 ? Number((durationFrames / fr).toFixed(2)) : null,
77
+ embeddedAssets: embedded,
78
+ },
79
+ };
80
+ }
81
+
82
+ function riveHeader(headerBytes) {
83
+ // .riv files begin with the ASCII magic "RIVE". Accept a string or an array of byte values.
84
+ const s = typeof headerBytes === 'string'
85
+ ? headerBytes.slice(0, 4)
86
+ : Array.isArray(headerBytes)
87
+ ? String.fromCharCode.apply(null, headerBytes.slice(0, 4))
88
+ : '';
89
+ return s === 'RIVE';
90
+ }
91
+
92
+ module.exports = { validateLottie, motionBudget, riveHeader, DEFAULT_BUDGET_BYTES };
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: gdd-connections
3
- description: "Interactive onboarding wizard for the 19 external integrations the pipeline supports — probes all (`figma`, `refero`, `preview`, `storybook`, `chromatic`, `graphify`, `pinterest`, `claude-design`, `paper-design`, `pencil-dev`, `21st-dev`, `magic-patterns`, `lazyweb`, `mobbin`, `slack`, `discord`, `linear`, `jira`, `notion`), recommends based on project type, walks the user through setup (auto-run MCP install or copy-command fallback), writes results to `STATE.md <connections>`. Use after `/gdd:new-project` or whenever the user wants to add, inspect, or skip a connection. Re-runnable anytime."
3
+ description: "Interactive onboarding wizard for the 21 external integrations the pipeline supports — probes all (`figma`, `refero`, `preview`, `storybook`, `chromatic`, `graphify`, `pinterest`, `claude-design`, `paper-design`, `pencil-dev`, `21st-dev`, `magic-patterns`, `lazyweb`, `mobbin`, `slack`, `discord`, `linear`, `jira`, `notion`, `lottie`, `rive`), recommends based on project type, walks the user through setup (auto-run MCP install or copy-command fallback), writes results to `STATE.md <connections>`. Use after `/gdd:new-project` or whenever the user wants to add, inspect, or skip a connection. Re-runnable anytime."
4
4
  argument-hint: "[list | <connection-name> | --auto]"
5
5
  user-invocable: true
6
6
  tools: Read, Write, Bash, Glob, Grep, AskUserQuestion, ToolSearch
@@ -8,11 +8,11 @@ tools: Read, Write, Bash, Glob, Grep, AskUserQuestion, ToolSearch
8
8
 
9
9
  # /gdd:connections
10
10
 
11
- Interactive onboarding for the 19 external integrations the pipeline supports. Replaces "probe silently at scan entry and hope the user noticed" with an explicit "here is what can plug in, here is how."
11
+ Interactive onboarding for the 21 external integrations the pipeline supports. Replaces "probe silently at scan entry and hope the user noticed" with an explicit "here is what can plug in, here is how."
12
12
 
13
13
  Canonical per-connection specs live in `../../connections/<name>.md` (one file per integration). The capability matrix + probe-pattern spec live in `../../connections/connections.md`. This skill is the **user-facing front end** for those specs.
14
14
 
15
- For the 19 probe scripts (MCP + HTTP + CLI + file probes), bucket categorization, per-connection setup screen, auto-run eligibility matrix, value-prop one-liners, and STATE.md / config.json write contracts, see `./connections-onboarding.md`. For the cross-skill probe pattern + connection-handshake summary, see `../../reference/shared-preamble.md#connection-handshake-summary`. For the cross-skill output discipline, see `../../reference/shared-preamble.md#output-contract-reminders`.
15
+ For the 21 probe scripts (MCP + HTTP + CLI + file probes), bucket categorization, per-connection setup screen, auto-run eligibility matrix, value-prop one-liners, and STATE.md / config.json write contracts, see `./connections-onboarding.md`. For the cross-skill probe pattern + connection-handshake summary, see `../../reference/shared-preamble.md#connection-handshake-summary`. For the cross-skill output discipline, see `../../reference/shared-preamble.md#output-contract-reminders`.
16
16
 
17
17
  ---
18
18
 
@@ -38,7 +38,7 @@ For the 19 probe scripts (MCP + HTTP + CLI + file probes), bucket categorization
38
38
 
39
39
  ## Workflow
40
40
 
41
- 1. **Probe all 19 connections** — run every probe script per `./connections-onboarding.md#step-1--probe-all-19-connections`. MCP probes use `ToolSearch` first; HTTP / CLI / file probes follow non-MCP patterns. Merge results into `STATE.md <connections>` with the three-value schema (`available | unavailable | not_configured`) — never add new values.
41
+ 1. **Probe all 21 connections** — run every probe script per `./connections-onboarding.md#step-1--probe-all-21-connections`. MCP probes use `ToolSearch` first; HTTP / CLI / file probes follow non-MCP patterns. Merge results into `STATE.md <connections>` with the three-value schema (`available | unavailable | not_configured`) — never add new values.
42
42
  2. **Categorize + build summary** — bucket each probe result (available / recommended / optional / skipped / unavailable) using project-hint detection. Detail + recommendation mapping: `./connections-onboarding.md#step-2--bucket-categorization`.
43
43
  3. **Print summary table** — show buckets + value-prop one-liners (verbatim from `./connections-onboarding.md#step-3--summary-table`).
44
44
  4. **Route by mode** — `list` / `--auto` exits after summary; `<name>` jumps straight to Step 5; default mode opens an AskUserQuestion (configure recommended / pick one by one / configure all optional / re-check specific / exit). Routing detail: `./connections-onboarding.md#step-4--route-by-mode`.
@@ -9,7 +9,7 @@ last_updated: 2026-05-18
9
9
 
10
10
  Source: extracted from `skills/connections/SKILL.md` (Phase 28.5 rework — D-10 extract-then-link).
11
11
  The skill's load-bearing routing + invocation-mode dispatch stays in `../skills/connections/SKILL.md`;
12
- this file holds the 19 probe scripts, bucket categorization, per-connection setup screen,
12
+ this file holds the 21 probe scripts, bucket categorization, per-connection setup screen,
13
13
  auto-run eligibility matrix, value-prop one-liners, and STATE.md / config.json write contracts.
14
14
 
15
15
  # Connections Onboarding Procedure
@@ -27,7 +27,7 @@ this file does NOT duplicate them; it points at them by name.
27
27
 
28
28
  ---
29
29
 
30
- ## Step 1 — Probe all 19 connections
30
+ ## Step 1 — Probe all 21 connections
31
31
 
32
32
  Run every probe below in order. MCP probes call `ToolSearch` first (deferred tools fail silently without it). Write every result to `STATE.md <connections>` when done.
33
33
 
@@ -180,7 +180,23 @@ Bash: ls .design/handoff/ 2>/dev/null || find . -maxdepth 3 \
180
180
  → Non-empty → claude_design: available
181
181
  ```
182
182
 
183
- After all 19 probes complete, merge results into `STATE.md <connections>`. Preserve the three-value schema verbatim (`available | unavailable | not_configured`). Do not add new values.
183
+ **lottie** (file probe Lottie JSON motion export):
184
+ ```
185
+ Bash: find . -name "*.json" -not -path "*/node_modules/*" 2>/dev/null | head (confirm the Lottie signature: top-level v / fr / layers)
186
+ grep -lE '"lottie-web"|@lottiefiles|lottie-react' package.json 2>/dev/null
187
+ → Lottie exports or a lottie dep found → lottie: available
188
+ → none → lottie: not_configured
189
+ ```
190
+
191
+ **rive** (file probe — Rive .riv motion export):
192
+ ```
193
+ Bash: find . -name "*.riv" -not -path "*/node_modules/*" 2>/dev/null | head
194
+ grep -E '@rive-app|rive-react' package.json 2>/dev/null
195
+ → .riv files or a @rive-app dep found → rive: available
196
+ → none → rive: not_configured
197
+ ```
198
+
199
+ After all 21 probes complete, merge results into `STATE.md <connections>`. Preserve the three-value schema verbatim (`available | unavailable | not_configured`). Do not add new values.
184
200
 
185
201
  ---
186
202
 
@@ -268,6 +284,8 @@ One-line value props (use verbatim):
268
284
  | linear | ticket-sync — link a cycle to a Linear issue; read comments + transition on completion |
269
285
  | jira | ticket-sync — parity with Linear via the Atlassian MCP |
270
286
  | notion | export — `/gdd:export --format notion` writes a stakeholder page (degrade-to-HTML) |
287
+ | lottie | verify — Lottie JSON motion check (frame-rate / duration / bloat / perf-budget), WARN-never-block |
288
+ | rive | verify — Rive `.riv` motion check (size + state-machine reachability via the opt-in runtime), WARN-never-block |
271
289
 
272
290
  ---
273
291
 
@@ -295,7 +313,7 @@ options:
295
313
  - "Exit" → emit ## CONNECTIONS COMPLETE, exit
296
314
  ```
297
315
 
298
- If recommended bucket is empty, swap that option for "Show all 19 and pick."
316
+ If recommended bucket is empty, swap that option for "Show all 21 and pick."
299
317
 
300
318
  ---
301
319
 
@@ -359,6 +377,8 @@ options:
359
377
  | linear | `claude mcp add linear ...` (Linear MCP) | ✓ yes | Reversible MCP add; OAuth on first call, no credential filesystem-write |
360
378
  | jira | `claude mcp add atlassian ...` (Atlassian MCP) | ✓ yes | Reversible MCP add; OAuth on first call |
361
379
  | notion | `claude mcp add notion ...` (Notion MCP) | ✓ yes | Reversible MCP add; OAuth on first call |
380
+ | lottie | (file-based — no install; drop a Lottie `.json` export in the repo) | n/a | Detected from Lottie exports / a `lottie-web` dep; live player opt-in |
381
+ | rive | (file-based — no install; add a `.riv` export / `@rive-app` dep) | n/a | Detected from `.riv` files / a `@rive-app` dep; Rive runtime opt-in |
362
382
 
363
383
  For non-auto-run connections, hide the "Run install command now" option entirely in 5.3.
364
384