voidmachine 0.0.0 → 4.0.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 (341) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +123 -4
  3. package/bin/void-harness.mjs +12 -0
  4. package/bin/void-machine.mjs +12 -0
  5. package/core-assets/.claude-plugin/plugin.json +253 -0
  6. package/core-assets/.gitkeep +0 -0
  7. package/core-assets/PHILOSOPHY.md +218 -0
  8. package/core-assets/PROJECT-DOCTRINE.template.md +14 -0
  9. package/core-assets/adapters/security/manifest.yaml +96 -0
  10. package/core-assets/agents/.gitkeep +0 -0
  11. package/core-assets/agents/accessibility-specialist.md +59 -0
  12. package/core-assets/agents/api-integration-engineer.md +59 -0
  13. package/core-assets/agents/code-explorer.md +94 -0
  14. package/core-assets/agents/code-explorer.source +7 -0
  15. package/core-assets/agents/data-migration-engineer.md +59 -0
  16. package/core-assets/agents/devex-docs-engineer.md +57 -0
  17. package/core-assets/agents/doctrine-critic.md +91 -0
  18. package/core-assets/agents/doctrine-critic.source +11 -0
  19. package/core-assets/agents/domain-architect.md +56 -0
  20. package/core-assets/agents/experience-designer.md +59 -0
  21. package/core-assets/agents/frontend-engineer.md +60 -0
  22. package/core-assets/agents/independent-code-reviewer.md +61 -0
  23. package/core-assets/agents/migration-planner.md +97 -0
  24. package/core-assets/agents/migration-planner.source +7 -0
  25. package/core-assets/agents/observability-sre-engineer.md +59 -0
  26. package/core-assets/agents/pdf-specialist.md +58 -0
  27. package/core-assets/agents/performance-engineer.md +58 -0
  28. package/core-assets/agents/product-challenger.md +55 -0
  29. package/core-assets/agents/security-engineer.md +66 -0
  30. package/core-assets/agents/silent-failure-hunter.md +94 -0
  31. package/core-assets/agents/silent-failure-hunter.source +8 -0
  32. package/core-assets/agents/solution-architect.md +57 -0
  33. package/core-assets/agents/test-qa-engineer.md +60 -0
  34. package/core-assets/agents/type-design-analyzer.md +93 -0
  35. package/core-assets/agents/type-design-analyzer.source +8 -0
  36. package/core-assets/agents/visual-craft-director.md +62 -0
  37. package/core-assets/codex/hooks.json +157 -0
  38. package/core-assets/contract-history/visual-craft-director/v2.yaml +43 -0
  39. package/core-assets/data/catalog.v3.json +10479 -0
  40. package/core-assets/data/certification.json +1800 -0
  41. package/core-assets/data/identity.json +8 -0
  42. package/core-assets/data/model.json +4226 -0
  43. package/core-assets/enforce/ci-enforce.sh +183 -0
  44. package/core-assets/hooks/_checks.sh +145 -0
  45. package/core-assets/hooks/_hooklib.sh +163 -0
  46. package/core-assets/hooks/_syntax-worker.cjs +503 -0
  47. package/core-assets/hooks/_void-hook.mjs +5459 -0
  48. package/core-assets/hooks/activation-meter.sh +13 -0
  49. package/core-assets/hooks/anti-ai-slop-grep.sh +38 -0
  50. package/core-assets/hooks/auto-format.sh +9 -0
  51. package/core-assets/hooks/axe-precommit.sh +35 -0
  52. package/core-assets/hooks/block-dangerous-bash.sh +10 -0
  53. package/core-assets/hooks/block-protected-push.sh +81 -0
  54. package/core-assets/hooks/boundary-direction-check.sh +10 -0
  55. package/core-assets/hooks/control-character-grep.sh +10 -0
  56. package/core-assets/hooks/fowler-refactors.txt +71 -0
  57. package/core-assets/hooks/large-cl-grep.sh +9 -0
  58. package/core-assets/hooks/llm-cost-precommit.sh +55 -0
  59. package/core-assets/hooks/migration-lint.sh +58 -0
  60. package/core-assets/hooks/migration-pr-template.sh +55 -0
  61. package/core-assets/hooks/no-ai-design-slop.sh +10 -0
  62. package/core-assets/hooks/no-any-grep.sh +10 -0
  63. package/core-assets/hooks/no-as-cast-grep.sh +10 -0
  64. package/core-assets/hooks/no-console-log-grep.sh +10 -0
  65. package/core-assets/hooks/no-null-grep.sh +10 -0
  66. package/core-assets/hooks/no-only-no-skip.sh +10 -0
  67. package/core-assets/hooks/outcome-meter.sh +13 -0
  68. package/core-assets/hooks/pre-PR-review-evidence.sh +47 -0
  69. package/core-assets/hooks/protect-sensitive-files.sh +10 -0
  70. package/core-assets/hooks/refactor-named-grep.sh +49 -0
  71. package/core-assets/hooks/secret-in-content.sh +10 -0
  72. package/core-assets/hooks/sessionstart-context.sh +9 -0
  73. package/core-assets/hooks/stop-typecheck.sh +9 -0
  74. package/core-assets/hooks/tdd-guard.md +90 -0
  75. package/core-assets/hooks/tdd-guard.sh +10 -0
  76. package/core-assets/hooks/test-name-lint.sh +10 -0
  77. package/core-assets/hooks/tidying-commit-prefix.sh +37 -0
  78. package/core-assets/hooks/trim-large-output.sh +9 -0
  79. package/core-assets/hooks/tsc-noemit-precommit.sh +22 -0
  80. package/core-assets/hooks/ubiquitous-language-lint.sh +58 -0
  81. package/core-assets/hooks/viewport-screenshot-gate.sh +48 -0
  82. package/core-assets/modules/.gitkeep +0 -0
  83. package/core-assets/packs/pack-mobile/skills/void-eas-build-profile/.source +7 -0
  84. package/core-assets/packs/pack-mobile/skills/void-eas-build-profile/SKILL.md +164 -0
  85. package/core-assets/packs/pack-mobile/skills/void-eas-build-profile/harness.yaml +14 -0
  86. package/core-assets/packs/pack-mobile/skills/void-expo-config-plugins/.source +7 -0
  87. package/core-assets/packs/pack-mobile/skills/void-expo-config-plugins/SKILL.md +178 -0
  88. package/core-assets/packs/pack-mobile/skills/void-expo-config-plugins/harness.yaml +14 -0
  89. package/core-assets/packs/pack-mobile/skills/void-expo-router-pattern/.source +8 -0
  90. package/core-assets/packs/pack-mobile/skills/void-expo-router-pattern/SKILL.md +209 -0
  91. package/core-assets/packs/pack-mobile/skills/void-expo-router-pattern/harness.yaml +14 -0
  92. package/core-assets/packs/pack-mobile/skills/void-ota-update-strategy/.source +7 -0
  93. package/core-assets/packs/pack-mobile/skills/void-ota-update-strategy/SKILL.md +194 -0
  94. package/core-assets/packs/pack-mobile/skills/void-ota-update-strategy/harness.yaml +14 -0
  95. package/core-assets/packs/pack-monorepo/skills/void-dependency-direction/.source +5 -0
  96. package/core-assets/packs/pack-monorepo/skills/void-dependency-direction/SKILL.md +160 -0
  97. package/core-assets/packs/pack-monorepo/skills/void-dependency-direction/harness.yaml +14 -0
  98. package/core-assets/packs/pack-monorepo/skills/void-package-extraction/.source +5 -0
  99. package/core-assets/packs/pack-monorepo/skills/void-package-extraction/SKILL.md +70 -0
  100. package/core-assets/packs/pack-monorepo/skills/void-package-extraction/harness.yaml +14 -0
  101. package/core-assets/packs/pack-monorepo/skills/void-service-package/.source +5 -0
  102. package/core-assets/packs/pack-monorepo/skills/void-service-package/SKILL.md +122 -0
  103. package/core-assets/packs/pack-monorepo/skills/void-service-package/harness.yaml +14 -0
  104. package/core-assets/packs/pack-monorepo/skills/void-turbo-pipeline-tuning/.source +7 -0
  105. package/core-assets/packs/pack-monorepo/skills/void-turbo-pipeline-tuning/SKILL.md +116 -0
  106. package/core-assets/packs/pack-monorepo/skills/void-turbo-pipeline-tuning/harness.yaml +14 -0
  107. package/core-assets/packs/pack-nextjs/skills/void-cache-component-pattern/.source +5 -0
  108. package/core-assets/packs/pack-nextjs/skills/void-cache-component-pattern/SKILL.md +162 -0
  109. package/core-assets/packs/pack-nextjs/skills/void-cache-component-pattern/harness.yaml +14 -0
  110. package/core-assets/packs/pack-nextjs/skills/void-instrumentation-setup/.source +5 -0
  111. package/core-assets/packs/pack-nextjs/skills/void-instrumentation-setup/SKILL.md +161 -0
  112. package/core-assets/packs/pack-nextjs/skills/void-instrumentation-setup/harness.yaml +14 -0
  113. package/core-assets/packs/pack-nextjs/skills/void-loading-error-boundaries/.source +5 -0
  114. package/core-assets/packs/pack-nextjs/skills/void-loading-error-boundaries/SKILL.md +176 -0
  115. package/core-assets/packs/pack-nextjs/skills/void-loading-error-boundaries/harness.yaml +14 -0
  116. package/core-assets/packs/pack-nextjs/skills/void-parallel-routes-slots/.source +5 -0
  117. package/core-assets/packs/pack-nextjs/skills/void-parallel-routes-slots/SKILL.md +129 -0
  118. package/core-assets/packs/pack-nextjs/skills/void-parallel-routes-slots/harness.yaml +14 -0
  119. package/core-assets/packs/pack-nextjs/skills/void-route-group-decision/.source +5 -0
  120. package/core-assets/packs/pack-nextjs/skills/void-route-group-decision/SKILL.md +107 -0
  121. package/core-assets/packs/pack-nextjs/skills/void-route-group-decision/harness.yaml +14 -0
  122. package/core-assets/packs/pack-pwa/skills/void-install-prompt-ux/.source +5 -0
  123. package/core-assets/packs/pack-pwa/skills/void-install-prompt-ux/SKILL.md +153 -0
  124. package/core-assets/packs/pack-pwa/skills/void-install-prompt-ux/harness.yaml +14 -0
  125. package/core-assets/packs/pack-pwa/skills/void-manifest-checklist/.source +5 -0
  126. package/core-assets/packs/pack-pwa/skills/void-manifest-checklist/SKILL.md +204 -0
  127. package/core-assets/packs/pack-pwa/skills/void-manifest-checklist/harness.yaml +14 -0
  128. package/core-assets/packs/pack-pwa/skills/void-offline-first-mutation/.source +8 -0
  129. package/core-assets/packs/pack-pwa/skills/void-offline-first-mutation/SKILL.md +266 -0
  130. package/core-assets/packs/pack-pwa/skills/void-offline-first-mutation/harness.yaml +14 -0
  131. package/core-assets/packs/pack-pwa/skills/void-service-worker-strategy/.source +5 -0
  132. package/core-assets/packs/pack-pwa/skills/void-service-worker-strategy/SKILL.md +178 -0
  133. package/core-assets/packs/pack-pwa/skills/void-service-worker-strategy/harness.yaml +14 -0
  134. package/core-assets/packs/pack-react/skills/void-accessibility-check/.source +8 -0
  135. package/core-assets/packs/pack-react/skills/void-accessibility-check/SKILL.md +136 -0
  136. package/core-assets/packs/pack-react/skills/void-accessibility-check/harness.yaml +14 -0
  137. package/core-assets/packs/pack-react/skills/void-client-vs-server-component/.source +5 -0
  138. package/core-assets/packs/pack-react/skills/void-client-vs-server-component/SKILL.md +116 -0
  139. package/core-assets/packs/pack-react/skills/void-client-vs-server-component/harness.yaml +14 -0
  140. package/core-assets/packs/pack-react/skills/void-form-pattern/.source +7 -0
  141. package/core-assets/packs/pack-react/skills/void-form-pattern/SKILL.md +157 -0
  142. package/core-assets/packs/pack-react/skills/void-form-pattern/harness.yaml +14 -0
  143. package/core-assets/packs/pack-react/skills/void-state-architecture/.source +5 -0
  144. package/core-assets/packs/pack-react/skills/void-state-architecture/SKILL.md +160 -0
  145. package/core-assets/packs/pack-react/skills/void-state-architecture/harness.yaml +14 -0
  146. package/core-assets/packs/pack-server/skills/void-background-job-pattern/.source +6 -0
  147. package/core-assets/packs/pack-server/skills/void-background-job-pattern/SKILL.md +214 -0
  148. package/core-assets/packs/pack-server/skills/void-background-job-pattern/harness.yaml +14 -0
  149. package/core-assets/packs/pack-server/skills/void-drizzle-migration-safe/.source +6 -0
  150. package/core-assets/packs/pack-server/skills/void-drizzle-migration-safe/SKILL.md +168 -0
  151. package/core-assets/packs/pack-server/skills/void-drizzle-migration-safe/harness.yaml +14 -0
  152. package/core-assets/packs/pack-server/skills/void-env-validation/.source +6 -0
  153. package/core-assets/packs/pack-server/skills/void-env-validation/SKILL.md +131 -0
  154. package/core-assets/packs/pack-server/skills/void-env-validation/harness.yaml +14 -0
  155. package/core-assets/packs/pack-server/skills/void-rate-limit-strategy/.source +6 -0
  156. package/core-assets/packs/pack-server/skills/void-rate-limit-strategy/SKILL.md +149 -0
  157. package/core-assets/packs/pack-server/skills/void-rate-limit-strategy/harness.yaml +14 -0
  158. package/core-assets/packs/pack-server/skills/void-server-action/.source +7 -0
  159. package/core-assets/packs/pack-server/skills/void-server-action/SKILL.md +181 -0
  160. package/core-assets/packs/pack-server/skills/void-server-action/harness.yaml +14 -0
  161. package/core-assets/packs/pack-server/skills/void-testing-server-modules/.source +7 -0
  162. package/core-assets/packs/pack-server/skills/void-testing-server-modules/SKILL.md +73 -0
  163. package/core-assets/packs/pack-server/skills/void-testing-server-modules/harness.yaml +14 -0
  164. package/core-assets/packs/pack-server/skills/void-webhook-handler-pattern/.source +7 -0
  165. package/core-assets/packs/pack-server/skills/void-webhook-handler-pattern/SKILL.md +205 -0
  166. package/core-assets/packs/pack-server/skills/void-webhook-handler-pattern/harness.yaml +14 -0
  167. package/core-assets/policies/core.yaml +95 -0
  168. package/core-assets/policies/ui.yaml +23 -0
  169. package/core-assets/profiles/base.yaml +29 -0
  170. package/core-assets/profiles/expo-config.yaml +36 -0
  171. package/core-assets/profiles/expo.yaml +35 -0
  172. package/core-assets/profiles/monorepo.yaml +33 -0
  173. package/core-assets/profiles/nextjs-config.yaml +31 -0
  174. package/core-assets/profiles/nextjs.yaml +31 -0
  175. package/core-assets/profiles/node-server.yaml +31 -0
  176. package/core-assets/profiles/pwa.yaml +33 -0
  177. package/core-assets/profiles/react.yaml +39 -0
  178. package/core-assets/profiles/sql.yaml +39 -0
  179. package/core-assets/profiles/typescript.yaml +39 -0
  180. package/core-assets/skills/.gitkeep +0 -0
  181. package/core-assets/skills/void-accessibility/.source +15 -0
  182. package/core-assets/skills/void-accessibility/SKILL.md +275 -0
  183. package/core-assets/skills/void-accessibility/harness.yaml +17 -0
  184. package/core-assets/skills/void-api-and-interface-design/.source +13 -0
  185. package/core-assets/skills/void-api-and-interface-design/SKILL.md +231 -0
  186. package/core-assets/skills/void-api-and-interface-design/harness.yaml +16 -0
  187. package/core-assets/skills/void-async-safety/.source +13 -0
  188. package/core-assets/skills/void-async-safety/SKILL.md +287 -0
  189. package/core-assets/skills/void-async-safety/harness.yaml +16 -0
  190. package/core-assets/skills/void-audit/.source +15 -0
  191. package/core-assets/skills/void-audit/SKILL.md +83 -0
  192. package/core-assets/skills/void-audit/harness.yaml +14 -0
  193. package/core-assets/skills/void-autopilot/.source +21 -0
  194. package/core-assets/skills/void-autopilot/SKILL.md +358 -0
  195. package/core-assets/skills/void-autopilot/harness.yaml +14 -0
  196. package/core-assets/skills/void-brainstorm/.source +14 -0
  197. package/core-assets/skills/void-brainstorm/SKILL.md +271 -0
  198. package/core-assets/skills/void-brainstorm/harness.yaml +14 -0
  199. package/core-assets/skills/void-checkpoint/.source +39 -0
  200. package/core-assets/skills/void-checkpoint/SKILL.md +227 -0
  201. package/core-assets/skills/void-checkpoint/harness.yaml +14 -0
  202. package/core-assets/skills/void-claude-md/.source +15 -0
  203. package/core-assets/skills/void-claude-md/SKILL.md +180 -0
  204. package/core-assets/skills/void-claude-md/harness.yaml +14 -0
  205. package/core-assets/skills/void-code-review/.source +14 -0
  206. package/core-assets/skills/void-code-review/SKILL.md +232 -0
  207. package/core-assets/skills/void-code-review/harness.yaml +15 -0
  208. package/core-assets/skills/void-commit-discipline/.source +9 -0
  209. package/core-assets/skills/void-commit-discipline/SKILL.md +211 -0
  210. package/core-assets/skills/void-commit-discipline/harness.yaml +15 -0
  211. package/core-assets/skills/void-context/.source +15 -0
  212. package/core-assets/skills/void-context/SKILL.md +167 -0
  213. package/core-assets/skills/void-context/harness.yaml +14 -0
  214. package/core-assets/skills/void-debug/.source +11 -0
  215. package/core-assets/skills/void-debug/SKILL.md +211 -0
  216. package/core-assets/skills/void-debug/harness.yaml +14 -0
  217. package/core-assets/skills/void-decide/.source +9 -0
  218. package/core-assets/skills/void-decide/SKILL.md +147 -0
  219. package/core-assets/skills/void-decide/harness.yaml +14 -0
  220. package/core-assets/skills/void-devex-audit/.source +8 -0
  221. package/core-assets/skills/void-devex-audit/SKILL.md +113 -0
  222. package/core-assets/skills/void-devex-audit/harness.yaml +15 -0
  223. package/core-assets/skills/void-doctor/.source +15 -0
  224. package/core-assets/skills/void-doctor/SKILL.md +83 -0
  225. package/core-assets/skills/void-doctor/harness.yaml +14 -0
  226. package/core-assets/skills/void-domain-driven-design/.source +13 -0
  227. package/core-assets/skills/void-domain-driven-design/SKILL.md +292 -0
  228. package/core-assets/skills/void-domain-driven-design/harness.yaml +15 -0
  229. package/core-assets/skills/void-frontend-design/.source +19 -0
  230. package/core-assets/skills/void-frontend-design/SKILL.md +274 -0
  231. package/core-assets/skills/void-frontend-design/harness.yaml +17 -0
  232. package/core-assets/skills/void-functional/.source +14 -0
  233. package/core-assets/skills/void-functional/SKILL.md +312 -0
  234. package/core-assets/skills/void-functional/harness.yaml +15 -0
  235. package/core-assets/skills/void-graph/.source +15 -0
  236. package/core-assets/skills/void-graph/SKILL.md +80 -0
  237. package/core-assets/skills/void-graph/harness.yaml +14 -0
  238. package/core-assets/skills/void-hexagonal-architecture/.source +12 -0
  239. package/core-assets/skills/void-hexagonal-architecture/SKILL.md +276 -0
  240. package/core-assets/skills/void-hexagonal-architecture/harness.yaml +15 -0
  241. package/core-assets/skills/void-implement/.source +39 -0
  242. package/core-assets/skills/void-implement/SKILL.md +183 -0
  243. package/core-assets/skills/void-implement/harness.yaml +14 -0
  244. package/core-assets/skills/void-learn/.source +13 -0
  245. package/core-assets/skills/void-learn/SKILL.md +226 -0
  246. package/core-assets/skills/void-learn/harness.yaml +14 -0
  247. package/core-assets/skills/void-llm-cost-discipline/.source +13 -0
  248. package/core-assets/skills/void-llm-cost-discipline/SKILL.md +299 -0
  249. package/core-assets/skills/void-llm-cost-discipline/harness.yaml +15 -0
  250. package/core-assets/skills/void-make-pdf/.source +9 -0
  251. package/core-assets/skills/void-make-pdf/SKILL.md +52 -0
  252. package/core-assets/skills/void-make-pdf/harness.yaml +15 -0
  253. package/core-assets/skills/void-merge/.source +8 -0
  254. package/core-assets/skills/void-merge/SKILL.md +111 -0
  255. package/core-assets/skills/void-merge/harness.yaml +14 -0
  256. package/core-assets/skills/void-migrations/.source +13 -0
  257. package/core-assets/skills/void-migrations/SKILL.md +264 -0
  258. package/core-assets/skills/void-migrations/harness.yaml +17 -0
  259. package/core-assets/skills/void-observability/.source +12 -0
  260. package/core-assets/skills/void-observability/SKILL.md +245 -0
  261. package/core-assets/skills/void-observability/harness.yaml +15 -0
  262. package/core-assets/skills/void-plan/.source +15 -0
  263. package/core-assets/skills/void-plan/SKILL.md +239 -0
  264. package/core-assets/skills/void-plan/harness.yaml +14 -0
  265. package/core-assets/skills/void-plan-review/.source +12 -0
  266. package/core-assets/skills/void-plan-review/SKILL.md +128 -0
  267. package/core-assets/skills/void-plan-review/harness.yaml +15 -0
  268. package/core-assets/skills/void-qa/.source +15 -0
  269. package/core-assets/skills/void-qa/SKILL.md +103 -0
  270. package/core-assets/skills/void-qa/harness.yaml +15 -0
  271. package/core-assets/skills/void-refactor/.source +9 -0
  272. package/core-assets/skills/void-refactor/SKILL.md +220 -0
  273. package/core-assets/skills/void-refactor/harness.yaml +15 -0
  274. package/core-assets/skills/void-retrospective/.source +9 -0
  275. package/core-assets/skills/void-retrospective/SKILL.md +71 -0
  276. package/core-assets/skills/void-retrospective/harness.yaml +15 -0
  277. package/core-assets/skills/void-security-audit/.source +12 -0
  278. package/core-assets/skills/void-security-audit/SKILL.md +138 -0
  279. package/core-assets/skills/void-security-audit/harness.yaml +15 -0
  280. package/core-assets/skills/void-security-guidance/.source +12 -0
  281. package/core-assets/skills/void-security-guidance/SKILL.md +255 -0
  282. package/core-assets/skills/void-security-guidance/harness.yaml +15 -0
  283. package/core-assets/skills/void-source-driven-development/.source +12 -0
  284. package/core-assets/skills/void-source-driven-development/SKILL.md +158 -0
  285. package/core-assets/skills/void-source-driven-development/harness.yaml +15 -0
  286. package/core-assets/skills/void-tdd/.source +15 -0
  287. package/core-assets/skills/void-tdd/SKILL.md +394 -0
  288. package/core-assets/skills/void-tdd/harness.yaml +15 -0
  289. package/core-assets/skills/void-testing/.source +19 -0
  290. package/core-assets/skills/void-testing/SKILL.md +301 -0
  291. package/core-assets/skills/void-testing/harness.yaml +17 -0
  292. package/core-assets/skills/void-ticket/.source +18 -0
  293. package/core-assets/skills/void-ticket/SKILL.md +239 -0
  294. package/core-assets/skills/void-ticket/harness.yaml +14 -0
  295. package/core-assets/skills/void-typescript-strict/.source +10 -0
  296. package/core-assets/skills/void-typescript-strict/SKILL.md +294 -0
  297. package/core-assets/skills/void-typescript-strict/harness.yaml +17 -0
  298. package/core-assets/skills/void-ui-review/.source +12 -0
  299. package/core-assets/skills/void-ui-review/SKILL.md +97 -0
  300. package/core-assets/skills/void-ui-review/harness.yaml +15 -0
  301. package/core-assets/skills/void-verify/.source +12 -0
  302. package/core-assets/skills/void-verify/SKILL.md +184 -0
  303. package/core-assets/skills/void-verify/harness.yaml +15 -0
  304. package/core-assets/specialists/accessibility-specialist.source +11 -0
  305. package/core-assets/specialists/accessibility-specialist.yaml +30 -0
  306. package/core-assets/specialists/api-integration-engineer.source +11 -0
  307. package/core-assets/specialists/api-integration-engineer.yaml +30 -0
  308. package/core-assets/specialists/data-migration-engineer.source +11 -0
  309. package/core-assets/specialists/data-migration-engineer.yaml +30 -0
  310. package/core-assets/specialists/devex-docs-engineer.source +11 -0
  311. package/core-assets/specialists/devex-docs-engineer.yaml +29 -0
  312. package/core-assets/specialists/domain-architect.source +11 -0
  313. package/core-assets/specialists/domain-architect.yaml +28 -0
  314. package/core-assets/specialists/experience-designer.source +15 -0
  315. package/core-assets/specialists/experience-designer.yaml +38 -0
  316. package/core-assets/specialists/frontend-engineer.source +11 -0
  317. package/core-assets/specialists/frontend-engineer.yaml +32 -0
  318. package/core-assets/specialists/independent-code-reviewer.source +10 -0
  319. package/core-assets/specialists/independent-code-reviewer.yaml +37 -0
  320. package/core-assets/specialists/migrations.json +15 -0
  321. package/core-assets/specialists/observability-sre-engineer.source +11 -0
  322. package/core-assets/specialists/observability-sre-engineer.yaml +30 -0
  323. package/core-assets/specialists/pdf-specialist.source +11 -0
  324. package/core-assets/specialists/pdf-specialist.yaml +29 -0
  325. package/core-assets/specialists/performance-engineer.source +11 -0
  326. package/core-assets/specialists/performance-engineer.yaml +29 -0
  327. package/core-assets/specialists/product-challenger.source +10 -0
  328. package/core-assets/specialists/product-challenger.yaml +27 -0
  329. package/core-assets/specialists/security-engineer.source +13 -0
  330. package/core-assets/specialists/security-engineer.yaml +41 -0
  331. package/core-assets/specialists/solution-architect.source +13 -0
  332. package/core-assets/specialists/solution-architect.yaml +32 -0
  333. package/core-assets/specialists/test-qa-engineer.source +14 -0
  334. package/core-assets/specialists/test-qa-engineer.yaml +35 -0
  335. package/core-assets/specialists/visual-craft-director.source +17 -0
  336. package/core-assets/specialists/visual-craft-director.yaml +60 -0
  337. package/core-assets/templates/github/dependency-audit.mjs +54 -0
  338. package/core-assets/templates/github/void-dependency-audit.yml +35 -0
  339. package/core-assets/templates/github/void-security.yml +85 -0
  340. package/dist/main.js +57001 -0
  341. package/package.json +66 -4
@@ -0,0 +1,292 @@
1
+ ---
2
+ name: void-domain-driven-design
3
+ description: Bounded contexts, aggregates as consistency boundaries, value objects as branded types, always-valid domain, ubiquitous language. No CQRS, event sourcing, or generic Repository<T>. Use on the domain.
4
+ ---
5
+
6
+ # domain-driven-design — voidcorp craftsman edition
7
+
8
+ The data model does not drive the design. The domain does. Inside a bounded context, every word has one meaning. Aggregates enforce invariants. Value objects model semantic primitives. The code uses the words the team uses.
9
+
10
+ **Attribution**: see `.source` in this directory. Foundation: Evans 2003, Vernon 2013, Wlaschin "Domain Modeling Made Functional," Stemmler TS adaptation, Khorikov.
11
+
12
+ ---
13
+
14
+ ## Strategic DDD — the vocabulary
15
+
16
+ | Term | Definition |
17
+ |---|---|
18
+ | **Bounded Context** | A boundary inside which a model is valid and a language is consistent. One context = one module/package. |
19
+ | **Ubiquitous Language** | The shared vocabulary inside a context. Code uses the same words stakeholders use. Diverging is a bug. |
20
+ | **Context Map** | The graph of bounded contexts and their relationships (partnership, conformist, anti-corruption layer, ...). Documented in `docs/CONTEXT-MAP.md` for non-trivial systems. |
21
+ | **Aggregate** | A cluster of objects treated as a single unit for consistency. The aggregate enforces its own invariants. |
22
+ | **Aggregate Root** | The single entity through which the aggregate is accessed. The only thing repositories return. |
23
+ | **Entity** | An object identified by its identity (UserId), not its attributes. Two entities with the same fields but different IDs are distinct. |
24
+ | **Value Object** | An object identified by its attributes. Two value objects with the same fields are equal. Immutable. |
25
+ | **Domain Service** | A stateless operation that does not fit any single aggregate (e.g., `TransferFunds` across two accounts). |
26
+ | **Domain Event** | A typed record describing something that happened in the domain (`OrderConfirmed`, `UserSuspended`). Emitted by aggregates. |
27
+
28
+ ---
29
+
30
+ ## Bounded Context = unit of language
31
+
32
+ Inside one context, `Order` means ONE thing. Across contexts, `Order` can mean different things — and that is fine, as long as the boundary translates.
33
+
34
+ Example:
35
+
36
+ - In the **Checkout** context, `Order` = a cart in the process of being paid.
37
+ - In the **Fulfilment** context, `Order` = a list of items to ship.
38
+ - In the **Accounting** context, `Order` = a revenue line on the ledger.
39
+
40
+ These are three distinct types in three distinct packages. They share an ID (`OrderId`) and are translated at the boundary by an **anti-corruption layer** (an adapter that maps from one context's model to another's).
41
+
42
+ The companion advisory hook `ubiquitous-language-lint` flags terms appearing in code but not in `docs/DOMAIN.md` (the per-context glossary).
43
+
44
+ ### Banned
45
+
46
+ - Cross-context type imports (`import { Order } from '@/contexts/fulfilment'` from inside the checkout context). The boundary MUST go through an adapter.
47
+ - A single shared `Order` type across all contexts. That is "Big Ball of Mud" by another name.
48
+
49
+ ---
50
+
51
+ ## Aggregates — consistency boundaries
52
+
53
+ An aggregate is a transactional unit. Loading and saving happens at the aggregate root. Invariants inside the aggregate are ALWAYS true (by construction and by aggregate methods).
54
+
55
+ ### Small aggregates (Vernon's rule)
56
+
57
+ Prefer many small aggregates referencing each other by ID over fewer large aggregates that load deep graphs. Default to small.
58
+
59
+ <Good>
60
+ ```typescript
61
+ // small aggregates
62
+ class Order { id: OrderId; customerId: CustomerId; lineItems: LineItem[]; ... }
63
+ class Customer { id: CustomerId; email: Email; ... }
64
+ // Order does NOT contain the full Customer object — just the ID
65
+ ```
66
+ </Good>
67
+
68
+ <Bad>
69
+ ```typescript
70
+ // large aggregate loading everything
71
+ class Order {
72
+ customer: Customer; // loads the customer's address book, preferences, ...
73
+ shipments: Shipment[]; // loads every shipment with carrier details
74
+ invoices: Invoice[]; // loads every invoice with line items
75
+ ...
76
+ }
77
+ // loading one Order from DB now requires N joins or N+1 queries
78
+ ```
79
+ </Bad>
80
+
81
+ ### Always-valid domain model (Khorikov)
82
+
83
+ ```typescript
84
+ class Order {
85
+ private constructor(
86
+ readonly id: OrderId,
87
+ private status: OrderStatus,
88
+ private items: LineItem[],
89
+ ) {}
90
+
91
+ static create(input: { items: LineItem[]; customerId: CustomerId }): Result<Order, ValidationError> {
92
+ if (input.items.length === 0) return err({ kind: 'empty_order' });
93
+ return ok(new Order(newOrderId(), 'draft', input.items));
94
+ }
95
+
96
+ confirm(): Result<void, OrderError> {
97
+ if (this.status !== 'draft') return err({ kind: 'not_draft', currentStatus: this.status });
98
+ this.status = 'confirmed';
99
+ return ok(undefined);
100
+ }
101
+ }
102
+ ```
103
+
104
+ - No public constructor (smart constructor `create`).
105
+ - No setter `setStatus(s: string)` that accepts any value.
106
+ - Every mutation goes through a method that preserves invariants and returns `Result`.
107
+
108
+ ### State machines as discriminated unions (alternative shape)
109
+
110
+ For workflows with distinct shapes per state, prefer a discriminated union:
111
+
112
+ ```typescript
113
+ type Booking =
114
+ | { kind: 'draft'; id: BookingId; partyOf: number }
115
+ | { kind: 'submitted'; id: BookingId; partyOf: number; submittedAt: IsoDate }
116
+ | { kind: 'confirmed'; id: BookingId; partyOf: number; confirmedAt: IsoDate; tableNumber: number }
117
+ | { kind: 'cancelled'; id: BookingId; reason: string; cancelledAt: IsoDate };
118
+ ```
119
+
120
+ Transitions are functions: `submit(b: Booking & { kind: 'draft' }): Booking & { kind: 'submitted' }`. The compiler refuses to call `submit` on a `confirmed` booking. Composes with `void-typescript-strict` exhaustive switches and `void-functional` ADTs.
121
+
122
+ ### Heuristic: class vs discriminated union
123
+
124
+ - Class for aggregates with many invariants and behavior methods (Order, Account)
125
+ - Discriminated union for stateful workflows with distinct data per state (BookingFlow, SignupFlow)
126
+ - Document the choice per aggregate in `docs/DOMAIN.md`
127
+
128
+ ---
129
+
130
+ ## Value objects — branded types with smart constructors
131
+
132
+ A value object is identified by attributes. Two `Email`s with the same string are equal. Immutable.
133
+
134
+ ```typescript
135
+ type Email = string & { readonly __brand: 'Email' };
136
+
137
+ export function createEmail(raw: string): Result<Email, ValidationError> {
138
+ if (!EMAIL_REGEX.test(raw)) return err({ kind: 'invalid_email', raw });
139
+ return ok(raw as Email);
140
+ }
141
+ ```
142
+
143
+ Apply to every domain primitive: `UserId`, `OrgId`, `OrderId`, `Email`, `PhoneNumber`, `IsoDate`, `Money` (`{ amount: number; currency: CurrencyCode }`, with `CurrencyCode` itself branded).
144
+
145
+ Composes with `void-typescript-strict` (branded type mechanics) and `void-functional` (smart constructors return `Result`).
146
+
147
+ ### Banned: raw primitives for things with semantics
148
+
149
+ ```typescript
150
+ function transferFunds(from: string, to: string, amount: number) { ... }
151
+ // BAD — nothing prevents transferFunds('alice@example.com', '42', -100)
152
+ ```
153
+
154
+ ```typescript
155
+ function transferFunds(from: AccountId, to: AccountId, amount: Money): Result<void, TransferError> { ... }
156
+ // GOOD — the compiler refuses raw strings; Money carries currency
157
+ ```
158
+
159
+ ---
160
+
161
+ ## Repositories — ports per aggregate, no generic `Repository<T>`
162
+
163
+ A repository in DDD = a port in `void-hexagonal-architecture`. Named by what it does, methods specific to the aggregate's invariants.
164
+
165
+ <Good>
166
+ ```typescript
167
+ interface OrdersPort {
168
+ findById(id: OrderId): Promise<Result<Order, NotFoundError>>;
169
+ findByCustomer(customerId: CustomerId): Promise<Result<Order[], never>>;
170
+ save(order: Order): Promise<Result<void, ConflictError>>;
171
+ // NO `delete()` if orders are never deleted (audit constraint)
172
+ }
173
+ ```
174
+ </Good>
175
+
176
+ <Bad>
177
+ ```typescript
178
+ interface Repository<T> {
179
+ findById(id: string): Promise<T | null>;
180
+ findAll(): Promise<T[]>;
181
+ save(t: T): Promise<void>;
182
+ delete(id: string): Promise<void>;
183
+ }
184
+ // BAD — exposes operations the aggregate may not allow (`delete`); lies about success (`null` vs Result)
185
+ ```
186
+ </Bad>
187
+
188
+ ---
189
+
190
+ ## Domain Services — multi-aggregate operations only
191
+
192
+ A domain service is justified when the operation involves multiple aggregates.
193
+
194
+ ```typescript
195
+ // domain service: TransferFunds across two Account aggregates
196
+ export async function transferFunds(
197
+ deps: { accounts: AccountsPort; events: EventBusPort },
198
+ input: { from: AccountId; to: AccountId; amount: Money },
199
+ ): Promise<Result<TransferResult, TransferError>> {
200
+ // ... orchestration across two aggregates ...
201
+ }
202
+ ```
203
+
204
+ Single-aggregate operations are aggregate methods — `account.deposit(amount)`, not `AccountService.deposit(account, amount)`. Without this discipline, domain services become anemic dumping grounds.
205
+
206
+ ---
207
+
208
+ ## Domain Events — typed records emitted by aggregates
209
+
210
+ ```typescript
211
+ type OrderEvent =
212
+ | { kind: 'OrderConfirmed'; orderId: OrderId; at: IsoDate }
213
+ | { kind: 'OrderCancelled'; orderId: OrderId; reason: string; at: IsoDate };
214
+ ```
215
+
216
+ Aggregates collect events; use-cases dispatch them via an injected `EventBusPort` at the end of the transaction. Composes with `void-hexagonal-architecture` (event bus as a port).
217
+
218
+ ---
219
+
220
+ ## Banned by default
221
+
222
+ ### CQRS, event sourcing, mediator, generic `Repository<T>`
223
+
224
+ All rejected per `.void/installed/PHILOSOPHY.md` Wing Chun. Re-introducing any of them is an ADR, written through the `void-decide` skill.
225
+
226
+ ### Anemic models (data + setters, logic elsewhere)
227
+
228
+ Public setters on aggregate fields are forbidden. Mutations go through methods that preserve invariants.
229
+
230
+ ### Service classes named `*Manager`, `*Helper`, `*Util`
231
+
232
+ Evans' anemic anti-patterns. A `UserManager` that holds `signUp`, `login`, `delete` is a domain service collection — split into named operations.
233
+
234
+ ### Cross-context type imports
235
+
236
+ The anti-corruption layer (adapter) is mandatory. No direct import.
237
+
238
+ ---
239
+
240
+ ## Companion hooks
241
+
242
+ - **`ubiquitous-language-lint`** (advisory) — flags code terms not in `docs/DOMAIN.md` (per-context glossary), and glossary terms not present in code. Informational; HITL decides. See `../../hooks/`.
243
+
244
+ (The structural rules surface through `void-code-review` flags and `void-hexagonal-architecture`'s `boundary-direction-check` hook.)
245
+
246
+ ---
247
+
248
+ ## Composition with other skills
249
+
250
+ - **`void-hexagonal-architecture`**: this skill decides what an aggregate IS; hex decides where it sits physically. Repositories are ports.
251
+ - **`void-functional`**: aggregates as discriminated unions for stateful flows. Value objects as branded types + smart constructors returning `Result`. Always-valid domain.
252
+ - **`void-typescript-strict`**: value objects ARE branded types. State machines ARE discriminated unions.
253
+ - **`void-tdd`**: aggregate invariants are test-driven — each invariant is a test.
254
+ - **`void-code-review`**: structure dimension flags anemic models, generic repositories, raw primitives, public setters.
255
+ - **`void-refactor`**: refactors that touch aggregate boundaries (Extract Aggregate, Move Field across contexts) compose for the boundary decision.
256
+ - **`void-security-guidance`**: anti-corruption layer at the context boundary is also a trust boundary.
257
+
258
+ ---
259
+
260
+ ## Anti-rules
261
+
262
+ - MUST NOT prescribe CQRS / event sourcing / mediator / generic repositories by default.
263
+ - MUST NOT decide tactical implementation shape (FP / OOP) inside an aggregate — `void-functional`'s call.
264
+ - MUST NOT decide whether a sub-domain is Core / Supporting / Generic — product call, lives upstream.
265
+ - MUST NOT decide framework / DB / queue — pack concerns.
266
+ - MUST NOT silently allow cross-context type imports.
267
+ - MUST NOT decide aggregate identity strategy (UUID / nanoid / DB-assigned) — pack provides default, consumer overrides.
268
+
269
+ ---
270
+
271
+ ## When you are stuck
272
+
273
+ | Problem | Solution |
274
+ |---|---|
275
+ | Where does this aggregate sit? | Identify the bounded context. One context per package. Cross-context = anti-corruption adapter. |
276
+ | Class or discriminated union? | Class for many-invariants + methods. Union for distinct-shape-per-state workflows. |
277
+ | Should this be an aggregate or a value object? | Identity matters → entity / aggregate root. Pure attributes → value object. |
278
+ | Aggregate growing too large | Apply small-aggregate rule. Reference other aggregates by ID, not by inclusion. |
279
+ | Stuck naming | Use the stakeholders' word. If terminology is unclear, the domain is unclear — fix that first. |
280
+ | Need to share data across contexts | Anti-corruption adapter at the destination context. No direct type import. |
281
+
282
+ ---
283
+
284
+ ## Final rule
285
+
286
+ ```
287
+ Bounded contexts are independent. Aggregates are always valid.
288
+ Value objects use branded types. The code speaks the team's language.
289
+ Otherwise → it is not voidcorp DDD.
290
+ ```
291
+
292
+ The domain is the heart. The technology is plumbing. Get the domain right and the rest follows.
@@ -0,0 +1,15 @@
1
+ # Harness metadata for this skill. Not part of the Agent Skills
2
+ # specification, and never copied into a consumer project: the SKILL.md
3
+ # beside it stays portable and validates against the official six fields.
4
+ # Read by this repository's graph, and by the installer for `runtimes`.
5
+ kind: standard
6
+ activation: always
7
+ owner: folpe
8
+ runtimes: [claude, codex]
9
+ enforcement:
10
+ floor: ci
11
+ inline:
12
+ claude: pretooluse
13
+ codex: pretooluse
14
+ hermes: ci-only
15
+ eval_targets: [claude/anthropic/opus]
@@ -0,0 +1,19 @@
1
+ Sources for `void-frontend-design` skill (see `docs/plans/skill-audits/void-frontend-design.md` for full audit):
2
+
3
+ - Vercel `frontend-design` plugin (installed globally as `frontend-design:frontend-design`) — https://github.com/vercel-labs/agent-skills — vendored with void-machine additions (mobile-first dual-quality, matrix integration, shadcn composition)
4
+ - citypaul/.dotfiles UI patterns — density, hierarchy notes
5
+ - Refactoring UI (Adam Wathan + Steve Schoger) — book — foundation, density, hierarchy, motion principles
6
+ - Apple HIG visual design chapter — https://developer.apple.com/design/human-interface-guidelines — mobile layout heuristics
7
+ - Folpe DESIGN.md convention (per-project) — brand identity belongs in consumer DESIGN.md
8
+ - pbakaus/impeccable-design — referenced by citypaul
9
+ - impeccable (standalone skill) — VENDORED (DEV-389, build-time half): the current-AI-tell absolute bans (side-stripe, gradient-text, glassmorphism, hero-metric, eyebrow/numbered-markers, cream/sand body, text-overflow), the color-strategy commitment axis, and the type/layout/motion/interaction specifics. Its audit/critique/refine half went to the new `void-ui-review`; its browser runtime is deferred to Vague 4.
10
+ - gstack /design-review — the Krug reading model (scan/satisfice/muddle) vendored here (DEV-389); its designer's-eye QA went to ui-review.
11
+
12
+ Strategy: vendor-plugin + distill. Fork Vercel plugin for Void Machine invariant (mobile-first dual-quality) + matrix integration; DEV-389 enriched it with impeccable's build-time craft so the harness is self-contained on UI (no external impeccable dependency).
13
+
14
+ Companion hooks: viewport-screenshot-gate (shared with accessibility), anti-ai-slop-grep.
15
+
16
+ Stack-specific @repo/ui + design system tokens + Tailwind config in pack-nextjs-pwa.
17
+
18
+ DEV-444 adaptation: consumes a fresh-context Experience Designer brief before build; independent
19
+ post-build judgment remains downstream in ui-review and Visual Craft Director.
@@ -0,0 +1,274 @@
1
+ ---
2
+ name: void-frontend-design
3
+ description: Anti-AI-slop UI. Density first, 3-size hierarchy, motion <250ms, components via @repo/ui (Radix/shadcn), mobile-first dual-quality. Brand from DESIGN.md. Use when building or modifying UI.
4
+ ---
5
+
6
+ # frontend-design — voidcorp craftsman edition
7
+
8
+ AI-generated UI tends to "vibe coded": blue-to-violet gradients, generic hero copy, low information density, mid hierarchy, motion as decoration. The result reads as generated. This skill encodes the discipline that breaks that pattern.
9
+
10
+ Brand identity (palette, typography stack, motion language) lives in the consumer project's `DESIGN.md`. This skill imposes the DISCIPLINE that applies across all brand identities.
11
+
12
+ **Attribution**: see `.source`. Foundation: Vercel `void-frontend-design` plugin + Refactoring UI + Apple HIG + citypaul UI notes; the current-AI-tell bans, color-strategy axis, and type/layout/motion specifics are vendored from `impeccable` (DEV-389); the Krug reading model from gstack `/design-review`.
13
+
14
+ ---
15
+
16
+ ## Mobile-first dual-quality
17
+
18
+ Every UI is designed mobile-first AND must reach first-class quality on both viewports simultaneously. (Folpe rule, `.void/installed/PHILOSOPHY.md`.)
19
+
20
+ - **Layout starts at 360–390px** (iPhone 12 mini → 15 Pro range), progressively enhanced wider.
21
+ - **Never the reverse.** No "desktop-first then squeeze for mobile."
22
+ - **Both viewports screenshot-reviewed before merge** — `viewport-screenshot-gate` hook (shared with `void-accessibility`).
23
+ - **No mobile-only / desktop-only features** without an explicit decision recorded through the `void-decide` skill.
24
+ - **Performance budget enforced for both**: LCP < 2.5s on slow 4G mobile AND on desktop fiber (measure with the project's perf tooling — Lighthouse CI, WebPageTest, bundlesize).
25
+
26
+ ---
27
+
28
+ ## Pre-build experience pass
29
+
30
+ Before implementation, invoke `core:experience-designer` in a fresh read-only context with the
31
+ ticket, product intent, `DESIGN.md`, and existing interface evidence. Its build brief names the IA,
32
+ primary action, keyboard path, responsive intent, and applicable UI states. Missing or stale
33
+ pre-build attestation blocks implementation. This skill consumes that brief and owns the build; it
34
+ does not self-approve the post-build result.
35
+
36
+ ---
37
+
38
+ ## Anti-AI-slop — banned patterns
39
+
40
+ ### Banned copy
41
+
42
+ - "Build faster, ship smarter"
43
+ - "Ship 10× faster"
44
+ - "Unlock your potential"
45
+ - "Empower your team"
46
+ - "Transform your workflow"
47
+ - Generic CTA: "Get Started Free Forever"
48
+
49
+ These signal "vibe coded" and lose user trust before the content is read. The companion hook `anti-ai-slop-grep` warns on these patterns in staged copy. Override per-string with explicit code review approval — the discipline is heuristic, the writer is final.
50
+
51
+ ### Banned visual patterns by default
52
+
53
+ - Blue → violet / purple → pink gradient backgrounds as default decoration
54
+ - Abstract 3D / blobs / orbs as primary hero visual
55
+ - Lorem ipsum or placeholder text in shipped UI
56
+ - Random ad hoc font sizes outside the 3-size system
57
+ - Decorative animations longer than 250ms
58
+
59
+ These are defaults. Brand can override via `DESIGN.md` if the brand justifies a specific pattern (e.g., a brand that legitimately uses a specific gradient). Override is documented; default is rejection.
60
+
61
+ ### Absolute bans — the current AI tells (match-and-refuse; vendored from impeccable)
62
+
63
+ If you are about to write any of these, rewrite the element with different structure:
64
+
65
+ - **Side-stripe borders** — a colored `border-left`/`border-right` > 1px on cards/alerts/list-items. Use a full border, a background tint, a leading number/icon, or nothing.
66
+ - **Gradient text** — `background-clip: text` over a gradient. Use a single solid color; emphasize with weight or size.
67
+ - **Glassmorphism as default** — decorative blur/glass cards. Rare and purposeful, or nothing.
68
+ - **The hero-metric template** — an oversized figure over a tiny caption, flanked by supporting stats and a gradient flourish. The default SaaS landing scaffold; reach for a real layout instead.
69
+ - **Uppercase tracked eyebrows above every section** and **numbered section markers (01 / 02 / 03) as default scaffolding.** One deliberate kicker or a real ordered sequence is voice; one on *every* section is AI grammar — pick a different cadence.
70
+ - **The cream / sand / beige body background** — the warm-neutral band (OKLCH L 0.84-0.97, C < 0.06, hue 40-100) reading as paper/parchment is the saturated AI default of 2026, tell-tale even under names like `--cream`/`--sand`/`--linen`. Carry "warmth" through accent + type + imagery, not a warm-tinted near-white body.
71
+ - **Text that overflows its container** at any breakpoint — long heading words + large `clamp()` + narrow grids. The viewport is part of the design; test heading copy at every width.
72
+
73
+ ---
74
+
75
+ ## Color strategy — commit before picking colors (vendored from impeccable)
76
+
77
+ Pick a strategy on the commitment axis first; picking colors without one produces the timid default.
78
+
79
+ - **Restrained** — tinted neutrals + one accent ≤ 10%. Product default.
80
+ - **Committed** — one saturated color carries 30-60% of the surface. Identity-driven pages.
81
+ - **Full palette** — 3-4 named roles, each used deliberately. Campaigns, data viz.
82
+ - **Drenched** — the surface IS the color. Heroes, campaign pages.
83
+
84
+ Use OKLCH. Dark vs light is never a reflex ("tools look cool dark", "light to be safe") — write one sentence of physical scene (who uses this, where, under what light, in what mood); if it doesn't force the answer, add detail until it does. Tint neutrals 0.005-0.015 toward the brand hue, never toward warm/cool "because it feels that way."
85
+
86
+ ---
87
+
88
+ ## Information architecture before visual design
89
+
90
+ The discipline is structural FIRST:
91
+
92
+ 1. **What is the hierarchy?** What does the user need to read / do first, second, third?
93
+ 2. **What is the primary action?** Singular. The page exists to lead to this action.
94
+ 3. **What is supporting context?** Provided but recessed.
95
+ 4. **What is noise?** Cut.
96
+
97
+ THEN visual:
98
+
99
+ 5. Typography expresses the hierarchy
100
+ 6. Color guides attention to the primary action
101
+ 7. Motion communicates state change, not entertainment
102
+
103
+ AI-generated UI tends to skip the IA step and jump to visual. The result feels busy and unfocused.
104
+
105
+ ---
106
+
107
+ ## Density first
108
+
109
+ Information density > whitespace by default. Whitespace earns its place via hierarchy, not as default.
110
+
111
+ Generic AI output over-uses whitespace ("looks clean!") and under-uses density. Real users want to do work, not admire margins.
112
+
113
+ **How users actually read** (Krug, *Don't Make Me Think* — vendored via design-review): they *scan*, not read; they *satisfice* (pick the first reasonable option, so make the right choice the most visible one); they *muddle through*. Design rule: "omit needless words, then omit again." The **mindless-click test** — every decision point should be an obvious click, not a puzzle the user has to solve.
114
+
115
+ ### Density heuristics
116
+
117
+ - Lists with > 3 items: tabular, not card-grid-with-images.
118
+ - Forms: compact, with inline labels when label space matches input width.
119
+ - Dashboards: tabular metrics with sparklines. Cards only for genuinely independent objects.
120
+ - Hero sections: useful from the first scroll. No 100vh splash without immediate value.
121
+
122
+ ---
123
+
124
+ ## Type hierarchy: 3 sizes max + weight + color
125
+
126
+ The design system tokens (in `pack-nextjs`) expose exactly 3 type sizes:
127
+
128
+ | Token | Use |
129
+ |---|---|
130
+ | `text-display` | Page hero, section header (rare) |
131
+ | `text-heading` | Section title |
132
+ | `text-body` | Everything else |
133
+
134
+ Differentiation within `text-body` comes from weight (`font-medium`, `font-bold`) and color (`text-primary`, `text-muted`).
135
+
136
+ ### Specifics (vendored from impeccable)
137
+
138
+ - Cap body line length at **65-75ch**.
139
+ - Pair fonts on a **contrast axis** (serif + sans, geometric + humanist) or one family in multiple weights — never two similar-but-not-identical sans.
140
+ - Display heading `clamp()` max **≤ 6rem** (above that the page is shouting), letter-spacing floor **≥ -0.04em** (tighter and letters touch).
141
+ - `text-wrap: balance` on h1-h3; `text-wrap: pretty` on long prose.
142
+
143
+ ### Banned
144
+
145
+ - Random custom font sizes (`text-[19px]`, `text-[27px]`, etc.) outside the token system
146
+ - Five+ levels of heading hierarchy
147
+ - Lowercase `text-xs` for body copy on mobile (under 14px is unreadable for many users)
148
+ - **`system-ui` / `-apple-system` as the primary display or body font** — the "I gave up on typography" tell. Choose a real typeface.
149
+
150
+ ---
151
+
152
+ ## Color guides attention
153
+
154
+ The primary action is the most saturated, most contrasted, most singular color on the screen. Everything else recesses.
155
+
156
+ - ONE primary action color per view. Two competing primaries = no primary.
157
+ - Secondary actions: muted, lower contrast.
158
+ - Tertiary: ghost / link style.
159
+ - Destructive: red — but reserve for actually destructive (delete, unsubscribe). Not for "Cancel."
160
+
161
+ WCAG AA contrast minimum (composes with `void-accessibility` — 4.5:1 normal text, 3:1 large / UI components).
162
+
163
+ ---
164
+
165
+ ## Motion: purpose-driven, < 250ms, ease-out
166
+
167
+ ```css
168
+ /* allowed */
169
+ .dropdown-content { animation: slide-down 200ms ease-out; }
170
+
171
+ /* banned */
172
+ .hero-decoration { animation: float 8s ease-in-out infinite; }
173
+ ```
174
+
175
+ Motion communicates state change. Not entertainment. Reserve for:
176
+
177
+ - Opening / closing (modal, dropdown, drawer)
178
+ - Affordance feedback (button press)
179
+ - State transition (success, error)
180
+
181
+ Duration: < 250ms. Easing: `ease-out` for entry, `ease-in` for exit. The design system (`pack-nextjs`) provides default tokens.
182
+
183
+ `prefers-reduced-motion` respected — composes with `void-accessibility`. The design system handles by default.
184
+
185
+ ### Banned
186
+
187
+ - Looping decorative animations
188
+ - Bouncy easing on functional UI (`ease-in-out-back` etc.) — reserves for playful brands explicitly
189
+ - Animations longer than 250ms unless documented (page transitions, intentional reveals)
190
+
191
+ ---
192
+
193
+ ## Layout & interaction craft (vendored from impeccable)
194
+
195
+ - **Cards are the lazy answer** — use them only when they are truly the best affordance; nested cards are always wrong.
196
+ - **Flexbox for 1D, Grid for 2D.** Don't reach for Grid when `flex-wrap` fits. Responsive grid without breakpoints: `repeat(auto-fit, minmax(280px, 1fr))`.
197
+ - **Semantic z-index scale** (dropdown → sticky → modal-backdrop → modal → toast → tooltip). Never `999` / `9999`.
198
+ - **Vary spacing for rhythm** — uniform spacing reads as a wireframe.
199
+ - **Motion easing**: ease-out with exponential curves (quart / quint / expo); no bounce, no elastic on functional UI. Every animation needs a `prefers-reduced-motion` alternative (crossfade or instant).
200
+ - **Reveal animations must enhance an already-visible default** — never gate content visibility on a class-triggered transition; it pauses on hidden tabs / headless renderers and the section ships blank.
201
+ - **Dropdown clipping**: a `position: absolute` menu inside `overflow: hidden`/`auto` is clipped — use `<dialog>` / the popover API / `position: fixed` / a portal to escape the stacking context.
202
+
203
+ ---
204
+
205
+ ## Components from `@repo/ui`
206
+
207
+ Composed with `void-accessibility`. No hand-rolled UI primitives:
208
+
209
+ ```tsx
210
+ // banned
211
+ <div className="px-4 py-2 bg-blue-500 rounded" onClick={...}>Submit</div>
212
+
213
+ // preferred
214
+ import { Button } from '@repo/ui';
215
+ <Button variant="primary" onClick={...}>Submit</Button>
216
+ ```
217
+
218
+ `@repo/ui` is shadcn-style — Radix base + Tailwind tokens + design system extension. Provided by `pack-nextjs`.
219
+
220
+ ---
221
+
222
+ ## Composition with other skills
223
+
224
+ - **With `void-accessibility`**: a11y is a precondition. Shared mobile-first dual-quality invariant. Shared `viewport-screenshot-gate` hook.
225
+ - **With `void-typescript-strict`**: component props strongly typed; discriminated unions for variants; no `any` in UI.
226
+ - **With `void-code-review`**: dimensions `readability` and `correctness` include UI quality flags.
227
+ - **With `pack-nextjs`**: provides `@repo/ui` + design system tokens + Tailwind config + shadcn preset matching this discipline.
228
+ - **With `void-ui-review`**: the audit/critique ceiling to this build-time floor — it catches on an existing UI what this skill prevents while building. Downstream.
229
+ - **With `core:experience-designer`**: the read-only pre-build brief upstream; this skill implements it without absorbing product or audit ownership.
230
+ - **With `DESIGN.md`**: the brand contract (palette, type, motion, decisions) is UPSTREAM; this skill consumes it. The file is produced by `impeccable document`/`init` or authored by hand — the schema is the interface, not a gstack workflow.
231
+ - **With `forge`** (voidcorp plugin): market recon, 12-dimension critique, and multi-variant design prompts live there (the design-shotgun/consultation exploration), bridged by the `docs/specs/` `source: forge` artifact contract, not a code dependency.
232
+
233
+ ---
234
+
235
+ ## Companion hooks
236
+
237
+ - `viewport-screenshot-gate` (pre-PR on UI changes, shared with `void-accessibility`) — fails PRs lacking both mobile and desktop screenshots.
238
+ - `anti-ai-slop-grep` (pre-commit) — warns on banned copy patterns. Initial list of ~10; grows from `void-learn` harness-gap feedback.
239
+
240
+ See `../../hooks/`.
241
+
242
+ ---
243
+
244
+ ## Anti-rules
245
+
246
+ - MUST NOT decide brand identity (colors / typography / motion language) — `DESIGN.md` per project owns.
247
+ - MUST NOT do the audit/critique pass — that is `void-ui-review` (this skill is build-time; ui-review is audit-time).
248
+ - MUST NOT permit hand-rolled UI primitives.
249
+ - MUST NOT skip dual-viewport verification.
250
+ - MUST NOT silently allow banned copy / banned visual patterns.
251
+
252
+ ---
253
+
254
+ ## When you are stuck
255
+
256
+ | Problem | Solution |
257
+ |---|---|
258
+ | Layout looks generic | Density audit. Information architecture first. Cut what does not earn its place. |
259
+ | Hero feels weak | Singular primary action. Recess everything else. Cut decorative gradient if generic. |
260
+ | Too many font sizes | Reduce to the 3-token system. Vary by weight and color. |
261
+ | Motion feels excessive | Cut decorative animations. Keep only state-change communication. |
262
+ | Mobile screenshot fails | Layout was desktop-first. Restart at 360–390px. |
263
+ | Cannot reach AA contrast | Design system token failure. Adjust palette tokens, not per-component overrides. |
264
+
265
+ ---
266
+
267
+ ## Final rule
268
+
269
+ ```
270
+ Every UI → IA first, density first, 3-size hierarchy, motion <250ms, @repo/ui components, dual-viewport verified, brand-from-DESIGN.md.
271
+ Otherwise → it is not voidcorp frontend-design.
272
+ ```
273
+
274
+ AI generates infinite UI. The discipline is what makes ours stop looking generated.
@@ -0,0 +1,17 @@
1
+ # Harness metadata for this skill. Not part of the Agent Skills
2
+ # specification, and never copied into a consumer project: the SKILL.md
3
+ # beside it stays portable and validates against the official six fields.
4
+ # Read by this repository's graph, and by the installer for `runtimes`.
5
+ kind: action
6
+ activation: always
7
+ triggers:
8
+ extensions: ["tsx"]
9
+ owner: folpe
10
+ runtimes: [claude, codex]
11
+ enforcement:
12
+ floor: ci
13
+ inline:
14
+ claude: pretooluse
15
+ codex: pretooluse
16
+ hermes: ci-only
17
+ eval_targets: [claude/anthropic/opus]
@@ -0,0 +1,14 @@
1
+ Sources for `void-functional` skill (see `docs/plans/skill-audits/void-functional.md` for full audit):
2
+
3
+ - Scott Wlaschin "Domain Modeling Made Functional" — https://pragprog.com/titles/swdddf — DDD + FP synthesis, Result for railway-oriented programming
4
+ - Mark Seemann "Code That Fits in Your Head" — FP discipline, complexity budget, command-query separation
5
+ - Gary Bernhardt "Functional Core, Imperative Shell" — DCDC 2012 talk — mental model
6
+ - Vlad Khorikov "Enterprise Craftsmanship" — Result alternative to exceptions, immutability rationale
7
+ - citypaul/.dotfiles fp notes — pragmatic FP-in-TS without Effect-TS
8
+ - fp-ts — https://gcanti.github.io/fp-ts/ — referenced, NOT vendored as default
9
+ - Effect-TS — https://effect.website — referenced as future opt-in pack, NOT default
10
+ - Eric Normand "Grokking Simplicity" — calculations vs actions framing
11
+
12
+ Strategy: distill. Reject Effect-TS / fp-ts / point-free / monad transformers as defaults. Standardize Result<T, E> + Option<T> + pipe helpers in @voidcorp/core (≤ 50 LOC total).
13
+
14
+ Companion hook: no-null-grep (warn on null in domain code).