@harness-engineering/cli 1.6.2 → 1.8.0

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.
Files changed (180) hide show
  1. package/dist/agents/personas/documentation-maintainer.yaml +3 -1
  2. package/dist/agents/personas/performance-guardian.yaml +23 -0
  3. package/dist/agents/personas/planner.yaml +27 -0
  4. package/dist/agents/personas/verifier.yaml +30 -0
  5. package/dist/agents/skills/claude-code/align-documentation/SKILL.md +13 -0
  6. package/dist/agents/skills/claude-code/cleanup-dead-code/SKILL.md +25 -1
  7. package/dist/agents/skills/claude-code/cleanup-dead-code/skill.yaml +5 -2
  8. package/dist/agents/skills/claude-code/detect-doc-drift/SKILL.md +12 -0
  9. package/dist/agents/skills/claude-code/enforce-architecture/SKILL.md +67 -1
  10. package/dist/agents/skills/claude-code/enforce-architecture/skill.yaml +5 -2
  11. package/dist/agents/skills/claude-code/harness-accessibility/SKILL.md +281 -0
  12. package/dist/agents/skills/claude-code/harness-accessibility/skill.yaml +51 -0
  13. package/dist/agents/skills/claude-code/harness-autopilot/SKILL.md +119 -72
  14. package/dist/agents/skills/claude-code/harness-autopilot/skill.yaml +4 -2
  15. package/dist/agents/skills/claude-code/harness-brainstorming/SKILL.md +76 -4
  16. package/dist/agents/skills/claude-code/harness-brainstorming/skill.yaml +2 -0
  17. package/dist/agents/skills/claude-code/harness-code-review/SKILL.md +487 -234
  18. package/dist/agents/skills/claude-code/harness-code-review/skill.yaml +15 -2
  19. package/dist/agents/skills/claude-code/harness-codebase-cleanup/SKILL.md +226 -0
  20. package/dist/agents/skills/claude-code/harness-codebase-cleanup/skill.yaml +64 -0
  21. package/dist/agents/skills/claude-code/harness-dependency-health/SKILL.md +35 -6
  22. package/dist/agents/skills/claude-code/harness-dependency-health/skill.yaml +1 -1
  23. package/dist/agents/skills/claude-code/harness-design/SKILL.md +265 -0
  24. package/dist/agents/skills/claude-code/harness-design/skill.yaml +53 -0
  25. package/dist/agents/skills/claude-code/harness-design-mobile/SKILL.md +336 -0
  26. package/dist/agents/skills/claude-code/harness-design-mobile/skill.yaml +49 -0
  27. package/dist/agents/skills/claude-code/harness-design-system/SKILL.md +282 -0
  28. package/dist/agents/skills/claude-code/harness-design-system/skill.yaml +50 -0
  29. package/dist/agents/skills/claude-code/harness-design-web/SKILL.md +360 -0
  30. package/dist/agents/skills/claude-code/harness-design-web/skill.yaml +52 -0
  31. package/dist/agents/skills/claude-code/harness-docs-pipeline/SKILL.md +460 -0
  32. package/dist/agents/skills/claude-code/harness-docs-pipeline/skill.yaml +69 -0
  33. package/dist/agents/skills/claude-code/harness-execution/SKILL.md +73 -8
  34. package/dist/agents/skills/claude-code/harness-execution/skill.yaml +1 -0
  35. package/dist/agents/skills/claude-code/harness-hotspot-detector/SKILL.md +32 -6
  36. package/dist/agents/skills/claude-code/harness-hotspot-detector/skill.yaml +1 -1
  37. package/dist/agents/skills/claude-code/harness-i18n/SKILL.md +484 -0
  38. package/dist/agents/skills/claude-code/harness-i18n/skill.yaml +54 -0
  39. package/dist/agents/skills/claude-code/harness-i18n-process/SKILL.md +388 -0
  40. package/dist/agents/skills/claude-code/harness-i18n-process/skill.yaml +43 -0
  41. package/dist/agents/skills/claude-code/harness-i18n-workflow/SKILL.md +512 -0
  42. package/dist/agents/skills/claude-code/harness-i18n-workflow/skill.yaml +53 -0
  43. package/dist/agents/skills/claude-code/harness-impact-analysis/SKILL.md +51 -6
  44. package/dist/agents/skills/claude-code/harness-integrity/SKILL.md +35 -1
  45. package/dist/agents/skills/claude-code/harness-knowledge-mapper/SKILL.md +46 -5
  46. package/dist/agents/skills/claude-code/harness-knowledge-mapper/skill.yaml +1 -1
  47. package/dist/agents/skills/claude-code/harness-onboarding/SKILL.md +19 -1
  48. package/dist/agents/skills/claude-code/harness-perf/SKILL.md +37 -8
  49. package/dist/agents/skills/claude-code/harness-perf/skill.yaml +3 -0
  50. package/dist/agents/skills/claude-code/harness-perf-tdd/SKILL.md +17 -4
  51. package/dist/agents/skills/claude-code/harness-planning/SKILL.md +57 -3
  52. package/dist/agents/skills/claude-code/harness-planning/skill.yaml +2 -0
  53. package/dist/agents/skills/claude-code/harness-release-readiness/SKILL.md +29 -9
  54. package/dist/agents/skills/claude-code/harness-roadmap/SKILL.md +562 -0
  55. package/dist/agents/skills/claude-code/harness-roadmap/skill.yaml +43 -0
  56. package/dist/agents/skills/claude-code/harness-security-review/SKILL.md +36 -2
  57. package/dist/agents/skills/claude-code/harness-security-review/skill.yaml +8 -6
  58. package/dist/agents/skills/claude-code/harness-security-scan/skill.yaml +1 -1
  59. package/dist/agents/skills/claude-code/harness-soundness-review/SKILL.md +1267 -0
  60. package/dist/agents/skills/claude-code/harness-soundness-review/skill.yaml +48 -0
  61. package/dist/agents/skills/claude-code/harness-test-advisor/SKILL.md +35 -6
  62. package/dist/agents/skills/claude-code/harness-verification/SKILL.md +66 -0
  63. package/dist/agents/skills/claude-code/harness-verification/skill.yaml +1 -0
  64. package/dist/agents/skills/claude-code/harness-verify/SKILL.md +37 -0
  65. package/dist/agents/skills/claude-code/initialize-harness-project/SKILL.md +15 -1
  66. package/dist/agents/skills/claude-code/validate-context-engineering/SKILL.md +12 -0
  67. package/dist/agents/skills/gemini-cli/harness-accessibility/SKILL.md +281 -0
  68. package/dist/agents/skills/gemini-cli/harness-accessibility/skill.yaml +51 -0
  69. package/dist/agents/skills/gemini-cli/harness-autopilot/SKILL.md +119 -72
  70. package/dist/agents/skills/gemini-cli/harness-autopilot/skill.yaml +4 -2
  71. package/dist/agents/skills/gemini-cli/harness-codebase-cleanup/SKILL.md +226 -0
  72. package/dist/agents/skills/gemini-cli/harness-codebase-cleanup/skill.yaml +64 -0
  73. package/dist/agents/skills/gemini-cli/harness-dependency-health/SKILL.md +35 -6
  74. package/dist/agents/skills/gemini-cli/harness-dependency-health/skill.yaml +1 -1
  75. package/dist/agents/skills/gemini-cli/harness-design/SKILL.md +265 -0
  76. package/dist/agents/skills/gemini-cli/harness-design/skill.yaml +53 -0
  77. package/dist/agents/skills/gemini-cli/harness-design-mobile/SKILL.md +336 -0
  78. package/dist/agents/skills/gemini-cli/harness-design-mobile/skill.yaml +49 -0
  79. package/dist/agents/skills/gemini-cli/harness-design-system/SKILL.md +282 -0
  80. package/dist/agents/skills/gemini-cli/harness-design-system/skill.yaml +50 -0
  81. package/dist/agents/skills/gemini-cli/harness-design-web/SKILL.md +360 -0
  82. package/dist/agents/skills/gemini-cli/harness-design-web/skill.yaml +52 -0
  83. package/dist/agents/skills/gemini-cli/harness-docs-pipeline/SKILL.md +460 -0
  84. package/dist/agents/skills/gemini-cli/harness-docs-pipeline/skill.yaml +69 -0
  85. package/dist/agents/skills/gemini-cli/harness-hotspot-detector/SKILL.md +32 -6
  86. package/dist/agents/skills/gemini-cli/harness-hotspot-detector/skill.yaml +1 -1
  87. package/dist/agents/skills/gemini-cli/harness-i18n/SKILL.md +484 -0
  88. package/dist/agents/skills/gemini-cli/harness-i18n/skill.yaml +54 -0
  89. package/dist/agents/skills/gemini-cli/harness-i18n-process/SKILL.md +388 -0
  90. package/dist/agents/skills/gemini-cli/harness-i18n-process/skill.yaml +43 -0
  91. package/dist/agents/skills/gemini-cli/harness-i18n-workflow/SKILL.md +512 -0
  92. package/dist/agents/skills/gemini-cli/harness-i18n-workflow/skill.yaml +53 -0
  93. package/dist/agents/skills/gemini-cli/harness-impact-analysis/SKILL.md +51 -6
  94. package/dist/agents/skills/gemini-cli/harness-knowledge-mapper/SKILL.md +46 -5
  95. package/dist/agents/skills/gemini-cli/harness-knowledge-mapper/skill.yaml +1 -1
  96. package/dist/agents/skills/gemini-cli/harness-perf/SKILL.md +37 -8
  97. package/dist/agents/skills/gemini-cli/harness-perf/skill.yaml +3 -0
  98. package/dist/agents/skills/gemini-cli/harness-perf-tdd/SKILL.md +17 -4
  99. package/dist/agents/skills/gemini-cli/harness-release-readiness/SKILL.md +29 -9
  100. package/dist/agents/skills/gemini-cli/harness-roadmap/SKILL.md +562 -0
  101. package/dist/agents/skills/gemini-cli/harness-roadmap/skill.yaml +43 -0
  102. package/dist/agents/skills/gemini-cli/harness-security-review/skill.yaml +8 -6
  103. package/dist/agents/skills/gemini-cli/harness-security-scan/skill.yaml +1 -1
  104. package/dist/agents/skills/gemini-cli/harness-soundness-review/SKILL.md +1267 -0
  105. package/dist/agents/skills/gemini-cli/harness-soundness-review/skill.yaml +48 -0
  106. package/dist/agents/skills/gemini-cli/harness-test-advisor/SKILL.md +35 -6
  107. package/dist/agents/skills/node_modules/.bin/vitest +2 -2
  108. package/dist/agents/skills/shared/design-knowledge/anti-patterns/color.yaml +106 -0
  109. package/dist/agents/skills/shared/design-knowledge/anti-patterns/layout.yaml +109 -0
  110. package/dist/agents/skills/shared/design-knowledge/anti-patterns/motion.yaml +109 -0
  111. package/dist/agents/skills/shared/design-knowledge/anti-patterns/typography.yaml +112 -0
  112. package/dist/agents/skills/shared/design-knowledge/industries/creative.yaml +80 -0
  113. package/dist/agents/skills/shared/design-knowledge/industries/ecommerce.yaml +80 -0
  114. package/dist/agents/skills/shared/design-knowledge/industries/emerging-tech.yaml +83 -0
  115. package/dist/agents/skills/shared/design-knowledge/industries/fintech.yaml +80 -0
  116. package/dist/agents/skills/shared/design-knowledge/industries/healthcare.yaml +80 -0
  117. package/dist/agents/skills/shared/design-knowledge/industries/lifestyle.yaml +80 -0
  118. package/dist/agents/skills/shared/design-knowledge/industries/saas.yaml +80 -0
  119. package/dist/agents/skills/shared/design-knowledge/industries/services.yaml +80 -0
  120. package/dist/agents/skills/shared/design-knowledge/palettes/curated.yaml +234 -0
  121. package/dist/agents/skills/shared/design-knowledge/platform-rules/android.yaml +125 -0
  122. package/dist/agents/skills/shared/design-knowledge/platform-rules/flutter.yaml +144 -0
  123. package/dist/agents/skills/shared/design-knowledge/platform-rules/ios.yaml +106 -0
  124. package/dist/agents/skills/shared/design-knowledge/platform-rules/web.yaml +102 -0
  125. package/dist/agents/skills/shared/design-knowledge/typography/pairings.yaml +274 -0
  126. package/dist/agents/skills/shared/i18n-knowledge/accessibility/intersection.yaml +142 -0
  127. package/dist/agents/skills/shared/i18n-knowledge/anti-patterns/encoding.yaml +67 -0
  128. package/dist/agents/skills/shared/i18n-knowledge/anti-patterns/formatting.yaml +106 -0
  129. package/dist/agents/skills/shared/i18n-knowledge/anti-patterns/layout.yaml +80 -0
  130. package/dist/agents/skills/shared/i18n-knowledge/anti-patterns/pluralization.yaml +80 -0
  131. package/dist/agents/skills/shared/i18n-knowledge/anti-patterns/string-handling.yaml +106 -0
  132. package/dist/agents/skills/shared/i18n-knowledge/frameworks/android-resources.yaml +47 -0
  133. package/dist/agents/skills/shared/i18n-knowledge/frameworks/apple-strings.yaml +47 -0
  134. package/dist/agents/skills/shared/i18n-knowledge/frameworks/backend-patterns.yaml +50 -0
  135. package/dist/agents/skills/shared/i18n-knowledge/frameworks/flutter-intl.yaml +47 -0
  136. package/dist/agents/skills/shared/i18n-knowledge/frameworks/i18next.yaml +47 -0
  137. package/dist/agents/skills/shared/i18n-knowledge/frameworks/react-intl.yaml +47 -0
  138. package/dist/agents/skills/shared/i18n-knowledge/frameworks/vue-i18n.yaml +47 -0
  139. package/dist/agents/skills/shared/i18n-knowledge/industries/ecommerce.yaml +66 -0
  140. package/dist/agents/skills/shared/i18n-knowledge/industries/fintech.yaml +66 -0
  141. package/dist/agents/skills/shared/i18n-knowledge/industries/gaming.yaml +69 -0
  142. package/dist/agents/skills/shared/i18n-knowledge/industries/healthcare.yaml +66 -0
  143. package/dist/agents/skills/shared/i18n-knowledge/industries/legal.yaml +66 -0
  144. package/dist/agents/skills/shared/i18n-knowledge/locales/ar.yaml +41 -0
  145. package/dist/agents/skills/shared/i18n-knowledge/locales/de.yaml +35 -0
  146. package/dist/agents/skills/shared/i18n-knowledge/locales/en.yaml +32 -0
  147. package/dist/agents/skills/shared/i18n-knowledge/locales/es.yaml +35 -0
  148. package/dist/agents/skills/shared/i18n-knowledge/locales/fi.yaml +35 -0
  149. package/dist/agents/skills/shared/i18n-knowledge/locales/fr.yaml +35 -0
  150. package/dist/agents/skills/shared/i18n-knowledge/locales/he.yaml +41 -0
  151. package/dist/agents/skills/shared/i18n-knowledge/locales/hi.yaml +35 -0
  152. package/dist/agents/skills/shared/i18n-knowledge/locales/it.yaml +32 -0
  153. package/dist/agents/skills/shared/i18n-knowledge/locales/ja.yaml +38 -0
  154. package/dist/agents/skills/shared/i18n-knowledge/locales/ko.yaml +38 -0
  155. package/dist/agents/skills/shared/i18n-knowledge/locales/nl.yaml +32 -0
  156. package/dist/agents/skills/shared/i18n-knowledge/locales/pl.yaml +35 -0
  157. package/dist/agents/skills/shared/i18n-knowledge/locales/pt.yaml +32 -0
  158. package/dist/agents/skills/shared/i18n-knowledge/locales/ru.yaml +35 -0
  159. package/dist/agents/skills/shared/i18n-knowledge/locales/sv.yaml +32 -0
  160. package/dist/agents/skills/shared/i18n-knowledge/locales/th.yaml +35 -0
  161. package/dist/agents/skills/shared/i18n-knowledge/locales/tr.yaml +35 -0
  162. package/dist/agents/skills/shared/i18n-knowledge/locales/zh-Hans.yaml +38 -0
  163. package/dist/agents/skills/shared/i18n-knowledge/locales/zh-Hant.yaml +35 -0
  164. package/dist/agents/skills/shared/i18n-knowledge/mcp-interop/i18next-mcp.yaml +56 -0
  165. package/dist/agents/skills/shared/i18n-knowledge/mcp-interop/lingo-dev.yaml +56 -0
  166. package/dist/agents/skills/shared/i18n-knowledge/mcp-interop/lokalise.yaml +60 -0
  167. package/dist/agents/skills/shared/i18n-knowledge/mcp-interop/tolgee.yaml +60 -0
  168. package/dist/agents/skills/shared/i18n-knowledge/testing/locale-testing.yaml +107 -0
  169. package/dist/agents/skills/shared/i18n-knowledge/testing/pseudo-localization.yaml +86 -0
  170. package/dist/bin/harness.js +64 -4
  171. package/dist/{chunk-UDWGSL3T.js → chunk-3JWCBVUZ.js} +3 -3
  172. package/dist/{chunk-IUFFBBYV.js → chunk-LNI4T7R6.js} +179 -61
  173. package/dist/{chunk-USEYPS7F.js → chunk-SJECMKSS.js} +2250 -40
  174. package/dist/{dist-4MYPT3OE.js → dist-BDO5GFEM.js} +295 -14
  175. package/dist/{dist-RBZXXJHG.js → dist-NT3GXHQZ.js} +95 -1
  176. package/dist/index.d.ts +266 -7
  177. package/dist/index.js +7 -3
  178. package/dist/validate-cross-check-2OPGCGGU.js +7 -0
  179. package/package.json +7 -7
  180. package/dist/validate-cross-check-CPEPNLOD.js +0 -7
@@ -0,0 +1,336 @@
1
+ # Harness Design Mobile
2
+
3
+ > Token-bound mobile component generation. Scaffold from design tokens and aesthetic intent, implement with React Native, SwiftUI, Flutter, or Compose patterns following platform-specific design rules, and verify every value references the token set with native convention compliance.
4
+
5
+ ## When to Use
6
+
7
+ - Generating new mobile components that must conform to the project's design system tokens
8
+ - When `on_new_feature` triggers fire with mobile UI scope requiring token-bound component generation
9
+ - When `on_commit` triggers fire and new mobile components contain hardcoded design values that should reference tokens
10
+ - Implementing design intent from `design-system/DESIGN.md` into platform-native styling (StyleSheet, SwiftUI modifiers, Flutter ThemeData, Compose MaterialTheme)
11
+ - Ensuring components follow platform-specific guidelines (iOS Human Interface Guidelines, Material Design 3, Flutter design patterns)
12
+ - NOT for generating design tokens themselves (use harness-design-system)
13
+ - NOT for establishing aesthetic direction or anti-patterns (use harness-design)
14
+ - NOT for accessibility auditing (use harness-accessibility)
15
+ - NOT for web platform components (use harness-design-web)
16
+
17
+ ## Process
18
+
19
+ ### Phase 1: SCAFFOLD — Read Tokens, Detect Platform, Plan Structure
20
+
21
+ 1. **Read design tokens.** Load `design-system/tokens.json` (W3C DTCG format). Extract:
22
+ - Color tokens: primary, secondary, accent, neutral ramps, semantic colors
23
+ - Typography tokens: heading and body font families, font weights, font sizes, line heights
24
+ - Spacing tokens: spacing scale values
25
+ - If `design-system/tokens.json` does not exist, stop and instruct the user to run `harness-design-system` first.
26
+
27
+ 2. **Read design intent.** Load `design-system/DESIGN.md` for:
28
+ - Aesthetic direction (style, tone, differentiator)
29
+ - Anti-patterns to avoid
30
+ - Platform-specific mobile notes (touch targets, native component usage, platform conventions)
31
+ - If `design-system/DESIGN.md` does not exist, warn the user and proceed with tokens only.
32
+
33
+ 3. **Check harness configuration.** Read `harness.config.json` for:
34
+ - `design.strictness` — enforcement level. Default to `standard`.
35
+ - `design.platforms` — confirm `mobile` is in the platforms list.
36
+
37
+ 4. **Detect mobile platform.** Scan the project for:
38
+ - **React Native:** `package.json` contains `react-native` or `expo`, `.tsx` files with `StyleSheet` or `react-native` imports
39
+ - **SwiftUI:** `.swift` files with `import SwiftUI`, `Package.swift` or `.xcodeproj` exists
40
+ - **Flutter:** `pubspec.yaml` exists, `.dart` files with `import 'package:flutter/`
41
+ - **Compose:** `build.gradle.kts` with `compose` dependencies, `.kt` files with `@Composable`
42
+ - If the user specified `--platform`, use that override.
43
+
44
+ 5. **Load platform-specific rules.** Based on detected platform, read platform design guidelines from `agents/skills/shared/design-knowledge/platform-rules/`:
45
+ - **iOS (SwiftUI/React Native on iOS):** Read `ios.yaml` — Human Interface Guidelines, safe area insets, navigation bar patterns, tab bar conventions, dynamic type support, SF Symbols integration
46
+ - **Android (Compose/React Native on Android):** Read `android.yaml` — Material Design 3, elevation system, shape system, dynamic color, navigation patterns, edge-to-edge layout
47
+ - **Flutter:** Read `flutter.yaml` — Flutter design patterns, ThemeData structure, widget composition, adaptive layouts, platform channel considerations
48
+ - **React Native cross-platform:** Read both `ios.yaml` and `android.yaml` — platform-specific overrides via `Platform.select`, safe area handling, navigation library patterns
49
+
50
+ 6. **Load anti-pattern definitions.** Read anti-pattern files from `agents/skills/shared/design-knowledge/anti-patterns/`:
51
+ - `typography.yaml` — typographic anti-patterns (too many fonts, inconsistent scales)
52
+ - `color.yaml` — color anti-patterns (hardcoded hex, insufficient contrast)
53
+ - `layout.yaml` — layout anti-patterns (magic numbers, inconsistent spacing)
54
+ - `motion.yaml` — motion anti-patterns (excessive animation, missing reduced-motion)
55
+
56
+ 7. **Build token-to-platform mapping.** Create a lookup table mapping tokens to platform-native representations:
57
+ - **React Native:** `color.primary.500` maps to `StyleSheet` value or themed constant
58
+ - **SwiftUI:** `color.primary.500` maps to `Color("primary500")` in asset catalog or `Color(hex:)` extension
59
+ - **Flutter:** `color.primary.500` maps to `Theme.of(context).colorScheme.primary` or custom `AppColors.primary500`
60
+ - **Compose:** `color.primary.500` maps to `MaterialTheme.colorScheme.primary` or custom `AppTheme.colors.primary500`
61
+
62
+ 8. **Plan component structure.** Define:
63
+ - Component file path(s) following platform conventions
64
+ - Props/parameters interface
65
+ - Which tokens will be consumed
66
+ - Platform-specific considerations (safe areas, touch targets, dynamic type)
67
+ - Present plan to user before proceeding.
68
+
69
+ ### Phase 2: IMPLEMENT — Generate Token-Bound Mobile Components
70
+
71
+ 1. **Generate platform-specific component code.** Based on detected platform:
72
+
73
+ **React Native (TypeScript):**
74
+ - Functional component with TypeScript props interface
75
+ - All colors via themed StyleSheet or token constants (no hardcoded hex values)
76
+ - Typography via scaled text styles referencing token font families and sizes
77
+ - Spacing via token-derived constants in StyleSheet
78
+ - Platform-specific overrides via `Platform.select` where iOS and Android differ
79
+ - Safe area handling via `useSafeAreaInsets` for edge-to-edge content
80
+
81
+ **SwiftUI:**
82
+ - View struct with typed properties
83
+ - Colors from asset catalog or Color extension referencing tokens
84
+ - Typography via custom `Font` extensions mapping to token values
85
+ - Spacing via token-derived constants
86
+ - Dynamic Type support via `.font(.body)` or custom scaled fonts
87
+ - Safe area respect via `.safeAreaInset` modifiers
88
+ - iOS Human Interface Guidelines compliance (44pt minimum touch targets)
89
+
90
+ **Flutter (Dart):**
91
+ - StatelessWidget or StatefulWidget with typed constructor parameters
92
+ - Colors via `Theme.of(context)` or custom `AppColors` class referencing tokens
93
+ - Typography via `Theme.of(context).textTheme` or custom `AppTypography`
94
+ - Spacing via token-derived constants class
95
+ - Material Design 3 compliance (elevation, shape, dynamic color)
96
+ - Adaptive layout via `LayoutBuilder` or `MediaQuery` for responsive behavior
97
+
98
+ **Compose (Kotlin):**
99
+ - `@Composable` function with typed parameters
100
+ - Colors via `MaterialTheme.colorScheme` or custom theme referencing tokens
101
+ - Typography via `MaterialTheme.typography` or custom type scale
102
+ - Spacing via token-derived `Dp` constants
103
+ - Material Design 3 compliance (Surface, ElevatedCard, shape system)
104
+ - Modifier chains for layout following Compose conventions
105
+
106
+ 2. **Apply platform-specific rules:**
107
+ - **Touch targets:** Minimum 44x44pt (iOS) or 48x48dp (Android/Material)
108
+ - **Safe areas:** All platforms handle notch/status bar/navigation bar correctly
109
+ - **Typography scaling:** Support dynamic type (iOS), font scale (Android), and text scale factor (Flutter)
110
+ - **Elevation/shadows:** Platform-appropriate (iOS shadow, Material elevation, Flutter elevation)
111
+ - **Navigation patterns:** Platform-native navigation (UINavigationController, NavHost, Navigator)
112
+
113
+ 3. **Add USES_TOKEN annotations.** Insert platform-appropriate comments documenting token consumption:
114
+ ```
115
+ // @design-token color.primary.500 — primary action background
116
+ // @design-token typography.heading.fontFamily — section heading
117
+ // @design-token spacing.md — card internal padding
118
+ ```
119
+
120
+ ### Phase 3: VERIFY — Check Token Binding and Platform Compliance
121
+
122
+ 1. **Scan for hardcoded values.** Search generated files for:
123
+ - Hardcoded color values: hex codes, `UIColor(red:green:blue:)`, `Color(0xFF...)`, `Color(red:green:blue:)`
124
+ - Hardcoded font families: string literals for font names not referencing tokens
125
+ - Hardcoded spacing: raw numeric values in padding/margin not from the token scale
126
+
127
+ 2. **Verify token coverage.** For every design value in generated components:
128
+ - Confirm it resolves to a token in `design-system/tokens.json`
129
+ - Confirm the token path is valid
130
+ - Report orphan references
131
+
132
+ 3. **Check platform guideline compliance:**
133
+ - **iOS:** Touch targets >= 44pt, safe area respected, dynamic type supported
134
+ - **Android/Material:** Touch targets >= 48dp, edge-to-edge layout, Material 3 components used
135
+ - **Flutter:** ThemeData used consistently, no hardcoded Material values
136
+ - **React Native:** Platform.select used for iOS/Android differences, safe area handled
137
+
138
+ 4. **Check anti-pattern compliance.** Cross-reference against `design-system/DESIGN.md` anti-patterns and definitions in `agents/skills/shared/design-knowledge/anti-patterns/`.
139
+
140
+ 5. **Query the knowledge graph.** If available at `.harness/graph/`:
141
+ - Verify `DesignToken` nodes exist for all referenced tokens
142
+ - Verify `PLATFORM_BINDING` edges exist for the target mobile platform
143
+ - Check `VIOLATES_DESIGN` edges via `DesignConstraintAdapter`
144
+
145
+ 6. **Assign severity based on `designStrictness`:**
146
+ - `permissive` — all findings are `info`
147
+ - `standard` — hardcoded values are `warn`, platform guideline violations are `warn`, accessibility violations are `error`
148
+ - `strict` — hardcoded values are `error` (blocks), platform violations are `warn`, accessibility violations are `error`
149
+
150
+ 7. **Report verification results:**
151
+
152
+ ```
153
+ MOBILE-001 [warn] Hardcoded color Color(0xFF3B82F6) — should reference token
154
+ File: lib/widgets/action_button.dart:15
155
+ Fix: Use Theme.of(context).colorScheme.primary or AppColors.primary500
156
+
157
+ MOBILE-002 [warn] Touch target 32dp below minimum 48dp (Material Design 3)
158
+ File: lib/widgets/icon_action.dart:22
159
+ Fix: Set minimumSize to Size(48, 48) in ButtonStyle
160
+
161
+ MOBILE-003 [info] Missing dynamic type support
162
+ File: Sources/Views/ProductCard.swift:18
163
+ Fix: Use .font(.body) instead of .font(.system(size: 16))
164
+ ```
165
+
166
+ 8. **Run `harness validate`.** Confirm new components integrate cleanly.
167
+
168
+ ## Harness Integration
169
+
170
+ - **`harness validate`** — Run after generating components to verify project health.
171
+ - **`harness scan`** — Run after component generation to update the knowledge graph with `USES_TOKEN` and `PLATFORM_BINDING` edges.
172
+ - **`DesignIngestor`** (`packages/graph/src/ingest/DesignIngestor.ts`) — Verifies `DesignToken` nodes exist for all tokens referenced by generated components.
173
+ - **`DesignConstraintAdapter`** (`packages/graph/src/constraints/DesignConstraintAdapter.ts`) — Checks for `VIOLATES_DESIGN` edges during VERIFY phase. Reports constraint violations at configured strictness.
174
+ - **`harness-design-system`** — Dependency. Provides `design-system/tokens.json`. If tokens do not exist, instruct user to run harness-design-system first.
175
+ - **`harness-design`** — Dependency. Provides `design-system/DESIGN.md` with aesthetic intent and anti-patterns.
176
+ - **`harness-impact-analysis`** — Traces token changes to affected mobile components via `USES_TOKEN` edges.
177
+
178
+ **Graph naming convention:** This skill uses PascalCase for node types (`DesignToken`, `DesignConstraint`) and UPPER_SNAKE for edge types (`USES_TOKEN`, `PLATFORM_BINDING`, `VIOLATES_DESIGN`) as conceptual labels. The graph schema registers these as snake_case identifiers (`design_token`, `design_constraint`, `uses_token`, `platform_binding`, `violates_design`). The adapter classes (`DesignIngestor`, `DesignConstraintAdapter`) handle the mapping — always use the adapters rather than constructing graph queries with raw type names.
179
+
180
+ ## Success Criteria
181
+
182
+ - Generated mobile components reference design tokens exclusively — no hardcoded color, font, or spacing values
183
+ - Platform detection correctly identifies React Native, SwiftUI, Flutter, or Compose projects
184
+ - Token-to-platform mapping produces correct output for each mobile platform
185
+ - Platform-specific rules are enforced (touch targets, safe areas, dynamic type, Material 3 compliance)
186
+ - `@design-token` annotations are present for every consumed token
187
+ - Anti-pattern compliance check catches violations from `design-system/DESIGN.md`
188
+ - Verification report uses severity levels matching `design.strictness` configuration
189
+ - `harness validate` passes after component generation
190
+
191
+ ## Examples
192
+
193
+ ### Example: React Native Card Component
194
+
195
+ **Context:** Fitness app. React Native with Expo. Tokens from harness-design-system. Design intent: expressive, warm tone.
196
+
197
+ **SCAFFOLD output:**
198
+
199
+ ```
200
+ Platform detected: React Native (Expo)
201
+ Tokens loaded: 38 tokens from design-system/tokens.json
202
+ Design intent: Expressive, warm (from DESIGN.md)
203
+ Component plan: WorkoutCard with progress indicator
204
+ Token consumption: color.primary.*, color.accent.*, typography.heading, spacing.md/lg
205
+ Platform rules: iOS 44pt touch targets, Android 48dp touch targets, safe area insets
206
+ ```
207
+
208
+ **IMPLEMENT output (WorkoutCard.tsx):**
209
+
210
+ ```tsx
211
+ // @design-token color.primary.500 — card accent
212
+ // @design-token color.neutral.50 — card background
213
+ // @design-token color.neutral.900 — primary text
214
+ // @design-token typography.heading.fontFamily — workout title
215
+ // @design-token typography.body.fontFamily — workout details
216
+ // @design-token spacing.md — card padding
217
+ // @design-token spacing.sm — content gap
218
+
219
+ import { View, Text, StyleSheet, Platform } from 'react-native';
220
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
221
+ import { tokens } from '@/theme/tokens';
222
+
223
+ interface WorkoutCardProps {
224
+ title: string;
225
+ duration: string;
226
+ progress: number;
227
+ }
228
+
229
+ export function WorkoutCard({ title, duration, progress }: WorkoutCardProps) {
230
+ return (
231
+ <View style={styles.card}>
232
+ <Text style={styles.title}>{title}</Text>
233
+ <Text style={styles.detail}>{duration}</Text>
234
+ <View style={styles.progressTrack}>
235
+ <View style={[styles.progressFill, { width: `${progress}%` }]} />
236
+ </View>
237
+ </View>
238
+ );
239
+ }
240
+
241
+ const styles = StyleSheet.create({
242
+ card: {
243
+ backgroundColor: tokens.color.neutral[50],
244
+ borderRadius: tokens.radius.md,
245
+ padding: tokens.spacing.md,
246
+ gap: tokens.spacing.sm,
247
+ ...Platform.select({
248
+ ios: {
249
+ shadowColor: tokens.color.neutral[900],
250
+ shadowOffset: { width: 0, height: 2 },
251
+ shadowOpacity: 0.08,
252
+ shadowRadius: 8,
253
+ },
254
+ android: {
255
+ elevation: 2,
256
+ },
257
+ }),
258
+ },
259
+ title: {
260
+ fontFamily: tokens.typography.heading.fontFamily,
261
+ fontWeight: tokens.typography.heading.fontWeight,
262
+ fontSize: 18,
263
+ color: tokens.color.neutral[900],
264
+ },
265
+ detail: {
266
+ fontFamily: tokens.typography.body.fontFamily,
267
+ fontSize: 14,
268
+ color: tokens.color.neutral[600],
269
+ },
270
+ progressTrack: {
271
+ height: 6,
272
+ backgroundColor: tokens.color.neutral[200],
273
+ borderRadius: 3,
274
+ },
275
+ progressFill: {
276
+ height: 6,
277
+ backgroundColor: tokens.color.primary[500],
278
+ borderRadius: 3,
279
+ },
280
+ });
281
+ ```
282
+
283
+ ### Example: SwiftUI List Item
284
+
285
+ **IMPLEMENT output (WorkoutRow.swift):**
286
+
287
+ ```swift
288
+ // @design-token color.primary.500 — accent color
289
+ // @design-token color.neutral.900 — primary text
290
+ // @design-token color.neutral.600 — secondary text
291
+ // @design-token typography.heading.fontWeight — title weight
292
+ // @design-token spacing.sm — content spacing
293
+
294
+ import SwiftUI
295
+
296
+ struct WorkoutRow: View {
297
+ let title: String
298
+ let duration: String
299
+ let progress: Double
300
+
301
+ var body: some View {
302
+ VStack(alignment: .leading, spacing: AppSpacing.sm) {
303
+ Text(title)
304
+ .font(.headline)
305
+ .foregroundColor(AppColors.neutral900)
306
+
307
+ Text(duration)
308
+ .font(.subheadline)
309
+ .foregroundColor(AppColors.neutral600)
310
+
311
+ ProgressView(value: progress)
312
+ .tint(AppColors.primary500)
313
+ }
314
+ .padding(AppSpacing.md)
315
+ .accessibilityElement(children: .combine)
316
+ }
317
+ }
318
+ ```
319
+
320
+ ## Gates
321
+
322
+ - **No component generation without reading tokens from harness-design-system.** The SCAFFOLD phase requires `design-system/tokens.json`. Do not generate components with hardcoded values as a fallback.
323
+ - **No hardcoded design values in generated output.** Every color, font, and spacing value must reference a token.
324
+ - **No platform-specific code without platform detection.** The SCAFFOLD phase must detect or receive the target mobile platform before generating components.
325
+ - **No generation without scaffold plan confirmation.** Present the component plan to the user first.
326
+ - **No iOS components without 44pt minimum touch targets.** Touch target violations are `error` severity regardless of strictness level.
327
+ - **No Android/Material components without 48dp minimum touch targets.** Same as iOS — touch targets are non-negotiable.
328
+ - **No graph mutations without validating node types.** Verify edge types are registered before writing.
329
+
330
+ ## Escalation
331
+
332
+ - **When `design-system/tokens.json` does not exist:** Instruct the user: "Design tokens have not been generated. Run `harness-design-system` first, then re-run `harness-design-mobile`."
333
+ - **When the project targets multiple mobile platforms:** Generate for the primary platform first, then offer to generate platform-adapted variants. React Native projects get both iOS and Android considerations in a single pass.
334
+ - **When tokens are insufficient for the requested component:** Report missing tokens and instruct the user to add them via harness-design-system.
335
+ - **When platform guidelines conflict with design intent:** Present the conflict: "Material Design 3 recommends rounded corners for cards, but your design intent declares 'sharp edges only.' Options: (1) Follow platform guidelines for native feel, (2) Override with design intent for brand consistency."
336
+ - **When the knowledge graph is unavailable:** Skip graph operations. Log: "Graph not available — skipping token node verification and PLATFORM_BINDING edge creation. Run `harness scan` later to populate."
@@ -0,0 +1,49 @@
1
+ name: harness-design-mobile
2
+ version: "1.0.0"
3
+ description: Token-bound mobile component generation with React Native, SwiftUI, Flutter, and Compose patterns and platform-specific design rules
4
+ cognitive_mode: meticulous-implementer
5
+ triggers:
6
+ - manual
7
+ - on_new_feature
8
+ - on_commit
9
+ platforms:
10
+ - claude-code
11
+ - gemini-cli
12
+ tools:
13
+ - Bash
14
+ - Read
15
+ - Write
16
+ - Edit
17
+ - Glob
18
+ - Grep
19
+ cli:
20
+ command: harness skill run harness-design-mobile
21
+ args:
22
+ - name: path
23
+ description: Project root path
24
+ required: false
25
+ - name: platform
26
+ description: Target mobile platform (react-native, swiftui, flutter, compose)
27
+ required: false
28
+ mcp:
29
+ tool: run_skill
30
+ input:
31
+ skill: harness-design-mobile
32
+ path: string
33
+ type: rigid
34
+ phases:
35
+ - name: scaffold
36
+ description: Read tokens and design intent, detect mobile platform, plan component structure with platform-specific rules
37
+ required: true
38
+ - name: implement
39
+ description: Generate token-bound components with platform-specific patterns and native conventions
40
+ required: true
41
+ - name: verify
42
+ description: Verify token binding, platform guideline compliance, and design constraints
43
+ required: true
44
+ state:
45
+ persistent: false
46
+ files: []
47
+ depends_on:
48
+ - harness-design-system
49
+ - harness-design
@@ -0,0 +1,282 @@
1
+ # Harness Design System
2
+
3
+ > Token-first design management. Discover existing design patterns, define intent through curated palettes and typography, generate W3C DTCG tokens, and validate every color pair for WCAG compliance.
4
+
5
+ ## When to Use
6
+
7
+ - Starting a new project that needs design tokens (colors, typography, spacing)
8
+ - Adding design consistency to an existing project that lacks a token system
9
+ - When `on_project_init` triggers fire and the project has no `design-system/tokens.json`
10
+ - When `on_new_feature` triggers fire with design scope (new theme, new component library, rebrand)
11
+ - Regenerating tokens after stakeholder feedback on palette or typography choices
12
+ - NOT for accessibility auditing of existing components (use harness-accessibility)
13
+ - NOT for aesthetic direction, mood boards, or brand strategy (use harness-design, Phase 4)
14
+ - NOT for platform-specific implementation of tokens into CSS/Tailwind/etc. (use harness-design-web/mobile, Phase 5)
15
+ - NOT for fixing individual contrast failures in code (use harness-accessibility fix phase)
16
+
17
+ ## Process
18
+
19
+ ### Phase 1: DISCOVER -- Detect Existing Design System
20
+
21
+ 1. **Read existing design files.** Search for:
22
+ - `design-system/tokens.json` -- existing W3C DTCG tokens
23
+ - `design-system/DESIGN.md` -- existing design intent documentation
24
+ - `tailwind.config.*` -- Tailwind CSS configuration with theme overrides
25
+ - CSS files with custom properties (`--color-*`, `--font-*`, `--space-*`)
26
+ - `theme.ts`, `theme.js`, `styles/variables.*` -- CSS-in-JS or preprocessor variables
27
+
28
+ 2. **Check harness configuration.** Read `harness.config.json` for:
29
+ - `design.strictness` -- enforcement level (`strict`, `standard`, `permissive`)
30
+ - `design.platforms` -- which platforms are enabled (web, mobile)
31
+ - `design.tokenPath` -- path to tokens file (default: `design-system/tokens.json`)
32
+ - `design.aestheticIntent` -- path to design intent doc (default: `design-system/DESIGN.md`)
33
+
34
+ 3. **Detect framework.** Identify the CSS strategy in use:
35
+ - Tailwind CSS (presence of `tailwind.config.*`)
36
+ - CSS-in-JS (styled-components, Emotion, Stitches imports)
37
+ - CSS Modules (`.module.css` or `.module.scss` files)
38
+ - Vanilla CSS/SCSS (global stylesheets)
39
+ - None detected (greenfield)
40
+
41
+ 4. **Identify existing patterns.** Use Grep to find:
42
+ - Color values: hex codes (`#[0-9a-fA-F]{3,8}`), rgb/hsl functions
43
+ - Font declarations: `font-family` properties, `@font-face` rules
44
+ - Spacing patterns: margin/padding values, gap values
45
+ - Count unique values to estimate design debt (many unique colors = high debt)
46
+
47
+ 5. **Load industry recommendations.** If an industry is specified (via CLI arg or config), read the industry profile from `agents/skills/shared/design-knowledge/industries/{industry}.yaml`. This provides sector-specific guidance on color psychology, typography conventions, and regulatory considerations.
48
+
49
+ 6. **Report findings before proceeding.** Present a summary:
50
+ - Existing token file: yes/no
51
+ - Framework detected: [name]
52
+ - Unique colors found: [count]
53
+ - Unique fonts found: [count]
54
+ - Industry profile loaded: yes/no
55
+ - Design debt assessment: low/medium/high
56
+
57
+ ### Phase 2: DEFINE -- Select Palette, Typography, and Spacing
58
+
59
+ 1. **Present palette options.** Load curated palettes from `agents/skills/shared/design-knowledge/palettes/curated.yaml`. Filter by industry tags if an industry is specified. Present 3-5 palette options with:
60
+ - Palette name and description
61
+ - Primary, secondary, accent, neutral color ramps
62
+ - Semantic colors (success, warning, error, info)
63
+ - Pre-computed contrast ratios for common pairs (text-on-background)
64
+
65
+ 2. **Present typography pairings.** Load pairings from `agents/skills/shared/design-knowledge/typography/pairings.yaml`. Present 3-5 options with:
66
+ - Heading font + body font combination
67
+ - Fallback stacks for each font
68
+ - Recommended size scale (base size, scale ratio)
69
+ - Line height and letter spacing recommendations
70
+
71
+ 3. **Define spacing scale.** Default: 4px base with multipliers [0.25, 0.5, 1, 1.5, 2, 3, 4, 6, 8, 12, 16]. Allow customization of:
72
+ - Base unit (4px, 8px)
73
+ - Scale multipliers
74
+ - Named aliases (xs, sm, md, lg, xl, 2xl, etc.)
75
+
76
+ 4. **Capture design intent.** Ask the user to define:
77
+ - Style: minimal, expressive, corporate, playful, editorial
78
+ - Tone: warm, cool, neutral, bold, muted
79
+ - Key differentiator: what makes this product's visual identity unique
80
+ - Anti-patterns: specific design choices to avoid
81
+
82
+ 5. **Confirm all choices.** Present a complete summary of palette, typography, spacing, and intent. Wait for user confirmation before generating. This is a hard gate -- no generation without confirmation.
83
+
84
+ ### Phase 3: GENERATE -- Create Tokens and Documentation
85
+
86
+ 1. **Generate `design-system/tokens.json`** in W3C Design Token Community Group (DTCG) format. Structure:
87
+
88
+ ```json
89
+ {
90
+ "color": {
91
+ "primary": {
92
+ "50": { "$value": "#eff6ff", "$type": "color", "$description": "Lightest primary" },
93
+ "500": { "$value": "#3b82f6", "$type": "color", "$description": "Base primary" },
94
+ "900": { "$value": "#1e3a5f", "$type": "color", "$description": "Darkest primary" }
95
+ },
96
+ "semantic": {
97
+ "success": {
98
+ "$value": "{color.green.500}",
99
+ "$type": "color",
100
+ "$description": "Success state"
101
+ },
102
+ "error": { "$value": "{color.red.500}", "$type": "color", "$description": "Error state" }
103
+ }
104
+ },
105
+ "typography": {
106
+ "heading": {
107
+ "fontFamily": { "$value": "Inter, system-ui, sans-serif", "$type": "fontFamily" },
108
+ "fontWeight": { "$value": 600, "$type": "fontWeight" }
109
+ },
110
+ "body": {
111
+ "fontFamily": { "$value": "Source Sans 3, system-ui, sans-serif", "$type": "fontFamily" },
112
+ "fontSize": { "$value": "1rem", "$type": "dimension" }
113
+ }
114
+ },
115
+ "spacing": {
116
+ "xs": { "$value": "4px", "$type": "dimension", "$description": "Extra small spacing" },
117
+ "sm": { "$value": "8px", "$type": "dimension", "$description": "Small spacing" },
118
+ "md": { "$value": "16px", "$type": "dimension", "$description": "Medium spacing" },
119
+ "lg": { "$value": "24px", "$type": "dimension", "$description": "Large spacing" },
120
+ "xl": { "$value": "32px", "$type": "dimension", "$description": "Extra large spacing" }
121
+ }
122
+ }
123
+ ```
124
+
125
+ 2. **Generate `design-system/DESIGN.md`** with:
126
+ - Aesthetic direction (style, tone, differentiator)
127
+ - Color usage guidelines (when to use primary vs. secondary vs. accent)
128
+ - Typography hierarchy (h1-h6 sizing, body text, captions)
129
+ - Spacing conventions (component padding, layout gaps, section margins)
130
+ - Anti-patterns (explicitly forbidden design choices)
131
+ - Platform-specific notes (Tailwind class mappings, CSS variable names)
132
+ - Strictness override instructions (how to change `design.strictness`)
133
+
134
+ 3. **Populate the knowledge graph.** If a graph exists at `.harness/graph/`, run `DesignIngestor` from `packages/graph/src/ingest/DesignIngestor.ts` to create graph nodes for:
135
+ - Each color token (type: `design_token`, subtype: `color`)
136
+ - Each typography token (type: `design_token`, subtype: `typography`)
137
+ - Each spacing token (type: `design_token`, subtype: `spacing`)
138
+ - The aesthetic intent (type: `aesthetic_intent`) with style, tone, differentiator, and strictness properties
139
+ - `declares_intent` edges from the project to the aesthetic intent node
140
+
141
+ ### Phase 4: VALIDATE -- Verify Tokens and Compliance
142
+
143
+ 1. **Parse `tokens.json` against W3C DTCG structure.** Verify:
144
+ - Every token has `$value` and `$type` fields
145
+ - Token references (e.g., `{color.primary.500}`) resolve to existing tokens
146
+ - No orphan tokens (defined but never referenced in DESIGN.md or usage guidelines)
147
+
148
+ 2. **Check color contrast compliance.** For every declared contrast pair:
149
+ - Calculate the contrast ratio using the WCAG 2.1 relative luminance formula
150
+ - Normal text (< 18px): require >= 4.5:1 ratio (WCAG AA)
151
+ - Large text (>= 18px or >= 14px bold): require >= 3:1 ratio (WCAG AA)
152
+ - Report each pair with its ratio and pass/fail status
153
+
154
+ 3. **Verify typography completeness.** Check that:
155
+ - Every font family declaration includes a fallback stack (at least `system-ui` or `sans-serif`/`serif`/`monospace`)
156
+ - Heading and body fonts are different (unless intentional single-font system)
157
+ - Font weights are specified as numbers, not names
158
+
159
+ 4. **Verify spacing scale.** Check that:
160
+ - Spacing values are monotonically increasing
161
+ - No gaps in the scale (e.g., jumping from 8px to 48px with nothing between)
162
+ - Base unit is consistent across all values
163
+
164
+ 5. **Run project health check.** Execute `harness validate` to ensure the new files do not break any existing constraints.
165
+
166
+ 6. **Report validation results.** Present a summary:
167
+ - DTCG structure: pass/fail with details
168
+ - Contrast pairs: N passed, M failed (list failures)
169
+ - Typography: pass/fail with details
170
+ - Spacing: pass/fail with details
171
+ - Harness validate: pass/fail
172
+
173
+ ## Harness Integration
174
+
175
+ - **`harness validate`** -- Run after generating tokens to verify project health. Token generation must not break existing constraints.
176
+ - **`harness scan`** -- Run after token changes to refresh the knowledge graph. Updated graph enables impact analysis when tokens are modified later.
177
+ - **`DesignIngestor`** (`packages/graph/src/ingest/DesignIngestor.ts`) -- Parses `tokens.json` and `DESIGN.md` to create graph nodes representing the design system. Called during the GENERATE phase.
178
+ - **`DesignConstraintAdapter`** (`packages/graph/src/constraints/DesignConstraintAdapter.ts`) -- Enforces design constraints by checking for `VIOLATES` edges in the graph. Used during validation to detect constraint violations.
179
+ - **`harness-impact-analysis`** -- When tokens change, impact analysis traces which components consume affected tokens, enabling targeted re-validation.
180
+
181
+ ## Success Criteria
182
+
183
+ - `design-system/tokens.json` exists and is valid W3C DTCG format (every token has `$value` and `$type`)
184
+ - `design-system/DESIGN.md` exists with aesthetic direction, usage guidelines, anti-patterns, and platform notes
185
+ - All declared color contrast pairs pass WCAG AA thresholds (4.5:1 normal text, 3:1 large text)
186
+ - Every font family has a fallback stack
187
+ - Spacing scale is monotonically increasing with no gaps
188
+ - Graph nodes created for each token (if graph exists at `.harness/graph/`)
189
+ - `harness validate` passes after token generation
190
+ - User confirmed palette and typography choices before generation
191
+
192
+ ## Examples
193
+
194
+ ### Example: SaaS Dashboard Project
195
+
196
+ **Context:** New SaaS analytics dashboard. Industry: `saas`. No existing design system.
197
+
198
+ **DISCOVER output:**
199
+
200
+ ```
201
+ Design System Discovery Report
202
+ -------------------------------
203
+ Existing token file: No
204
+ Framework detected: Tailwind CSS (tailwind.config.ts)
205
+ Unique colors found: 23 (high debt -- colors scattered across components)
206
+ Unique fonts found: 4 (medium debt -- inconsistent font usage)
207
+ Industry profile: Loaded (saas) -- recommends professional blues, clean sans-serif
208
+ Design debt assessment: High -- no centralized design system, ad-hoc color usage
209
+ ```
210
+
211
+ **DEFINE choices:**
212
+
213
+ ```
214
+ Selected palette: "Ocean Professional" (blue primary, slate neutral, emerald accent)
215
+ Selected typography: Inter (headings, 600 weight) + Source Sans 3 (body, 400 weight)
216
+ Spacing base: 4px with standard multipliers
217
+ Style: Minimal, data-focused
218
+ Tone: Cool, professional
219
+ Differentiator: Dense information display with generous whitespace between sections
220
+ Anti-patterns: No gradients on data elements, no decorative borders on cards
221
+ ```
222
+
223
+ **GENERATE output (tokens.json snippet):**
224
+
225
+ ```json
226
+ {
227
+ "color": {
228
+ "primary": {
229
+ "50": { "$value": "#eff6ff", "$type": "color", "$description": "Background tint" },
230
+ "100": { "$value": "#dbeafe", "$type": "color", "$description": "Hover state" },
231
+ "500": { "$value": "#3b82f6", "$type": "color", "$description": "Primary action" },
232
+ "700": { "$value": "#1d4ed8", "$type": "color", "$description": "Primary text on light" },
233
+ "900": { "$value": "#1e3a5f", "$type": "color", "$description": "Darkest primary" }
234
+ },
235
+ "neutral": {
236
+ "50": { "$value": "#f8fafc", "$type": "color", "$description": "Page background" },
237
+ "900": { "$value": "#0f172a", "$type": "color", "$description": "Primary text" }
238
+ }
239
+ },
240
+ "typography": {
241
+ "heading": {
242
+ "fontFamily": { "$value": "Inter, system-ui, sans-serif", "$type": "fontFamily" }
243
+ },
244
+ "body": {
245
+ "fontFamily": { "$value": "Source Sans 3, system-ui, sans-serif", "$type": "fontFamily" }
246
+ }
247
+ }
248
+ }
249
+ ```
250
+
251
+ **VALIDATE output:**
252
+
253
+ ```
254
+ Validation Results
255
+ ------------------
256
+ DTCG structure: PASS (42 tokens, all have $value and $type)
257
+ Contrast pairs: PASS (12/12 pairs meet WCAG AA)
258
+ - primary-700 on neutral-50: 8.1:1 PASS (normal text)
259
+ - neutral-900 on neutral-50: 15.4:1 PASS (normal text)
260
+ - neutral-50 on primary-500: 4.7:1 PASS (normal text)
261
+ Typography: PASS (all fonts have fallback stacks)
262
+ Spacing: PASS (monotonically increasing, no gaps)
263
+ Harness validate: PASS
264
+ ```
265
+
266
+ ## Gates
267
+
268
+ These are hard stops. Violating any gate means the process has broken down.
269
+
270
+ - **No tokens generated without user confirming palette and typography choices.** The DEFINE phase must end with explicit user confirmation. Do not auto-select and generate.
271
+ - **No `tokens.json` written without passing DTCG schema validation.** Every token must have `$value` and `$type`. Malformed tokens are rejected before writing to disk.
272
+ - **No contrast pair allowed below 4.5:1 for normal text.** If a selected palette produces a failing contrast pair, flag it and ask the user to choose an alternative. Do not silently accept.
273
+ - **No fonts without fallback stacks.** Every `fontFamily` token must include at least one generic fallback (`sans-serif`, `serif`, `monospace`, or `system-ui`).
274
+ - **No spacing scale with non-monotonic values.** If a user customizes spacing, validate that values increase. Reject scales where `md` is larger than `lg`.
275
+
276
+ ## Escalation
277
+
278
+ - **After 3 failed contrast validations on the same palette:** Suggest an alternative palette from the curated set that has pre-verified contrast ratios. Present the alternative with a comparison showing which pairs now pass.
279
+ - **When user rejects all curated palettes:** Accept custom colors but warn: "Custom colors have not been pre-validated for contrast compliance. Running full contrast check now." Run validation and report results before generating.
280
+ - **When existing project has conflicting design patterns:** Surface the specific conflicts (e.g., "Found 5 different blue values across 12 components"). Ask the user to choose: consolidate to the new palette, or map each existing value to the nearest token. Do not silently override existing colors.
281
+ - **When `design.strictness` is set to `permissive` but contrast fails:** Still report the failure as a warning. Permissive mode does not suppress contrast checks -- it only changes the severity from error to warning.
282
+ - **When the graph is unavailable:** Skip the graph population step in GENERATE. Log: "Graph not available at .harness/graph/ -- skipping token graph population. Run `harness scan` later to populate." Continue with file generation.