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,301 @@
1
+ ---
2
+ name: void-testing
3
+ description: How to write a good test. Behavior over implementation, real code over mocks, factories over beforeEach, pyramid respected, pristine output, no snapshot creep. Use when writing or modifying tests.
4
+ ---
5
+
6
+ # testing — voidcorp craftsman edition
7
+
8
+ `void-tdd` provides the cycle (when to write the test). This skill provides the technique (how to write a good one). Mocking is the last resort. Behavior, not implementation. Factories, not `beforeEach`. Pristine output is a passing condition.
9
+
10
+ **Attribution**: see `.source` in this directory.
11
+
12
+ ---
13
+
14
+ ## Core principles
15
+
16
+ ### 1. Test the behavior, not the implementation
17
+
18
+ Assertions describe what the user / consumer of the code observes. They do not describe which private method ran, which collaborator was invoked, which exact internal sequence happened.
19
+
20
+ <Good>
21
+ ```typescript
22
+ test('retries failed operations 3 times before giving up', async () => {
23
+ let attempts = 0;
24
+ const op = () => {
25
+ attempts++;
26
+ if (attempts < 3) throw new Error('transient');
27
+ return 'success';
28
+ };
29
+ expect(await retryOperation(op)).toBe('success');
30
+ expect(attempts).toBe(3); // observable: how many times the operation ran
31
+ });
32
+ ```
33
+ </Good>
34
+
35
+ <Bad>
36
+ ```typescript
37
+ test('retry', () => {
38
+ const spy = vi.fn().mockRejectedValueOnce(...).mockResolvedValueOnce(...);
39
+ retryOperation(spy);
40
+ expect(spy).toHaveBeenCalledTimes(3); // tests the spy, not the behavior
41
+ expect(retryOperation['_internalDelay']).toBeDefined(); // tests internals
42
+ });
43
+ ```
44
+ </Bad>
45
+
46
+ For UI: query by accessible role / label, not by class or `data-testid`. `data-testid` is the escape hatch when no semantic query works, not the default.
47
+
48
+ For interactive UI, pair the accessible query with the user input that proves the contract:
49
+ `userEvent.keyboard` for keyboard paths, pointer input only for pointer behavior, and visible output
50
+ for state transitions. Test loading, empty, error, success, and partial states only when applicable,
51
+ but make that applicability explicit. Component, hook, and store tests stay at their observable
52
+ boundaries; a broad E2E test does not substitute for the focused regression that identifies which
53
+ contract broke.
54
+
55
+ ### 2. Sociable tests over solitary tests
56
+
57
+ Let collaborators run inside the test by default. Only mock at infrastructure boundaries:
58
+
59
+ - HTTP → MSW (Mock Service Worker)
60
+ - DB → pglite (in-memory Postgres) or Neon dev branch
61
+ - Filesystem → `memfs` or a temp directory
62
+ - Time → `vi.useFakeTimers()`
63
+ - Randomness → seeded RNG
64
+
65
+ Mocking a collaborator that does pure computation is a code smell. If you find yourself mocking `formatCurrency()` to test `renderInvoice()`, the design is too coupled — or your test should run `formatCurrency` for real.
66
+
67
+ ### 3. Nullable infrastructure pattern (Shore)
68
+
69
+ For the infrastructure that DOES need a test double, the wrapper exposes a `createNull()` variant that returns deterministic / empty results. No mocking library invocation; the constructor handles it.
70
+
71
+ ```typescript
72
+ class StripeClient {
73
+ static create(apiKey: string): StripeClient { /* real */ }
74
+ static createNull(opts?: { charges?: ChargeFixture[] }): StripeClient { /* in-memory */ }
75
+ }
76
+
77
+ // in tests:
78
+ const stripe = StripeClient.createNull({ charges: [makeCharge({ amount_cents: 1000 })] });
79
+ ```
80
+
81
+ The nullable variant is production-typed. Tests do not reach into a mocking framework. The boundary is owned by the domain.
82
+
83
+ ### 4. Pristine output
84
+
85
+ After a test passes, the output is clean:
86
+
87
+ - No `console.log` from production code
88
+ - No warnings (React act warnings, deprecation warnings, etc.)
89
+ - No leaked unhandled rejections
90
+ - No leaked timers / open handles
91
+
92
+ Pristine output is a passing condition, not a nice-to-have. Vitest config: `onConsoleLog: 'fail'`.
93
+
94
+ ### 5. Release E2E proves the shipped artifact
95
+
96
+ Release proof exercises the immutable deployable artifact, not a development compiler. Keep build
97
+ readiness (the process started and became healthy) separate from application assertions, so a slow
98
+ compile cannot consume the assertion budget or hide a failed startup.
99
+
100
+ Fixtures use the lowest faithful boundary that preserves the behavior under test. Establishing an
101
+ authenticated precondition may use a server/API boundary; the authentication UI remains an E2E
102
+ subject when authentication itself is the behavior being proved.
103
+
104
+ External state is namespaced per run/worker and cleanup is idempotent and bounded, including after
105
+ interruption. Browser storage state is sensitive ephemeral output and belongs under the test output
106
+ directory, never in source control.
107
+
108
+ Test-only security overrides are typed, bounded, and paired with independent proof of production
109
+ defaults and denial behavior. A malformed or out-of-range override falls back to safe production
110
+ defaults. No retry-on-failure, quarantine, skip, or assertion-timeout inflation is a flake fix.
111
+
112
+ ---
113
+
114
+ ## Naming
115
+
116
+ Describe the behavior. Imperative. Specific.
117
+
118
+ <Good>
119
+ - `retries failed operations 3 times before giving up`
120
+ - `rejects payment when card balance is below total`
121
+ - `emits user-created event after first successful login`
122
+ </Good>
123
+
124
+ <Bad>
125
+ - `test retry` (vacuous)
126
+ - `should work` (says nothing)
127
+ - `retryOperation` (function name, not behavior)
128
+ - `it should retry` (the "should" is fluff)
129
+ </Bad>
130
+
131
+ The companion hook `test-name-lint` warns on weak patterns (`test`, `works`, `should` as the entire name).
132
+
133
+ ---
134
+
135
+ ## Fixtures and factories
136
+
137
+ ### Factories over `beforeEach`
138
+
139
+ `beforeEach` for environment setup (mount DOM, reset DB, install fake timers). NOT for test data.
140
+
141
+ <Good>
142
+ ```typescript
143
+ function makeUser(overrides: Partial<User> = {}): User {
144
+ return {
145
+ id: createUserId('usr_test_001'),
146
+ email: 'user@example.com',
147
+ createdAt: new Date('2026-01-01'),
148
+ ...overrides,
149
+ };
150
+ }
151
+
152
+ test('rejects suspended users', () => {
153
+ const user = makeUser({ suspended: true });
154
+ expect(authorize(user)).toEqual({ ok: false, error: 'suspended' });
155
+ });
156
+ ```
157
+ </Good>
158
+
159
+ <Bad>
160
+ ```typescript
161
+ let user: User;
162
+ beforeEach(() => {
163
+ user = { id: '...', email: '...', /* shared mutable state */ };
164
+ });
165
+ test('rejects suspended users', () => {
166
+ user.suspended = true; // mutates shared state, leaks between tests
167
+ expect(authorize(user)).toEqual({ ok: false, error: 'suspended' });
168
+ });
169
+ ```
170
+ </Bad>
171
+
172
+ ### Externalize > 5-line fixtures
173
+
174
+ Inline fixtures are fine when small (< 5 lines). Larger fixtures go to `tests/fixtures/<name>.ts`. Each fixture exposes a factory function with overrides.
175
+
176
+ Heavy data (multi-KB JSON, sample images): load from disk, never inline.
177
+
178
+ ---
179
+
180
+ ## Test pyramid
181
+
182
+ Heuristic ratios for a TS/web project:
183
+
184
+ - **~70% unit tests**: pure functions, business logic, schema validation. Run in < 100ms each.
185
+ - **~20% integration tests**: real infrastructure via pglite / MSW / temp filesystem. Run in < 1s each typically.
186
+ - **~10% E2E tests**: Playwright on critical user paths. Run in seconds.
187
+
188
+ Numbers are a heuristic, not a quota. A solopreneur with strong types may run closer to 50/40/10 because integration tests buy more confidence per unit of effort. Adjust by data, not by tradition.
189
+
190
+ **Inverted pyramid is a smell**: if your E2E suite carries the proof and your unit suite is sparse, your design is probably testing badly (too coupled to make unit tests cheap). Fix the design.
191
+
192
+ ---
193
+
194
+ ## Mocking strategy
195
+
196
+ ### When to use what
197
+
198
+ | Test target | Boundary technique |
199
+ |---|---|
200
+ | Pure business logic | No mock. Real code. |
201
+ | HTTP client → external API | MSW handlers in `tests/msw/handlers.ts` (or pglite for inbound HTTP if testing a Next.js route handler) |
202
+ | ORM → Postgres | pglite (in-memory) for unit-of-work. Neon dev branch for E2E-like integration |
203
+ | Date / Time | `vi.useFakeTimers()`, advance explicitly |
204
+ | `Math.random` / UUID | seeded RNG passed via parameter (composes with `void-hexagonal-architecture` port pattern) |
205
+ | File system | `memfs` or temp directory |
206
+ | Server Actions | invoke directly; the sandbox is light |
207
+
208
+ ### What NOT to mock
209
+
210
+ - A pure function (run it)
211
+ - A business service (compose, do not mock)
212
+ - The framework router (use the framework's testing utilities)
213
+ - The ORM at the unit level (use pglite — see `void-tdd` anti-pattern)
214
+
215
+ The companion hook `no-business-mock` warns on `vi.mock('@/services/...')` patterns.
216
+
217
+ ---
218
+
219
+ ## Banned practices
220
+
221
+ ### Snapshot testing — banned by default
222
+
223
+ Snapshots devolve into "update on green" — the test passes regardless of correctness. Allowed only for:
224
+
225
+ - **UI visual regression**: in `**/__visual__/**` directory with documented review process
226
+ - **Compiler output sanity** (`__generated__/` snapshots): same constraint
227
+
228
+ Each snapshot has a reason. No `.toMatchSnapshot()` outside the whitelist without explicit code-review approval.
229
+
230
+ ### `.only` / `.skip` / `fdescribe` / `xit`
231
+
232
+ Banned in committed code. They mean "I will not run this." If you mean "this case is intentionally not yet tested," write a `it.todo('description')` — the test runner reports todos.
233
+
234
+ The companion hook `no-only-no-skip` blocks commits with `.only` / `fdescribe` / `xit` in the staged diff (allowed in `**/__skip-on-purpose__/**` whitelist with justifying comment).
235
+
236
+ ### Implementation spies as primary assertion
237
+
238
+ `expect(spy).toHaveBeenCalledWith(...)` is for "did the side effect at this boundary happen" — only at infrastructure boundaries. It is not the assertion for business behavior.
239
+
240
+ ### `describe.each` for unrelated scenarios
241
+
242
+ `describe.each([...])` is for genuinely parametric tests (boundary values, equivalence classes). It is NOT for grouping 5 different scenarios that share scaffolding — that hides the differences.
243
+
244
+ ### Inline DB mocks for business-layer tests
245
+
246
+ Use pglite or dev branch. Mocking Drizzle breaks at every schema change while protecting nothing real.
247
+
248
+ ---
249
+
250
+ ## Composition with other skills
251
+
252
+ - **With `void-tdd`**: `void-tdd` is the cycle (when), `void-testing` is the technique (how). RED step delegates the *how* here.
253
+ - **With the mutation gate** (strict TDD, when the project declares a mutation runner): a high survivor rate is a `void-testing` signal — the tests are not asserting on the right things. KILL step iterates back here.
254
+ - **With `void-typescript-strict`**: tests use branded types from production. A test needing `as any` is signaling a missing factory or brittle type.
255
+ - **With `void-hexagonal-architecture`**: ports tested with nullable infrastructure. In-memory adapters owned by the domain.
256
+ - **With `void-migrations`**: DB migrations have their own discipline; this skill's pyramid does not apply to migration tests.
257
+
258
+ ---
259
+
260
+ ## Companion hooks
261
+
262
+ - **`no-only-no-skip`** — block on `.only` / `fdescribe` / `xit` / `.skip` in staged diff (whitelist: `**/__skip-on-purpose__/**`)
263
+ - **`test-name-lint`** — warn on weak test names matching `/^\s*(test|works|should)\s*$/i`
264
+ - **`no-business-mock`** — warn on `vi.mock\('@/(services|domain)/...'\)` patterns
265
+ - **`no-snapshot-default`** — warn on new `.toMatchSnapshot()` outside `**/__visual__/**` whitelist
266
+
267
+ See `../../hooks/`.
268
+
269
+ ---
270
+
271
+ ## Anti-rules
272
+
273
+ - MUST NOT decide WHETHER a test exists. That is `void-tdd`'s Iron Law.
274
+ - MUST NOT decide coverage thresholds. That is `void-tdd`'s 100%-on-business-layer default + documented exceptions.
275
+ - MUST NOT decide architecture (what is a port, what is an adapter). Hexagonal owns that.
276
+ - MUST NOT decide framework specifics (which Vitest reporter, Playwright trace mode). Pack-level config.
277
+ - MUST NOT silently allow snapshot creep.
278
+
279
+ ---
280
+
281
+ ## When you are stuck
282
+
283
+ | Problem | Solution |
284
+ |---|---|
285
+ | Test feels brittle, breaks on refactor | Coupled to implementation. Test the behavior at the boundary instead. |
286
+ | Need to mock 5 things to test 1 thing | Coupling smell. Inject dependencies via parameters. Compose with `void-hexagonal-architecture`. |
287
+ | Fixture is huge | Externalize to `tests/fixtures/`. Use a factory with overrides. |
288
+ | Test name is weak | Describe the behavior, not the function. Imperative. |
289
+ | Snapshot wants to update on every change | Snapshot is wrong. Replace with explicit assertions. |
290
+ | Pyramid feels wrong | Adjust by data after 50+ tests. The 70/20/10 is a heuristic. |
291
+
292
+ ---
293
+
294
+ ## Final rule
295
+
296
+ ```
297
+ A test → asserts behavior, uses real code where possible, runs deterministically, produces pristine output.
298
+ Otherwise → it is not a voidcorp testing test.
299
+ ```
300
+
301
+ Tests prove behavior. They are a specification, not a record.
@@ -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: standard
6
+ activation: always
7
+ triggers:
8
+ globs: ["**/*.test.ts", "**/*.spec.ts"]
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,18 @@
1
+ Sources for `void-ticket` skill (see `docs/plans/skill-audits/void-ticket.md` for full audit):
2
+
3
+ - loomcrafthq/ticket-craft — reference for the platform-agnostic tracker template
4
+ (Context / Scope / Technical Specs / AC / DoD / Edge Cases) and T-shirt sizing.
5
+ KEEP EXTERNAL as a generic fallback; this skill is the doctrine-aware,
6
+ harness-composing version. Distilled, not vendored.
7
+ - Composes upstream: brainstorm, plan (the thinking
8
+ this skill captures). Downstream: implement (consumes the ticket and
9
+ its declared passes).
10
+
11
+ Strategy: author + distill. Three deliberate additions over ticket-craft:
12
+ 1. INGEST-first: the ticket records decisions already made (spec, plan, ADR,
13
+ conversation), it never invents scope.
14
+ 2. Estimate + labels + parent are REQUIRED native fields, not optional metadata.
15
+ This is the observed baseline failure (tickets shipped without them).
16
+ 3. Two new slots tie it to the harness: a TDD-mode-per-ticket and a
17
+ "runner passes that apply" declaration, so implement does not
18
+ re-derive the conditional passes. Plus an all-angles sweep before saving.
@@ -0,0 +1,239 @@
1
+ ---
2
+ name: void-ticket
3
+ description: Use when turning a finished brainstorm, plan, or design decision into a tracker ticket. Triggers on creating a ticket or issue, logging work, or breaking an approved spec into tickets.
4
+ ---
5
+
6
+ # ticket
7
+
8
+ A ticket an implementation agent can execute with zero follow-up questions. It does NOT invent scope: it ingests what was already decided (the brainstorm, the plan, this conversation, the relevant ADR) and renders it as a complete, estimated, labeled work item in the tracker. Downstream, `void-implement` executes it.
9
+
10
+ **Core principle:** the ticket is the contract between the thinking and the building. Every required slot is filled or the ticket is not ready. Estimate and labels are not optional metadata, they are how the backlog stays pilotable.
11
+
12
+ **Attribution**: see `.source`.
13
+
14
+ ---
15
+
16
+ ## When to invoke
17
+
18
+ - After `void-brainstorm` or `void-plan` produced a decision or spec, to capture it as trackable work.
19
+ - When the user says create a ticket, log this, or break this into tickets.
20
+ - Always writes to the project's tracker (Linear / Jira / GitHub / ...). On a project with a fixed tracker, team, and label conventions, use them and do not re-ask.
21
+
22
+ Do NOT use this to execute a ticket (`void-implement`) or to sequence many steps (`void-plan`).
23
+
24
+ ---
25
+
26
+ ## Ingest first, do not invent
27
+
28
+ Pull from what already exists, in order: the approved spec/plan, the brainstorm decisions, this conversation's decisions, the applicable ADR(s), the code conventions. The ticket RECORDS decisions already made. If a load-bearing decision is missing, go get it or flag it. Do not guess scope into existence.
29
+
30
+ A `docs/specs/*.md` spec with `source: forge` in its frontmatter (the forge→harness artifact contract) is a first-class source: its 18 recon variables, winning design, and critique verdict already answer scope, persona, and constraints — ingest them, do not re-ask. A partial forge spec (missing critique, or an older `forge_version` field) is ingested for what it has, with the gaps listed as the ticket's open questions.
31
+
32
+ ---
33
+
34
+ ## Admission: a finding earns its place or it is dropped
35
+
36
+ Most of what reaches this skill is not a decision someone made, it is a defect someone
37
+ *noticed*. Those arrive without end, because reading code always finds another inconsistency,
38
+ and each one is defensible on its own. A backlog that admits them all stops being pilotable, and
39
+ the objective recedes while every individual step looks correct.
40
+
41
+ So a noticed defect is not admitted on its merits. It is compared against **the unit being built
42
+ right now**, judged against the program's stated objective, and there are three outcomes and one
43
+ slot:
44
+
45
+ 1. **It blocks the current unit** — it is fixed inside that unit. No ticket.
46
+ 2. **It beats the current unit** — it becomes the next unit, and nothing else starts until it is
47
+ disposed of.
48
+ 3. **It loses** — it is dropped. Not filed, not deferred, not "kept for later".
49
+
50
+ Dropped means lost, and that is the point. A genuine defect is rediscoverable by construction:
51
+ a skill that lies will lie to the next reader, and a run will trip on it again. The only thing
52
+ ever written down is **evidence that cannot be reconstructed** — a failure observed once, a
53
+ measurement — as one line carrying the command that replays it. Never the opinion, never the
54
+ proposed fix, because describing the fix is how a finding smuggles in a design.
55
+
56
+ Two things are not admissible at all:
57
+
58
+ - **A reading nobody asked for.** What you noticed in a file you were not convened on does not
59
+ become work. If it matters, it will be found again by someone who was asked.
60
+ - **An ambition claim.** "This would be tenfold better" belongs to `void-brainstorm`, on a named
61
+ subject, deliberately. During execution it is an escape hatch, and it is the one that grows
62
+ plans.
63
+
64
+ State the comparison out loud when you drop something: what you found, and what it lost to. One
65
+ line. An arbitration nobody can see did not happen.
66
+
67
+ **Prose incoherence is a first-class defect**, in four forms: inside one skill, between two
68
+ skills, between the user's stated demand and a skill, and between a skill and the code it
69
+ describes. The last is this repository's repeat offender. It still goes through the comparison
70
+ above like anything else.
71
+
72
+ See the decision on a finding entering only by beating the work in progress.
73
+
74
+ ---
75
+
76
+ ## Search the tracker before you write
77
+
78
+ The backlog already answered part of this. Query it on the **subject**, never on
79
+ the title you are about to write: DEV-591 was called "unstable test suite" and
80
+ DEV-561 "test contention" — no shared word, same question, three days apart.
81
+ Search several phrasings of the thing itself, and include **closed** tickets: one
82
+ closed because the approach was wrong is exactly the one not to reopen unchanged.
83
+
84
+ An overlap means reading that ticket **in full** before deciding, not its title.
85
+ What costs a day is not the duplicate, it is the reasoning that was in the first
86
+ one: DEV-561 had established that an intermittent test is a question nobody has
87
+ answered rather than noise to isolate, and DEV-591 recommended what it forbade.
88
+
89
+ Then exactly one of two things, and creating in silence is neither:
90
+
91
+ - **enrich the existing ticket**, when the subject is the same;
92
+ - **create, linked, naming the difference** in one sentence, when the scope is
93
+ deliberately disjoint.
94
+
95
+ Never merge two tickets on your own: a resemblance is not an identity, and that
96
+ call is the human's. Say what you searched and what came back — a search nobody
97
+ can see did not happen. If the tracker is unreachable, say so and keep writing;
98
+ a handoff blocked on a lookup is worse than a duplicate.
99
+
100
+ Thirty results means the terms were too broad, not the backlog too large.
101
+
102
+ ---
103
+
104
+ ## The ticket: required slots
105
+
106
+ Render into the tracker description. Every slot is REQUIRED unless marked optional. A missing required slot means the ticket is not ready.
107
+
108
+ - **Title**: `[Verb] [Subject]`, imperative.
109
+ - **Context**: why it exists; link to the broader goal / spec / ADR.
110
+ - **Scope**: in scope / out of scope.
111
+ - **Technical specs**: files and packages touched, applicable ADR, conventions and patterns to follow, third-party docs to ground in. Exhaustive enough that no unknown remains.
112
+ - **Acceptance criteria**: objectively verifiable checkboxes.
113
+ - **Definition of Done**: tests written and green, 0 lint / type errors, 0 regressions, plus ticket-specific items.
114
+ - **Edge cases and gotchas**: boundary behaviors, error / empty / loading states, failure modes. This is the all-angles slot; an empty one means angles were missed.
115
+ - **TDD mode**: defer to `void-tdd`'s path-based auto-selection; note an explicit override to strict only for a business-critical surface (auth, payments, security, money).
116
+ - **Runner passes that apply**: which `void-implement` conditional passes you expect to fire (architecture? migration safety? async/idempotency? E2E? UX/UI? deep security?). This is an accelerator HINT, not authoritative: the runner still evaluates every predicate itself and may add passes you did not list.
117
+
118
+ ### Close the link, both ways
119
+
120
+ A ticket that cites its spec is half a link. Do both, in the same change:
121
+
122
+ 1. The ticket body opens with the paths of the spec and the plan it comes from.
123
+ 2. The `ticket:` field in each of those two files' frontmatter is filled with the
124
+ tracker id just created.
125
+
126
+ Neither direction is optional, because each answers a question the other cannot.
127
+ From the ticket, the reasoning: why this shape, what was rejected, which
128
+ trade-off was taken. From the spec, whether the thinking was ever executed and
129
+ where it landed. A spec with no ticket is a decision nobody carried out, and
130
+ nothing says so today.
131
+
132
+ The asymmetry is deliberate and worth keeping in mind: the spec and the plan
133
+ live in the repository because they belong to the project and must survive the
134
+ tracker, while the ticket is execution state and is mutable by nature. Copying
135
+ the reasoning into the tracker would put it where a workspace change can lose
136
+ it; copying the status into the repository would give it two owners. Only the
137
+ link crosses.
138
+
139
+ If the project has no tracker, say so and stop: there is no ticket to write, and
140
+ the spec plus the plan already hold what would have gone in it.
141
+
142
+ Native tracker fields (REQUIRED, set the real field, not prose):
143
+
144
+ - **Estimate** (points / size). Never leave empty.
145
+ - **Labels** (at least one; reuse existing, create if genuinely new).
146
+ - **Parent epic / project** link.
147
+ - **Dependencies** (`blockedBy`) in the native field, not just text.
148
+ - **Priority**.
149
+
150
+ ---
151
+
152
+ ## Multi-ticket programme handoff
153
+
154
+ After creating a complete pool of two or more tickets intended to run across sessions, create
155
+ `.void/program.md` in the same change. Do this only after the plan and ticket pool are
156
+ human-approved and every native dependency is saved. A single standalone ticket does not need a
157
+ programme descriptor.
158
+
159
+ Use tracker-agnostic routing frontmatter:
160
+
161
+ ```yaml
162
+ ---
163
+ schemaVersion: 1
164
+ status: executing
165
+ program: <stable-program-slug>
166
+ plan: <repository-relative-plan-path>
167
+ spec: <repository-relative-spec-path>
168
+ progress:
169
+ provider: <adapter capability id>
170
+ scope: <native workspace/project/repository query>
171
+ order: [<ordered immutable work-unit identifiers>]
172
+ states:
173
+ ready: [<native ready states>]
174
+ started: [<native started states>]
175
+ review: [<native review states>]
176
+ done: [<native completed states>]
177
+ humanGates: [<ticket identifiers requiring explicit approval>]
178
+ autopilot:
179
+ schemaVersion: 1
180
+ enabled: <true | false>
181
+ mergeGate: human
182
+ ---
183
+ ```
184
+
185
+ The body states that the plan supplies global intent, the complete provider-native record is the
186
+ executable unit, native blocker relations decide readiness, and `void-implement` owns the per-unit
187
+ lifecycle. `progress.order` is the deterministic tie-break among simultaneously ready units; it is
188
+ scope, not mutable progress. Never store a current or next unit, copied status, assignee, or
189
+ completion checklist in the program or checkpoint.
190
+
191
+ The `void-autopilot` block is required, because consent to autonomous execution is never inferred from silence: a program that does not want it declares `enabled: false`. `mergeGate` takes `human`, or `union-reviewed` with a `deployBranch` naming the branch that ships — that pair IS the consent to a machine merge, and there is no flag for it. Add `clusterSize` (1..4), `base`, `verifyCommands` (argv arrays, run with `shell:false`) and `ownership.sequential` / `ownership.reconcileOnly` only when the program enables autopilot.
192
+
193
+ Do not replace an unrelated executing programme. Stop and surface the collision. When the same
194
+ programme already has a descriptor, preserve its routing unless the user explicitly changes
195
+ programme scope. Automatic selection requires a provider adapter that can read and update status,
196
+ relations, assignee, comments, and review evidence; if those capabilities are unavailable, do not
197
+ claim automatic continuity.
198
+
199
+ ---
200
+
201
+ ## All-angles sweep before saving
202
+
203
+ Run a quick expert sweep so nothing is missed, then fold what surfaces into Edge cases or the applicable-passes slot:
204
+
205
+ - **Architecture**: boundaries, data model, public types.
206
+ - **Data / migrations**: schema change, backfill, zero-downtime (flags the runner's migration-safety pass).
207
+ - **Security**: trust boundary, untrusted input, tenancy.
208
+ - **Async / idempotency**: email, webhook, job, single-use token, replay (flags the runner's async pass).
209
+ - **QA**: edge / error / empty states, the end-to-end path.
210
+ - **UX**: if a UI surface is involved.
211
+ - **Perf / observability / docs**: cost, logging, doc updates owed in the same change.
212
+
213
+ This is the cheap insurance an expert team would not skip. It is what makes a ticket cover the angles the author would not have thought of alone.
214
+
215
+ ---
216
+
217
+ ## Sizing
218
+
219
+ Map T-shirt to the tracker's native scale: XS (<1h, trivial), S (1-3h), M (3-8h, minor unknowns), L (1-2d, real complexity), XL (>2d, split unless truly indivisible).
220
+
221
+ ---
222
+
223
+ ## Red flags: STOP, the ticket is not ready
224
+
225
+ | Rationalization | Reality |
226
+ |-----------------|---------|
227
+ | "I will add the estimate later" | Estimate is a required field. An unestimated backlog cannot be planned. |
228
+ | "Labels do not matter for now" | At least one label, always. Filtering and routing depend on it. |
229
+ | "The agent will figure out the edges" | The edge-cases slot is where all-angles coverage lives. Empty = angles missed. |
230
+ | "Scope is obvious from the title" | The implementation agent has none of this conversation. Spell it out. |
231
+ | "No parent, it is standalone" | Orphan tickets rot. Link the epic or project. |
232
+
233
+ A ticket missing a required slot or field is not done, however clear it feels.
234
+
235
+ ---
236
+
237
+ ## Composition
238
+
239
+ Upstream: `void-brainstorm` and `void-plan` produced the thinking (or a `source: forge` spec did — see "Ingest first"); this skill captures it. Downstream: `void-implement` consumes the ticket and the passes it declares. On a project, follow that project's tracker doctrine (team, project, label and estimate conventions) rather than re-deciding them here; this skill stays the harness-doctrine layer (ingest, required slots, runner handoff).
@@ -0,0 +1,14 @@
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
+ owner: folpe
7
+ runtimes: [claude, codex]
8
+ enforcement:
9
+ floor: ci
10
+ inline:
11
+ claude: active
12
+ codex: active
13
+ hermes: ci-only
14
+ eval_targets: [claude/anthropic/opus]
@@ -0,0 +1,10 @@
1
+ Sources for `void-typescript-strict` skill (see `docs/plans/skill-audits/void-typescript-strict.md` for full audit):
2
+
3
+ - citypaul/.dotfiles tsconfig stance — strict + noUncheckedIndexedAccess + exactOptionalPropertyTypes baseline
4
+ - Anders Hejlsberg + TypeScript handbook — https://www.typescriptlang.org/docs/handbook/ — type system semantics
5
+ - Matt Pocock "Total TypeScript" — https://www.totaltypescript.com — branded types, satisfies operator, generic helpers
6
+ - tkdodo (Dominik Dorfmeister) "TypeScript Tag of Doom" + narrowing series — https://tkdodo.eu/blog/type-script-tag-of-doom — discriminated unions, as const, no-as discipline
7
+ - type-fest — https://github.com/sindresorhus/type-fest — utility library referenced, NOT vendored as default dep
8
+ - Zod — https://zod.dev — boundary validation library composed with this skill
9
+
10
+ Strategy: distill. Author from first principles; rules are common knowledge, discipline is in enforcement (hooks: tsc-noemit-precommit, no-any-grep, no-as-cast-grep).