@nurix/etna 0.18.20 → 0.18.22

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 (272) hide show
  1. package/README.md +1 -1
  2. package/data/harness-index.json +1 -1
  3. package/data/harnesses/code/CLAUDE.md +3 -3
  4. package/data/harnesses/code/agents/brainstorm.md +1 -1
  5. package/data/harnesses/code/agents/maintenance.md +8 -7
  6. package/data/harnesses/code/harness.json +2 -2
  7. package/data/harnesses/code/rules/database.md +38 -0
  8. package/data/harnesses/code/rules/express.md +28 -0
  9. package/data/harnesses/code/rules/frontend.md +14 -0
  10. package/data/harnesses/code/rules/general.md +2 -40
  11. package/data/harnesses/code/rules/nomenclature.md +1 -8
  12. package/data/harnesses/code/rules/nustack.md +150 -0
  13. package/data/harnesses/code/skills/brainstorm/README.md +4 -4
  14. package/data/harnesses/code/skills/brainstorm/SKILL.md +5 -3
  15. package/data/harnesses/code/skills/brainstorm/exit-artifacts.md +15 -11
  16. package/data/harnesses/code/skills/brainstorm/templates/source-of-truth.md +5 -5
  17. package/data/harnesses/code/skills/design/SKILL.md +14 -11
  18. package/data/harnesses/code/skills/design/data/catalog/rules.csv +4 -4
  19. package/data/harnesses/code/skills/design/data/combinations/Readme.md +29 -0
  20. package/data/harnesses/code/skills/design/data/combinations/charts.csv +33 -0
  21. package/data/harnesses/code/skills/design/data/combinations/fonts-known.json +437 -0
  22. package/data/harnesses/code/skills/design/data/combinations/icons.csv +157 -0
  23. package/data/harnesses/code/skills/design/data/combinations/landing.csv +38 -0
  24. package/data/harnesses/code/skills/design/data/combinations/lucide-names.json +2001 -0
  25. package/data/harnesses/code/skills/design/data/combinations/manifest.json +283 -0
  26. package/data/harnesses/code/skills/design/data/combinations/palettes.csv +49 -0
  27. package/data/harnesses/code/skills/design/data/combinations/product-router.csv +80 -0
  28. package/data/harnesses/code/skills/design/data/combinations/styles.csv +54 -0
  29. package/data/harnesses/code/skills/design/data/combinations/typography.csv +61 -0
  30. package/data/harnesses/code/skills/design/data/design-md/SCHEMA.md +27 -238
  31. package/data/harnesses/code/skills/design/data/design-md/library/airbnb.md +7 -88
  32. package/data/harnesses/code/skills/design/data/design-md/library/airtable.md +1 -82
  33. package/data/harnesses/code/skills/design/data/design-md/library/anthropic-claude.md +4 -85
  34. package/data/harnesses/code/skills/design/data/design-md/library/apple.md +5 -86
  35. package/data/harnesses/code/skills/design/data/design-md/library/binance.md +4 -87
  36. package/data/harnesses/code/skills/design/data/design-md/library/bmw.md +7 -86
  37. package/data/harnesses/code/skills/design/data/design-md/library/cal.md +4 -84
  38. package/data/harnesses/code/skills/design/data/design-md/library/clay.md +5 -86
  39. package/data/harnesses/code/skills/design/data/design-md/library/clickhouse.md +3 -84
  40. package/data/harnesses/code/skills/design/data/design-md/library/cohere.md +2 -82
  41. package/data/harnesses/code/skills/design/data/design-md/library/coinbase.md +10 -91
  42. package/data/harnesses/code/skills/design/data/design-md/library/composio.md +2 -84
  43. package/data/harnesses/code/skills/design/data/design-md/library/cursor.md +3 -85
  44. package/data/harnesses/code/skills/design/data/design-md/library/elevenlabs.md +7 -90
  45. package/data/harnesses/code/skills/design/data/design-md/library/expo.md +0 -80
  46. package/data/harnesses/code/skills/design/data/design-md/library/figma.md +0 -80
  47. package/data/harnesses/code/skills/design/data/design-md/library/framer.md +5 -85
  48. package/data/harnesses/code/skills/design/data/design-md/library/hashicorp.md +2 -82
  49. package/data/harnesses/code/skills/design/data/design-md/library/ibm.md +5 -86
  50. package/data/harnesses/code/skills/design/data/design-md/library/intercom.md +9 -91
  51. package/data/harnesses/code/skills/design/data/design-md/library/kraken.md +9 -89
  52. package/data/harnesses/code/skills/design/data/design-md/library/linear-app.md +0 -115
  53. package/data/harnesses/code/skills/design/data/design-md/library/lovable.md +5 -85
  54. package/data/harnesses/code/skills/design/data/design-md/library/meta.md +7 -88
  55. package/data/harnesses/code/skills/design/data/design-md/library/minimax.md +3 -84
  56. package/data/harnesses/code/skills/design/data/design-md/library/mintlify.md +4 -85
  57. package/data/harnesses/code/skills/design/data/design-md/library/miro.md +8 -88
  58. package/data/harnesses/code/skills/design/data/design-md/library/mistral-ai.md +8 -88
  59. package/data/harnesses/code/skills/design/data/design-md/library/mongodb.md +4 -85
  60. package/data/harnesses/code/skills/design/data/design-md/library/notion.md +4 -84
  61. package/data/harnesses/code/skills/design/data/design-md/library/nvidia.md +7 -88
  62. package/data/harnesses/code/skills/design/data/design-md/library/ollama.md +5 -86
  63. package/data/harnesses/code/skills/design/data/design-md/library/opencode-ai.md +6 -87
  64. package/data/harnesses/code/skills/design/data/design-md/library/posthog.md +9 -91
  65. package/data/harnesses/code/skills/design/data/design-md/library/raycast.md +5 -88
  66. package/data/harnesses/code/skills/design/data/design-md/library/replicate.md +9 -89
  67. package/data/harnesses/code/skills/design/data/design-md/library/resend.md +4 -119
  68. package/data/harnesses/code/skills/design/data/design-md/library/revolut.md +4 -84
  69. package/data/harnesses/code/skills/design/data/design-md/library/runwayml.md +0 -82
  70. package/data/harnesses/code/skills/design/data/design-md/library/sanity.md +3 -86
  71. package/data/harnesses/code/skills/design/data/design-md/library/sentry.md +13 -94
  72. package/data/harnesses/code/skills/design/data/design-md/library/shopify.md +2 -82
  73. package/data/harnesses/code/skills/design/data/design-md/library/slack.md +6 -88
  74. package/data/harnesses/code/skills/design/data/design-md/library/spacex.md +13 -94
  75. package/data/harnesses/code/skills/design/data/design-md/library/spotify.md +4 -86
  76. package/data/harnesses/code/skills/design/data/design-md/library/stripe.md +7 -88
  77. package/data/harnesses/code/skills/design/data/design-md/library/supabase.md +6 -88
  78. package/data/harnesses/code/skills/design/data/design-md/library/superhuman.md +5 -86
  79. package/data/harnesses/code/skills/design/data/design-md/library/tesla.md +6 -86
  80. package/data/harnesses/code/skills/design/data/design-md/library/theverge.md +12 -93
  81. package/data/harnesses/code/skills/design/data/design-md/library/together-ai.md +11 -91
  82. package/data/harnesses/code/skills/design/data/design-md/library/uber.md +8 -88
  83. package/data/harnesses/code/skills/design/data/design-md/library/vercel.md +2 -82
  84. package/data/harnesses/code/skills/design/data/design-md/library/voltagent.md +11 -126
  85. package/data/harnesses/code/skills/design/data/design-md/library/warp.md +8 -88
  86. package/data/harnesses/code/skills/design/data/design-md/library/webflow.md +3 -83
  87. package/data/harnesses/code/skills/design/data/design-md/library/wired.md +10 -91
  88. package/data/harnesses/code/skills/design/data/design-md/library/wise.md +7 -90
  89. package/data/harnesses/code/skills/design/data/design-md/library/x-ai.md +6 -88
  90. package/data/harnesses/code/skills/design/data/design-md/library/zapier.md +9 -89
  91. package/data/harnesses/code/skills/design/data/design-md/nurix.md +4 -87
  92. package/data/harnesses/code/skills/design/data/design-tokens/SCHEMA.md +580 -0
  93. package/data/harnesses/code/skills/design/data/design-tokens/airbnb/design.resolver.json +20 -0
  94. package/data/harnesses/code/skills/design/data/design-tokens/airbnb/design.tokens.json +964 -0
  95. package/data/harnesses/code/skills/design/data/design-tokens/airtable/design.resolver.json +20 -0
  96. package/data/harnesses/code/skills/design/data/design-tokens/airtable/design.tokens.json +960 -0
  97. package/data/harnesses/code/skills/design/data/design-tokens/anthropic-claude/design.resolver.json +20 -0
  98. package/data/harnesses/code/skills/design/data/design-tokens/anthropic-claude/design.tokens.json +965 -0
  99. package/data/harnesses/code/skills/design/data/design-tokens/apple/design.resolver.json +20 -0
  100. package/data/harnesses/code/skills/design/data/design-tokens/apple/design.tokens.json +954 -0
  101. package/data/harnesses/code/skills/design/data/design-tokens/binance/design.resolver.json +20 -0
  102. package/data/harnesses/code/skills/design/data/design-tokens/binance/design.tokens.json +949 -0
  103. package/data/harnesses/code/skills/design/data/design-tokens/bmw/design.resolver.json +20 -0
  104. package/data/harnesses/code/skills/design/data/design-tokens/bmw/design.tokens.json +962 -0
  105. package/data/harnesses/code/skills/design/data/design-tokens/cal/design.resolver.json +20 -0
  106. package/data/harnesses/code/skills/design/data/design-tokens/cal/design.tokens.json +958 -0
  107. package/data/harnesses/code/skills/design/data/design-tokens/clay/design.resolver.json +20 -0
  108. package/data/harnesses/code/skills/design/data/design-tokens/clay/design.tokens.json +953 -0
  109. package/data/harnesses/code/skills/design/data/design-tokens/clickhouse/design.resolver.json +20 -0
  110. package/data/harnesses/code/skills/design/data/design-tokens/clickhouse/design.tokens.json +960 -0
  111. package/data/harnesses/code/skills/design/data/design-tokens/cohere/design.resolver.json +20 -0
  112. package/data/harnesses/code/skills/design/data/design-tokens/cohere/design.tokens.json +973 -0
  113. package/data/harnesses/code/skills/design/data/design-tokens/coinbase/design.resolver.json +20 -0
  114. package/data/harnesses/code/skills/design/data/design-tokens/coinbase/design.tokens.json +954 -0
  115. package/data/harnesses/code/skills/design/data/design-tokens/composio/design.resolver.json +20 -0
  116. package/data/harnesses/code/skills/design/data/design-tokens/composio/design.tokens.json +963 -0
  117. package/data/harnesses/code/skills/design/data/design-tokens/cursor/design.resolver.json +20 -0
  118. package/data/harnesses/code/skills/design/data/design-tokens/cursor/design.tokens.json +968 -0
  119. package/data/harnesses/code/skills/design/data/design-tokens/elevenlabs/design.resolver.json +20 -0
  120. package/data/harnesses/code/skills/design/data/design-tokens/elevenlabs/design.tokens.json +981 -0
  121. package/data/harnesses/code/skills/design/data/design-tokens/expo/design.resolver.json +20 -0
  122. package/data/harnesses/code/skills/design/data/design-tokens/expo/design.tokens.json +962 -0
  123. package/data/harnesses/code/skills/design/data/design-tokens/figma/design.resolver.json +20 -0
  124. package/data/harnesses/code/skills/design/data/design-tokens/figma/design.tokens.json +964 -0
  125. package/data/harnesses/code/skills/design/data/design-tokens/framer/design.resolver.json +20 -0
  126. package/data/harnesses/code/skills/design/data/design-tokens/framer/design.tokens.json +959 -0
  127. package/data/harnesses/code/skills/design/data/design-tokens/goldens.json +251 -0
  128. package/data/harnesses/code/skills/design/data/design-tokens/hashicorp/design.resolver.json +20 -0
  129. package/data/harnesses/code/skills/design/data/design-tokens/hashicorp/design.tokens.json +965 -0
  130. package/data/harnesses/code/skills/design/data/design-tokens/ibm/design.resolver.json +20 -0
  131. package/data/harnesses/code/skills/design/data/design-tokens/ibm/design.tokens.json +978 -0
  132. package/data/harnesses/code/skills/design/data/design-tokens/intercom/design.resolver.json +20 -0
  133. package/data/harnesses/code/skills/design/data/design-tokens/intercom/design.tokens.json +982 -0
  134. package/data/harnesses/code/skills/design/data/design-tokens/kraken/design.resolver.json +20 -0
  135. package/data/harnesses/code/skills/design/data/design-tokens/kraken/design.tokens.json +958 -0
  136. package/data/harnesses/code/skills/design/data/design-tokens/linear-app/design.resolver.json +23 -0
  137. package/data/harnesses/code/skills/design/data/design-tokens/linear-app/design.tokens.dark.json +589 -0
  138. package/data/harnesses/code/skills/design/data/design-tokens/linear-app/design.tokens.json +964 -0
  139. package/data/harnesses/code/skills/design/data/design-tokens/lovable/design.resolver.json +20 -0
  140. package/data/harnesses/code/skills/design/data/design-tokens/lovable/design.tokens.json +955 -0
  141. package/data/harnesses/code/skills/design/data/design-tokens/meta/design.resolver.json +20 -0
  142. package/data/harnesses/code/skills/design/data/design-tokens/meta/design.tokens.json +977 -0
  143. package/data/harnesses/code/skills/design/data/design-tokens/minimax/design.resolver.json +20 -0
  144. package/data/harnesses/code/skills/design/data/design-tokens/minimax/design.tokens.json +950 -0
  145. package/data/harnesses/code/skills/design/data/design-tokens/mintlify/design.resolver.json +20 -0
  146. package/data/harnesses/code/skills/design/data/design-tokens/mintlify/design.tokens.json +976 -0
  147. package/data/harnesses/code/skills/design/data/design-tokens/miro/design.resolver.json +20 -0
  148. package/data/harnesses/code/skills/design/data/design-tokens/miro/design.tokens.json +979 -0
  149. package/data/harnesses/code/skills/design/data/design-tokens/mistral-ai/design.resolver.json +20 -0
  150. package/data/harnesses/code/skills/design/data/design-tokens/mistral-ai/design.tokens.json +955 -0
  151. package/data/harnesses/code/skills/design/data/design-tokens/mongodb/design.resolver.json +20 -0
  152. package/data/harnesses/code/skills/design/data/design-tokens/mongodb/design.tokens.json +958 -0
  153. package/data/harnesses/code/skills/design/data/design-tokens/notion/design.resolver.json +20 -0
  154. package/data/harnesses/code/skills/design/data/design-tokens/notion/design.tokens.json +953 -0
  155. package/data/harnesses/code/skills/design/data/design-tokens/nurix/design.resolver.json +20 -0
  156. package/data/harnesses/code/skills/design/data/design-tokens/nurix/design.tokens.json +904 -0
  157. package/data/harnesses/code/skills/design/data/design-tokens/nvidia/design.resolver.json +20 -0
  158. package/data/harnesses/code/skills/design/data/design-tokens/nvidia/design.tokens.json +957 -0
  159. package/data/harnesses/code/skills/design/data/design-tokens/ollama/design.resolver.json +20 -0
  160. package/data/harnesses/code/skills/design/data/design-tokens/ollama/design.tokens.json +945 -0
  161. package/data/harnesses/code/skills/design/data/design-tokens/opencode-ai/design.resolver.json +20 -0
  162. package/data/harnesses/code/skills/design/data/design-tokens/opencode-ai/design.tokens.json +960 -0
  163. package/data/harnesses/code/skills/design/data/design-tokens/posthog/design.resolver.json +20 -0
  164. package/data/harnesses/code/skills/design/data/design-tokens/posthog/design.tokens.json +953 -0
  165. package/data/harnesses/code/skills/design/data/design-tokens/raycast/design.resolver.json +20 -0
  166. package/data/harnesses/code/skills/design/data/design-tokens/raycast/design.tokens.json +955 -0
  167. package/data/harnesses/code/skills/design/data/design-tokens/replicate/design.resolver.json +20 -0
  168. package/data/harnesses/code/skills/design/data/design-tokens/replicate/design.tokens.json +958 -0
  169. package/data/harnesses/code/skills/design/data/design-tokens/resend/design.resolver.json +23 -0
  170. package/data/harnesses/code/skills/design/data/design-tokens/resend/design.tokens.dark.json +613 -0
  171. package/data/harnesses/code/skills/design/data/design-tokens/resend/design.tokens.json +968 -0
  172. package/data/harnesses/code/skills/design/data/design-tokens/revolut/design.resolver.json +20 -0
  173. package/data/harnesses/code/skills/design/data/design-tokens/revolut/design.tokens.json +956 -0
  174. package/data/harnesses/code/skills/design/data/design-tokens/runwayml/design.resolver.json +20 -0
  175. package/data/harnesses/code/skills/design/data/design-tokens/runwayml/design.tokens.json +960 -0
  176. package/data/harnesses/code/skills/design/data/design-tokens/sanity/design.resolver.json +20 -0
  177. package/data/harnesses/code/skills/design/data/design-tokens/sanity/design.tokens.json +958 -0
  178. package/data/harnesses/code/skills/design/data/design-tokens/sentry/design.resolver.json +20 -0
  179. package/data/harnesses/code/skills/design/data/design-tokens/sentry/design.tokens.json +980 -0
  180. package/data/harnesses/code/skills/design/data/design-tokens/shopify/design.resolver.json +20 -0
  181. package/data/harnesses/code/skills/design/data/design-tokens/shopify/design.tokens.json +964 -0
  182. package/data/harnesses/code/skills/design/data/design-tokens/slack/design.resolver.json +20 -0
  183. package/data/harnesses/code/skills/design/data/design-tokens/slack/design.tokens.json +957 -0
  184. package/data/harnesses/code/skills/design/data/design-tokens/spacex/design.resolver.json +20 -0
  185. package/data/harnesses/code/skills/design/data/design-tokens/spacex/design.tokens.json +979 -0
  186. package/data/harnesses/code/skills/design/data/design-tokens/spotify/design.resolver.json +20 -0
  187. package/data/harnesses/code/skills/design/data/design-tokens/spotify/design.tokens.json +974 -0
  188. package/data/harnesses/code/skills/design/data/design-tokens/stripe/design.resolver.json +20 -0
  189. package/data/harnesses/code/skills/design/data/design-tokens/stripe/design.tokens.json +973 -0
  190. package/data/harnesses/code/skills/design/data/design-tokens/supabase/design.resolver.json +20 -0
  191. package/data/harnesses/code/skills/design/data/design-tokens/supabase/design.tokens.json +979 -0
  192. package/data/harnesses/code/skills/design/data/design-tokens/superhuman/design.resolver.json +20 -0
  193. package/data/harnesses/code/skills/design/data/design-tokens/superhuman/design.tokens.json +966 -0
  194. package/data/harnesses/code/skills/design/data/design-tokens/tesla/design.resolver.json +20 -0
  195. package/data/harnesses/code/skills/design/data/design-tokens/tesla/design.tokens.json +961 -0
  196. package/data/harnesses/code/skills/design/data/design-tokens/theverge/design.resolver.json +20 -0
  197. package/data/harnesses/code/skills/design/data/design-tokens/theverge/design.tokens.json +977 -0
  198. package/data/harnesses/code/skills/design/data/design-tokens/together-ai/design.resolver.json +20 -0
  199. package/data/harnesses/code/skills/design/data/design-tokens/together-ai/design.tokens.json +991 -0
  200. package/data/harnesses/code/skills/design/data/design-tokens/uber/design.resolver.json +20 -0
  201. package/data/harnesses/code/skills/design/data/design-tokens/uber/design.tokens.json +966 -0
  202. package/data/harnesses/code/skills/design/data/design-tokens/vercel/design.resolver.json +20 -0
  203. package/data/harnesses/code/skills/design/data/design-tokens/vercel/design.tokens.json +988 -0
  204. package/data/harnesses/code/skills/design/data/design-tokens/voltagent/design.resolver.json +23 -0
  205. package/data/harnesses/code/skills/design/data/design-tokens/voltagent/design.tokens.dark.json +602 -0
  206. package/data/harnesses/code/skills/design/data/design-tokens/voltagent/design.tokens.json +974 -0
  207. package/data/harnesses/code/skills/design/data/design-tokens/warp/design.resolver.json +20 -0
  208. package/data/harnesses/code/skills/design/data/design-tokens/warp/design.tokens.json +979 -0
  209. package/data/harnesses/code/skills/design/data/design-tokens/webflow/design.resolver.json +20 -0
  210. package/data/harnesses/code/skills/design/data/design-tokens/webflow/design.tokens.json +960 -0
  211. package/data/harnesses/code/skills/design/data/design-tokens/wired/design.resolver.json +20 -0
  212. package/data/harnesses/code/skills/design/data/design-tokens/wired/design.tokens.json +968 -0
  213. package/data/harnesses/code/skills/design/data/design-tokens/wise/design.resolver.json +20 -0
  214. package/data/harnesses/code/skills/design/data/design-tokens/wise/design.tokens.json +965 -0
  215. package/data/harnesses/code/skills/design/data/design-tokens/x-ai/design.resolver.json +20 -0
  216. package/data/harnesses/code/skills/design/data/design-tokens/x-ai/design.tokens.json +988 -0
  217. package/data/harnesses/code/skills/design/data/design-tokens/zapier/design.resolver.json +20 -0
  218. package/data/harnesses/code/skills/design/data/design-tokens/zapier/design.tokens.json +978 -0
  219. package/data/harnesses/code/skills/design/data/operator-pack/surface-catalog.md +1 -1
  220. package/data/harnesses/code/skills/design/references/create.md +14 -9
  221. package/data/harnesses/code/skills/design/references/diagnosis.md +1 -1
  222. package/data/harnesses/code/skills/design/references/hard-rules.md +4 -4
  223. package/data/harnesses/code/skills/design/references/improve.md +11 -9
  224. package/data/harnesses/code/skills/design/references/introspect.md +1 -1
  225. package/data/harnesses/code/skills/design/references/personality.md +337 -413
  226. package/data/harnesses/code/skills/design/scripts/convert-design-md.mjs +1032 -0
  227. package/data/harnesses/code/skills/design/scripts/derive-personality.mjs +596 -296
  228. package/data/harnesses/code/skills/design/scripts/{detector.mjs → lib/checks.mjs} +145 -140
  229. package/data/harnesses/code/skills/design/scripts/lib/golden.mjs +26 -0
  230. package/data/harnesses/code/skills/design/scripts/phase-gate.mjs +105 -37
  231. package/data/harnesses/code/skills/design/scripts/preship-sweep.mjs +60 -73
  232. package/data/harnesses/code/skills/design/scripts/render-rung.mjs +1 -1
  233. package/data/harnesses/code/skills/design/scripts/scaffold.mjs +1 -1
  234. package/data/harnesses/code/skills/design/scripts/self-integrity.mjs +205 -37
  235. package/data/harnesses/code/skills/design/scripts/snapshot-goldens.mjs +68 -0
  236. package/data/harnesses/code/skills/design/scripts/validate-combinations.mjs +314 -0
  237. package/data/harnesses/code/skills/documentation/SKILL.md +61 -17
  238. package/data/harnesses/code/skills/documentation/references/examples.md +41 -0
  239. package/data/harnesses/code/skills/documentation/references/style-guide.md +14 -9
  240. package/data/harnesses/code/skills/documentation/references/templates.md +306 -52
  241. package/data/harnesses/etna/CLAUDE.md +3 -3
  242. package/data/harnesses/etna/agents/brainstorm.md +1 -1
  243. package/data/harnesses/etna/agents/maintenance.md +8 -7
  244. package/data/harnesses/etna/harness.json +2 -2
  245. package/data/harnesses/etna/rules/general.md +2 -40
  246. package/data/harnesses/etna/rules/nomenclature.md +1 -8
  247. package/data/harnesses/etna/skills/brainstorm/README.md +4 -4
  248. package/data/harnesses/etna/skills/brainstorm/SKILL.md +5 -3
  249. package/data/harnesses/etna/skills/brainstorm/exit-artifacts.md +15 -11
  250. package/data/harnesses/etna/skills/brainstorm/templates/source-of-truth.md +5 -5
  251. package/data/harnesses/etna/skills/documentation/SKILL.md +61 -17
  252. package/data/harnesses/etna/skills/documentation/references/examples.md +41 -0
  253. package/data/harnesses/etna/skills/documentation/references/style-guide.md +14 -9
  254. package/data/harnesses/etna/skills/documentation/references/templates.md +306 -52
  255. package/data/harnesses/mobile/CLAUDE.md +3 -3
  256. package/data/harnesses/mobile/agents/brainstorm.md +1 -1
  257. package/data/harnesses/mobile/agents/maintenance.md +8 -7
  258. package/data/harnesses/mobile/harness.json +2 -2
  259. package/data/harnesses/mobile/rules/database.md +38 -0
  260. package/data/harnesses/mobile/rules/general.md +2 -40
  261. package/data/harnesses/mobile/rules/nomenclature.md +1 -8
  262. package/data/harnesses/mobile/rules/nustack.md +150 -0
  263. package/data/harnesses/mobile/skills/brainstorm/README.md +4 -4
  264. package/data/harnesses/mobile/skills/brainstorm/SKILL.md +5 -3
  265. package/data/harnesses/mobile/skills/brainstorm/exit-artifacts.md +15 -11
  266. package/data/harnesses/mobile/skills/brainstorm/templates/source-of-truth.md +5 -5
  267. package/data/harnesses/mobile/skills/documentation/SKILL.md +61 -17
  268. package/data/harnesses/mobile/skills/documentation/references/examples.md +41 -0
  269. package/data/harnesses/mobile/skills/documentation/references/style-guide.md +14 -9
  270. package/data/harnesses/mobile/skills/documentation/references/templates.md +306 -52
  271. package/package.json +1 -1
  272. package/data/harnesses/code/skills/design/scripts/hook-config.json +0 -11
@@ -0,0 +1,580 @@
1
+ # design-tokens — schema `design-tokens/v1`
2
+
3
+ A look travels as a **design-tokens artifact**: three JSON files in the pinned **DTCG 2025.10 Stable**
4
+ grammar (W3C Design Tokens Community Group — the dated snapshot; the live drafts carry the spec's own
5
+ "do not implement" warning). The artifact is exact, queryable, and diffable — no consumer interprets
6
+ prose. [`derive-personality.mjs`](../../scripts/derive-personality.mjs) is the reference consumer:
7
+ `--check` is the coverage gate, `--emit` writes `personality.css` / `globals.css` / the `<html>`
8
+ attributes. The check engine ([`lib/checks.mjs`](../../scripts/lib/checks.mjs), fired at the phase
9
+ gates and the verify/pre-ship sweeps) reads the lever manifest from the artifact's `$extensions` payload.
10
+
11
+ The token files are a project's **canonical look state**. Create writes them, improve rewrites them,
12
+ extraction on a foreign UI recovers them. No readable design.md view is generated from the token
13
+ files — the nine-section [design.md format](../design-md/SCHEMA.md) serves only as the library's
14
+ documentation format.
15
+
16
+ **One schema, every origin.** A project's own artifact, an extracted artifact, a shipped library
17
+ entry, and the Nurix default all use this identical shape; only the payload's `provenance` varies.
18
+
19
+ ---
20
+
21
+ ## The three files
22
+
23
+ | File | Ships | Contents |
24
+ | --- | --- | --- |
25
+ | `design.tokens.json` | always | The base/light set: the 26 visual primitives, the 34 color roles, the typography composites, and the file-level `$extensions["com.nurix.design"]` payload. The base set **is** the light rendering — light is never omitted. |
26
+ | `design.tokens.dark.json` | only when the look has dark values | The dark modifier set: the `color` group remapped, nothing else. |
27
+ | `design.resolver.json` | always | Sets, modifiers, and resolution order. Light-first. |
28
+
29
+ The three files sit together in one directory: a project's artifact lives at the repo root; a library
30
+ entry lives at `data/design-tokens/<product-slug>/`; the Nurix default at `data/design-tokens/nurix/`.
31
+
32
+ Look resolution is project-first — `project`/`extracted` artifacts win outright; a `library` entry
33
+ serves only on confirmed match; the `default` serves when nothing else does. The origin is recorded in
34
+ the payload's `provenance` field:
35
+
36
+ | `provenance` | Origin | Precedence |
37
+ | --- | --- | --- |
38
+ | `project` | The project's own artifact, written by a create run. | Wins outright when present. |
39
+ | `extracted` | Recovered from a UI this skill did not build. | Same tier as `project`. |
40
+ | `library` | A shipped library entry. | Serves only when the brief names or resembles the product and the user confirms. |
41
+ | `default` | The Nurix default. | Worn when there is no project artifact and no confirmed library match. |
42
+
43
+ ---
44
+
45
+ ## DTCG grammar in this artifact
46
+
47
+ A token is an object with `$type` and `$value`, plus optional `$description` and `$extensions`.
48
+ Groups nest; the file root is a group and carries the file-level `$extensions`. An alias is the
49
+ string `"{path.to.token}"` and may appear anywhere a value of the target's type is legal, including
50
+ composite sub-values; alias chains are legal, cycles are not. Exactly eight `$type` values appear —
51
+ **never invent a custom `$type`**:
52
+
53
+ | `$type` | `$value` shape | Used by |
54
+ | --- | --- | --- |
55
+ | `color` | `{ "colorSpace": "oklch"\|"srgb", "components": [n, n, n], "alpha"?: n, "hex"?: "#rrggbb" }` | the 34 color roles |
56
+ | `dimension` | `{ "value": n, "unit": "px" }` (`px`\|`rem` per spec; this artifact always writes `px`) | `radius`, `border-weight`, `icon-size-base`, the 8 layout primitives, ramp `fontSize` |
57
+ | `duration` | `{ "value": n, "unit": "ms" }` | the 4 duration primitives |
58
+ | `cubicBezier` | `[x1, y1, x2, y2]` (numbers; x in 0–1) | `ease-default` |
59
+ | `fontFamily` | array of family-name strings | `font-sans`, `font-mono`, `typography.family.*` |
60
+ | `fontWeight` | number 100–900 | `font-weight-normal`, `font-weight-strong`, ramp `fontWeight` |
61
+ | `number` | plain JSON number | `shadow-intensity`, `density-gap`, `density-inset`, `heading-tracking`, `contrast-boost`, `icon-stroke`, ramp `lineHeight` / `letterSpacing` |
62
+ | `typography` | composite `{ fontFamily, fontSize, fontWeight, letterSpacing, lineHeight }` | the 6 ramp steps |
63
+
64
+ Color rules: an oklch source stays `"colorSpace": "oklch"` with `components` carrying the literal
65
+ `[L, C, H]` numbers from the source string; a hex/rgba (or any other CSS color) source becomes
66
+ `"colorSpace": "srgb"` with `components` as `[r, g, b]` in 0–1 (at most 5 decimals), the `hex`
67
+ fallback field, and `alpha` when the source carries one:
68
+
69
+ ```json
70
+ {
71
+ "$type": "color",
72
+ "$value": { "colorSpace": "srgb", "components": [0.3098, 0.2745, 0.898], "alpha": 1, "hex": "#4f46e5" },
73
+ "$extensions": { "com.nurix.design": { "css": "#4f46e5" } }
74
+ }
75
+ ```
76
+
77
+ **One documented deviation.** The spec's `dimension` carries only `px`|`rem`, so an `em` tracking
78
+ value cannot be a dimension. `heading-tracking` is therefore a `number` token (an em multiplier) with
79
+ its exact source string preserved (the preserved-css pattern, below), and a typography composite's
80
+ `letterSpacing` sub-value is a number (em multiplier) or an alias to one — not a spec dimension.
81
+ Everything else in the artifact is spec-shaped.
82
+
83
+ ---
84
+
85
+ ## The file-level payload — `$extensions["com.nurix.design"]`
86
+
87
+ One vendor namespace, reverse-domain, on the **base file's root group only** (the dark file carries no
88
+ payload; the resolver has no `$extensions`). It holds everything the look needs that is not a design
89
+ token:
90
+
91
+ | Key | Type | Legal values / shape |
92
+ | --- | --- | --- |
93
+ | `schema` | string | Literal `design-tokens/v1`. A parser refuses an unknown value. |
94
+ | `dtcg` | string | Literal `2025.10` — the pinned DTCG snapshot this artifact conforms to. |
95
+ | `product` | string | The product name; slugified (lowercase, non-alphanumeric runs → `-`) it becomes the `data-style` value. |
96
+ | `provenance` | enum | `project` \| `extracted` \| `library` \| `default` |
97
+ | `sourced` | string | ISO date the artifact was authored, extracted, or last re-sourced. |
98
+ | `verbosity` | enum | `full` \| `default` \| `compact` \| `expert` — emits `data-verbosity` on `<html>`. |
99
+ | `feedback` | enum | `subtle` \| `minimal` — emits `data-feedback`. |
100
+ | `density-tier` | enum | `spacious` \| `standard` \| `dense` — emits `data-density`; drives the density base multipliers. |
101
+ | `product-traits` | array | Non-empty list of product-type trait slugs the front gate reads — e.g. `["review-queue", "case-detail", "fintech"]`. Never emitted to CSS. |
102
+ | `lever-manifest` | object | The drift-check allowlist (below). |
103
+
104
+ Payload fields are always concrete — the hint mechanism (below) exists only on tokens.
105
+
106
+ ### The lever manifest
107
+
108
+ The machine-readable allowlist the drift check reads: the check engine flags any emitted value outside
109
+ this vocabulary — a radius not on `radius-scale`, a spacing off `spacing-scale`, a motion duration off
110
+ `motion.durations`.
111
+
112
+ | Key | Shape | Rule |
113
+ | --- | --- | --- |
114
+ | `spacing-scale` | number[] (px) | Non-empty, ascending — on-scale values only. |
115
+ | `radius-scale` | number[] (px) | Non-empty, ascending. |
116
+ | `shadow-levels` | string[] | Non-empty; names drawn from `none` `2xs` `xs` `sm` `md` `lg` `xl` `2xl`, ordered by strictly increasing intensity. |
117
+ | `motion` | `{ "durations": number[], "easings": string[] }` | Durations in ms, non-empty, ascending; easings non-empty CSS easing strings. |
118
+ | `icons` | `{ "family": string }` | The icon family, e.g. `lucide`. |
119
+ | `accent-count` | number | ≥ 1. |
120
+
121
+ The manifest carries only vocabulary that is not already a token — **it never restates a token
122
+ value**. The allowlists that are tokens are read from the tokens: the 34 color values from the
123
+ `color` group, the font stacks from `primitive.font-sans` / `primitive.font-mono`, the icon stroke
124
+ from `primitive.icon-stroke`.
125
+
126
+ ---
127
+
128
+ ## `primitive.*` — the 26 visual primitives
129
+
130
+ One group, `primitive`, holding all 26 (leaf names are law — they map 1:1 to the emitted CSS
131
+ variables, without the leading `--`). Every token is either concrete or hinted.
132
+
133
+ | Family | Token (`primitive.…`) | `$type` | Notes | Example (source form) |
134
+ | --- | --- | --- | --- | --- |
135
+ | geometric | `radius` | `dimension` | | `6px` |
136
+ | | `shadow-intensity` | `number` | 0–1 multiplier on the emitted `--shadow-*` alpha | `0.4` |
137
+ | | `border-weight` | `dimension` | | `1px` |
138
+ | | `density-gap` | `number` | multiplier on the `0.25rem` spacing base | `1` |
139
+ | | `density-inset` | `number` | multiplier on component insets | `1` |
140
+ | typographic | `font-sans` | `fontFamily` | carries `.css` | `Inter, system-ui, sans-serif` |
141
+ | | `font-mono` | `fontFamily` | carries `.css` | `Geist Mono, ui-monospace, SFMono-Regular, monospace` |
142
+ | | `font-weight-normal` | `fontWeight` | | `400` |
143
+ | | `font-weight-strong` | `fontWeight` | | `600` |
144
+ | | `heading-tracking` | `number` | em multiplier; carries `.css` | `-0.01em` |
145
+ | temporal | `duration-unit` | `duration` | the tempo base | `50ms` |
146
+ | | `duration-fast` | `duration` | | `100ms` |
147
+ | | `duration-normal` | `duration` | | `150ms` |
148
+ | | `duration-slow` | `duration` | | `250ms` |
149
+ | | `ease-default` | `cubicBezier` | carries `.css` | `cubic-bezier(0.4,0,0.2,1)` |
150
+ | surface | `contrast-boost` | `number` | multiplier, 1 = default | `1` |
151
+ | iconography | `icon-stroke` | `number` | px stroke-width | `1.75` |
152
+ | | `icon-size-base` | `dimension` | | `16px` |
153
+ | layout | `sidebar-width-expanded` | `dimension` | | `248px` |
154
+ | | `sidebar-width-collapsed` | `dimension` | | `56px` |
155
+ | | `topbar-height` | `dimension` | | `52px` |
156
+ | | `side-panel-width` | `dimension` | | `420px` |
157
+ | | `side-panel-width-rich` | `dimension` | | `640px` |
158
+ | | `modal-width-max` | `dimension` | | `560px` |
159
+ | | `form-max-width` | `dimension` | | `640px` |
160
+ | | `table-row-height` | `dimension` | | `40px` |
161
+
162
+ **Derived, never stored.** Emission computes `--ease-enter`, `--ease-exit`, and `--stagger-delay`
163
+ from `ease-default` and `duration-unit`. They are not tokens, not authored, and not part of the
164
+ coverage gate. Do not add them.
165
+
166
+ ---
167
+
168
+ ## `color.*` — the 34 color roles
169
+
170
+ One flat group, `color`, holding all 34 (leaf names map 1:1 to the emitted `--<name>` variables).
171
+ Every token is `$type: "color"` with a typed `$value` **and** mandatory preserved `.css`.
172
+
173
+ - **Semantic (17):** `background` · `foreground` · `card` · `card-foreground` · `muted` ·
174
+ `muted-foreground` · `border` · `input` · `ring` · `primary` · `primary-foreground` · `accent` ·
175
+ `accent-foreground` · `destructive` · `destructive-foreground` · `success` · `warning`.
176
+ - **Substrate (17):** `popover` · `popover-foreground` · `secondary` · `secondary-foreground` ·
177
+ `chart-1` · `chart-2` · `chart-3` · `chart-4` · `chart-5` · `sidebar` · `sidebar-foreground` ·
178
+ `sidebar-primary` · `sidebar-primary-foreground` · `sidebar-accent` · `sidebar-accent-foreground` ·
179
+ `sidebar-border` · `sidebar-ring`.
180
+
181
+ No consumed token falls back to a shadcn-gray default: emission sets all 34. A color token may alias
182
+ another (`"$value": "{color.primary}"`), in which case it takes the target's `.css`; mechanical
183
+ conversion writes literals, aliases are for authored files.
184
+
185
+ ---
186
+
187
+ ## `typography.*` — families and the ramp
188
+
189
+ The first-class machine form of the type scale, in two subgroups. It reaches CSS variables only
190
+ through the primitives it aliases; emitters and exemplars read the ramp as data (size, line-height,
191
+ weight, tracking per step).
192
+
193
+ **`typography.family.*`** — the heading/body pairing plus mono, all `$type: "fontFamily"`:
194
+
195
+ | Token | Value |
196
+ | --- | --- |
197
+ | `typography.family.heading` | `"{primitive.font-sans}"` — or its own stack when the look pairs a distinct heading family. |
198
+ | `typography.family.body` | `"{primitive.font-sans}"` |
199
+ | `typography.family.mono` | `"{primitive.font-mono}"` |
200
+
201
+ **`typography.ramp.*`** — six fixed step names, each `$type: "typography"` carrying all five
202
+ sub-values:
203
+
204
+ | Step | Role |
205
+ | --- | --- |
206
+ | `h1` | page title |
207
+ | `h2` | section head |
208
+ | `h3` | card / group head |
209
+ | `body` | UI + prose |
210
+ | `small` | labels, meta, dense table |
211
+ | `caption` | uppercase eyebrow (text case is a usage rule; the composite carries no case slot) |
212
+
213
+ | Sub-value | Shape |
214
+ | --- | --- |
215
+ | `fontFamily` | alias to a `typography.family.*` token |
216
+ | `fontSize` | `dimension` (px) |
217
+ | `lineHeight` | number (unitless multiplier) |
218
+ | `fontWeight` | alias to `primitive.font-weight-strong` / `primitive.font-weight-normal`, or a number |
219
+ | `letterSpacing` | number (em multiplier) or alias to `primitive.heading-tracking` — the documented deviation |
220
+
221
+ ---
222
+
223
+ ## The preserved-css pattern
224
+
225
+ Every formatting-sensitive value carries **two forms that must agree**: the typed `$value` (the
226
+ queryable semantic) and `$extensions["com.nurix.design"].css` — the exact source CSS string.
227
+ Emitters prefer the preserved string, so output is byte-stable across convert/emit round trips.
228
+
229
+ - **Mandatory `.css`:** every `color` token; `heading-tracking` (sources vary — `0`, `0em`,
230
+ `-0.015em`); `ease-default`; any `fontFamily` token carrying its own stack.
231
+ - **Omitted where serialization is deterministic:** `dimension` and `duration` serialize as
232
+ `<value><unit>`; `number` and `fontWeight` as the plain number; `cubicBezier` (absent `.css`) as
233
+ `cubic-bezier(x1, y1, x2, y2)`; `fontFamily` (absent `.css`) as the families joined with `", "`,
234
+ multi-word names double-quoted.
235
+ - **On a composite token**, `.css` is an object keyed by sub-value name, present for
236
+ formatting-sensitive inline sub-values (e.g. `{ "letterSpacing": "0.02em" }`); an aliased sub-value
237
+ takes its `.css` from the alias target.
238
+ - **Parse-back verification is a converter requirement:** whatever writes a token must verify that
239
+ parsing `.css` reproduces `$value` exactly, and that re-serializing `$value` reproduces the byte
240
+ form — oklch components are the literal source numbers; srgb components round-trip through the
241
+ `hex` field. The gate re-verifies.
242
+
243
+ ## Hints and the coverage tri-state
244
+
245
+ DTCG has no hint concept; this is the convention. Where a value needs judgment, the token carries a
246
+ **valid provisional `$value`** plus `$extensions["com.nurix.design"].hint` — the intent in plain
247
+ words. Every gated token is in exactly one state:
248
+
249
+ | State | Marker | `--check` | `--emit` |
250
+ | --- | --- | --- | --- |
251
+ | **assigned** | real value, no `hint` key | passes | emits |
252
+ | **hinted** | `hint` key present | passes | **refuses**, naming every hinted path |
253
+ | **missing** | token absent | fails, naming the key | — |
254
+
255
+ Resolving a hint deletes the `hint` key and records the rationale in the token's `$description`, so
256
+ the resolved artifact is self-explaining and re-derivable. Judgment is recorded, never silent.
257
+
258
+ ```json
259
+ {
260
+ "$type": "number",
261
+ "$value": 1,
262
+ "$extensions": { "com.nurix.design": { "hint": "nudge borders up a step so the dense table grid reads as a grid" } }
263
+ }
264
+ ```
265
+
266
+ resolves to:
267
+
268
+ ```json
269
+ {
270
+ "$type": "number",
271
+ "$value": 1.1,
272
+ "$description": "derived: dense-grid brief, one step up (was hint)"
273
+ }
274
+ ```
275
+
276
+ ## Per-value provenance
277
+
278
+ A value's provenance rationale — why it diverges from a brand default, what judgment resolved its
279
+ hint — lives in the token's `$description`. Mechanical conversion moves source comments here.
280
+
281
+ ---
282
+
283
+ ## The dark set — `design.tokens.dark.json`
284
+
285
+ Ships **only when the look has dark values**; light is never omitted — the base set is the light
286
+ rendering. When it ships:
287
+
288
+ - It carries exactly the `color` group, all 34 roles, same shape rules (typed `$value` + `.css`) —
289
+ and nothing else: no primitives, no typography, no payload (the base file is the payload's single
290
+ carrier).
291
+ - Emission targets `[data-theme="dark"]`, remapping all 34; when the file is absent, no dark block is
292
+ emitted and the project is light-only.
293
+
294
+ ```json
295
+ {
296
+ "color": {
297
+ "background": { "$type": "color", "$value": { "colorSpace": "oklch", "components": [0.2077, 0.0398, 265.75] }, "$extensions": { "com.nurix.design": { "css": "oklch(0.2077 0.0398 265.75)" } } },
298
+ "foreground": { "$type": "color", "$value": { "colorSpace": "oklch", "components": [0.9842, 0.0034, 247.86] }, "$extensions": { "com.nurix.design": { "css": "oklch(0.9842 0.0034 247.86)" } } }
299
+ }
300
+ }
301
+ ```
302
+
303
+ (Fragment — a real dark file carries all 34.)
304
+
305
+ ---
306
+
307
+ ## The resolver — `design.resolver.json`
308
+
309
+ The DTCG resolver document has no stable snapshot, so this shape is **ours-until-standardized** — the
310
+ exact minimal shape the scripts implement, confined to this file so a future spec shift lands in one
311
+ place.
312
+
313
+ | Key | Shape |
314
+ | --- | --- |
315
+ | `schema` | Literal `design-resolver/v1`. |
316
+ | `sets` | Array of `{ "name": string, "values": [file, …] }` — the base token files, in load order. |
317
+ | `modifiers` | Array of `{ "name": string, "default": string, "contexts": { <context>: [file, …] } }`. Exactly one modifier today: `theme`. |
318
+
319
+ **Resolution order (deterministic):** concatenate the set files in array order; select one context
320
+ per modifier (the `default` when unstated); overlay the context's files in order — a later file
321
+ overrides an earlier one per token path, and an overlay may only override paths that exist in the
322
+ base, never introduce new ones. Aliases resolve after overlay. **Light-first:** `theme.default` is
323
+ always `light`, and the `light` context is always the empty overlay `[]` — the base set is the light
324
+ rendering. A light-only look carries only the `light` context; a look with dark adds
325
+ `"dark": ["design.tokens.dark.json"]`:
326
+
327
+ ```json
328
+ {
329
+ "schema": "design-resolver/v1",
330
+ "sets": [{ "name": "base", "values": ["design.tokens.json"] }],
331
+ "modifiers": [
332
+ { "name": "theme", "default": "light", "contexts": { "light": [], "dark": ["design.tokens.dark.json"] } }
333
+ ]
334
+ }
335
+ ```
336
+
337
+ ---
338
+
339
+ ## Emission mapping
340
+
341
+ The slug is the payload's `product`, slugified. Emission order is this document's enumeration order
342
+ (mirrored by the consumer's arrays); JSON key order carries no meaning.
343
+
344
+ | Source | Emitted target |
345
+ | --- | --- |
346
+ | `primitive.<name>` (24 static) | `[data-style="<slug>"] { --<name>: … }` — 1:1 by leaf name |
347
+ | `primitive.density-gap` / `density-inset` | governed refs (`var(--density-base-gap/inset)`); the tier writes the base |
348
+ | `color.<name>` (34) | `:root, :root[data-theme="light"] { --<name>: … }` |
349
+ | dark set `color.<name>` | `[data-theme="dark"] { --<name>: … }` — only when the dark file ships |
350
+ | `verbosity` / `feedback` / `density-tier` | `<html data-verbosity / data-feedback / data-density>` |
351
+ | `product` | `<html data-style="<slug>">` |
352
+ | `product-traits` | read by the front gate; never emitted |
353
+ | `typography.family.*` / `typography.ramp.*` | data for emitters and exemplars; reaches CSS only through the primitives it aliases |
354
+ | — (derived at emit) | `--ease-enter`, `--ease-exit`, `--stagger-delay` from `ease-default` + `duration-unit` |
355
+
356
+ ---
357
+
358
+ ## Validation — what `--check` enforces
359
+
360
+ The coverage gate. It exits non-zero and **names every offending path** so the fix is mechanical; an
361
+ artifact that passes is guaranteed derivable.
362
+
363
+ 1. **Files** — `design.tokens.json` and `design.resolver.json` present and parse as JSON; every file
364
+ the resolver references exists beside it; `design.tokens.dark.json` exists exactly when the
365
+ resolver's `dark` context names it.
366
+ 2. **Payload** — the base file's root `$extensions["com.nurix.design"]` present with: `schema` literal
367
+ `design-tokens/v1`; `dtcg` literal `2025.10`; `product` non-empty; `provenance` legal; `sourced` an
368
+ ISO date; `verbosity` / `feedback` / `density-tier` legal enum values (never hinted);
369
+ `product-traits` a non-empty array; `lever-manifest` carrying all six keys.
370
+ 3. **Primitive coverage** — all 26 `primitive.*` tokens present with the exact `$type` this schema
371
+ assigns, each assigned or hinted; fails naming every absent, empty, or mistyped key.
372
+ 4. **Color coverage** — all 34 `color.*` tokens present, `$type: "color"`, `colorSpace` one of
373
+ `oklch` | `srgb`, `.css` present, each assigned or hinted; fails naming every missing token.
374
+ 5. **Typography coverage** — `typography.family.heading|body|mono` present (`fontFamily`);
375
+ `typography.ramp.h1|h2|h3|body|small|caption` present (`typography`), each composite carrying all
376
+ five sub-values.
377
+ 6. **Alias integrity** — every `{path}` reference resolves within the artifact to a token of the
378
+ required type; no cycles.
379
+ 7. **Manifest scales** — `spacing-scale`, `radius-scale`, `motion.durations` non-empty and ascending;
380
+ `motion.easings` non-empty; `shadow-levels` non-empty, drawn from the legal vocabulary, strictly
381
+ increasing in intensity; `icons.family` non-empty; `accent-count` ≥ 1.
382
+ 8. **Manifest consistency** — the look's own base values sit on its own allowlist: `radius` ∈
383
+ `radius-scale`; `duration-fast` / `duration-normal` / `duration-slow` ∈ `motion.durations`;
384
+ `ease-default`'s serialization ∈ `motion.easings`.
385
+ 9. **Parse-back** — for every token carrying `.css`, parsing the string reproduces `$value` and
386
+ re-serializing `$value` reproduces the byte form.
387
+ 10. **Dark completeness** — the dark file, when present, carries exactly the `color` group with all
388
+ 34 roles under the same shape rules, and nothing else.
389
+ 11. **Spec conformance** — only the eight `$type` values this schema uses appear; no invented
390
+ `$type`; unknown `$extensions` namespaces are preserved, never authored.
391
+ 12. **Emission precondition** — `--emit` runs only over a passing artifact and refuses while any
392
+ token carries a `hint`, naming every hinted path.
393
+
394
+ ---
395
+
396
+ ## Worked example — the Nurix default (abbreviated)
397
+
398
+ `data/design-tokens/nurix/design.tokens.json`, abbreviated to a representative subset of each token
399
+ family — the real file carries all 26 primitives, all 34 color roles, and the full six-step ramp.
400
+ Nurix ships no dark set, so `design.tokens.dark.json` is absent and the resolver carries only the
401
+ `light` context.
402
+
403
+ ```json
404
+ {
405
+ "$description": "Nurix default — the look a zero-input project wears. Abbreviated here; the shipped file is complete.",
406
+ "$extensions": {
407
+ "com.nurix.design": {
408
+ "schema": "design-tokens/v1",
409
+ "dtcg": "2025.10",
410
+ "product": "Nurix",
411
+ "provenance": "default",
412
+ "sourced": "2026-07-04",
413
+ "product-traits": ["operator-console", "crm", "queue", "dashboard", "admin"],
414
+ "verbosity": "default",
415
+ "feedback": "subtle",
416
+ "density-tier": "standard",
417
+ "lever-manifest": {
418
+ "spacing-scale": [2, 4, 8, 12, 16, 24, 32, 48, 64],
419
+ "radius-scale": [0, 4, 6, 12, 9999],
420
+ "shadow-levels": ["none", "sm", "md"],
421
+ "motion": { "durations": [100, 150, 250], "easings": ["cubic-bezier(0.4,0,0.2,1)"] },
422
+ "icons": { "family": "lucide" },
423
+ "accent-count": 1
424
+ }
425
+ }
426
+ },
427
+ "primitive": {
428
+ "radius": {
429
+ "$type": "dimension",
430
+ "$value": { "value": 6, "unit": "px" },
431
+ "$description": "brand default 12px is marketing-surface soft; operator default tightens for a denser, engineered read"
432
+ },
433
+ "shadow-intensity": {
434
+ "$type": "number",
435
+ "$value": 0.4,
436
+ "$description": "brand is predominantly flat; shadow only lifts true overlays"
437
+ },
438
+ "border-weight": { "$type": "dimension", "$value": { "value": 1, "unit": "px" } },
439
+ "density-gap": { "$type": "number", "$value": 1 },
440
+ "font-sans": {
441
+ "$type": "fontFamily",
442
+ "$value": ["Inter", "system-ui", "sans-serif"],
443
+ "$description": "brand's body font; the single sans slot serves dense body/table chrome",
444
+ "$extensions": { "com.nurix.design": { "css": "Inter, system-ui, sans-serif" } }
445
+ },
446
+ "font-mono": {
447
+ "$type": "fontFamily",
448
+ "$value": ["Geist Mono", "ui-monospace", "SFMono-Regular", "monospace"],
449
+ "$description": "Geist monospace sibling — IDs, codes, log lines",
450
+ "$extensions": { "com.nurix.design": { "css": "Geist Mono, ui-monospace, SFMono-Regular, monospace" } }
451
+ },
452
+ "font-weight-normal": {
453
+ "$type": "fontWeight",
454
+ "$value": 400,
455
+ "$description": "brand base 500 is display-tuned; dense operator body reads cleaner at 400"
456
+ },
457
+ "font-weight-strong": { "$type": "fontWeight", "$value": 600 },
458
+ "heading-tracking": {
459
+ "$type": "number",
460
+ "$value": -0.01,
461
+ "$description": "em multiplier; brand display tracks 0 — at operator heading sizes Inter reads tighter",
462
+ "$extensions": { "com.nurix.design": { "css": "-0.01em" } }
463
+ },
464
+ "duration-unit": { "$type": "duration", "$value": { "value": 50, "unit": "ms" } },
465
+ "ease-default": {
466
+ "$type": "cubicBezier",
467
+ "$value": [0.4, 0, 0.2, 1],
468
+ "$extensions": { "com.nurix.design": { "css": "cubic-bezier(0.4,0,0.2,1)" } }
469
+ },
470
+ "icon-stroke": {
471
+ "$type": "number",
472
+ "$value": 1.75,
473
+ "$description": "one step under lucide's 2 for a refined operator stroke"
474
+ },
475
+ "sidebar-width-expanded": { "$type": "dimension", "$value": { "value": 248, "unit": "px" } },
476
+ "table-row-height": {
477
+ "$type": "dimension",
478
+ "$value": { "value": 40, "unit": "px" },
479
+ "$description": "comfortable at standard density; dense archetypes step down via the surface catalog"
480
+ }
481
+ },
482
+ "color": {
483
+ "background": {
484
+ "$type": "color",
485
+ "$value": { "colorSpace": "oklch", "components": [1, 0, 0] },
486
+ "$extensions": { "com.nurix.design": { "css": "oklch(1 0 0)" } }
487
+ },
488
+ "foreground": {
489
+ "$type": "color",
490
+ "$value": { "colorSpace": "oklch", "components": [0.2077, 0.0398, 265.75] },
491
+ "$extensions": { "com.nurix.design": { "css": "oklch(0.2077 0.0398 265.75)" } }
492
+ },
493
+ "border": {
494
+ "$type": "color",
495
+ "$value": { "colorSpace": "oklch", "components": [0.9288, 0.0126, 255.51] },
496
+ "$description": "brand #E2E8F0 — every separator, grid line, and field edge",
497
+ "$extensions": { "com.nurix.design": { "css": "oklch(0.9288 0.0126 255.51)" } }
498
+ },
499
+ "primary": {
500
+ "$type": "color",
501
+ "$value": { "colorSpace": "oklch", "components": [0.5211, 0.2145, 263.89] },
502
+ "$description": "brand #245AE2 — the one accent",
503
+ "$extensions": { "com.nurix.design": { "css": "oklch(0.5211 0.2145 263.89)" } }
504
+ },
505
+ "primary-foreground": {
506
+ "$type": "color",
507
+ "$value": { "colorSpace": "oklch", "components": [1, 0, 0] },
508
+ "$extensions": { "com.nurix.design": { "css": "oklch(1 0 0)" } }
509
+ },
510
+ "warning": {
511
+ "$type": "color",
512
+ "$value": { "colorSpace": "oklch", "components": [0.6658, 0.1574, 58.32] },
513
+ "$extensions": { "com.nurix.design": { "css": "oklch(0.6658 0.1574 58.32)" } }
514
+ },
515
+ "chart-2": {
516
+ "$type": "color",
517
+ "$value": { "colorSpace": "oklch", "components": [0.6089, 0.1109, 221.72] },
518
+ "$extensions": { "com.nurix.design": { "css": "oklch(0.6089 0.1109 221.72)" } }
519
+ },
520
+ "sidebar": {
521
+ "$type": "color",
522
+ "$value": { "colorSpace": "oklch", "components": [0.9842, 0.0034, 247.86] },
523
+ "$extensions": { "com.nurix.design": { "css": "oklch(0.9842 0.0034 247.86)" } }
524
+ }
525
+ },
526
+ "typography": {
527
+ "family": {
528
+ "heading": { "$type": "fontFamily", "$value": "{primitive.font-sans}" },
529
+ "body": { "$type": "fontFamily", "$value": "{primitive.font-sans}" },
530
+ "mono": { "$type": "fontFamily", "$value": "{primitive.font-mono}" }
531
+ },
532
+ "ramp": {
533
+ "h1": {
534
+ "$type": "typography",
535
+ "$value": {
536
+ "fontFamily": "{typography.family.heading}",
537
+ "fontSize": { "value": 24, "unit": "px" },
538
+ "lineHeight": 1.25,
539
+ "fontWeight": "{primitive.font-weight-strong}",
540
+ "letterSpacing": "{primitive.heading-tracking}"
541
+ }
542
+ },
543
+ "body": {
544
+ "$type": "typography",
545
+ "$value": {
546
+ "fontFamily": "{typography.family.body}",
547
+ "fontSize": { "value": 14, "unit": "px" },
548
+ "lineHeight": 1.45,
549
+ "fontWeight": "{primitive.font-weight-normal}",
550
+ "letterSpacing": 0
551
+ }
552
+ },
553
+ "caption": {
554
+ "$type": "typography",
555
+ "$value": {
556
+ "fontFamily": "{typography.family.body}",
557
+ "fontSize": { "value": 12, "unit": "px" },
558
+ "lineHeight": 1.2,
559
+ "fontWeight": "{primitive.font-weight-strong}",
560
+ "letterSpacing": 0.02
561
+ },
562
+ "$description": "uppercase eyebrow — text case is a usage rule; the composite carries no case slot",
563
+ "$extensions": { "com.nurix.design": { "css": { "letterSpacing": "0.02em" } } }
564
+ }
565
+ }
566
+ }
567
+ }
568
+ ```
569
+
570
+ `data/design-tokens/nurix/design.resolver.json`:
571
+
572
+ ```json
573
+ {
574
+ "schema": "design-resolver/v1",
575
+ "sets": [{ "name": "base", "values": ["design.tokens.json"] }],
576
+ "modifiers": [
577
+ { "name": "theme", "default": "light", "contexts": { "light": [] } }
578
+ ]
579
+ }
580
+ ```
@@ -0,0 +1,20 @@
1
+ {
2
+ "schema": "design-resolver/v1",
3
+ "sets": [
4
+ {
5
+ "name": "base",
6
+ "values": [
7
+ "design.tokens.json"
8
+ ]
9
+ }
10
+ ],
11
+ "modifiers": [
12
+ {
13
+ "name": "theme",
14
+ "default": "light",
15
+ "contexts": {
16
+ "light": []
17
+ }
18
+ }
19
+ ]
20
+ }