exonous 0.0.0-stage → 2.10.4

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 (385) hide show
  1. package/README.md +100 -2
  2. package/assets/THIRD-PARTY-NOTICES.md +29 -0
  3. package/assets/adapters/opencode/exonous.js +54 -0
  4. package/assets/agents/exo-backend.md +22 -0
  5. package/assets/agents/exo-cto.md +22 -0
  6. package/assets/agents/exo-data-ai.md +22 -0
  7. package/assets/agents/exo-designer.md +22 -0
  8. package/assets/agents/exo-devops.md +22 -0
  9. package/assets/agents/exo-frontend.md +22 -0
  10. package/assets/agents/exo-infra.md +22 -0
  11. package/assets/agents/exo-mobile.md +22 -0
  12. package/assets/agents/exo-pm.md +22 -0
  13. package/assets/agents/exo-qa.md +22 -0
  14. package/assets/agents/exo-researcher.md +22 -0
  15. package/assets/agents/exo-security.md +22 -0
  16. package/assets/agents/roster.json +209 -0
  17. package/assets/agents/taxis.js +189 -0
  18. package/assets/editors/cursor/frontend-skills.mdc +27 -0
  19. package/assets/editors/hooks/cursor/hooks.json +11 -0
  20. package/assets/machine/PR-TEMPLATE.md +21 -0
  21. package/assets/machine/hooks/anamnesis.cjs +61 -0
  22. package/assets/machine/hooks/ethos.cjs +48 -0
  23. package/assets/machine/hooks/kairos.cjs +46 -0
  24. package/assets/machine/hooks/lib/cli-options.cjs +133 -0
  25. package/assets/machine/hooks/lib/memory.cjs +488 -0
  26. package/assets/machine/hooks/lib/metron.cjs +52 -0
  27. package/assets/machine/hooks/lib/paths.cjs +99 -0
  28. package/assets/machine/hooks/lib/payload.cjs +81 -0
  29. package/assets/machine/hooks/lib/pr-template-validate.cjs +103 -0
  30. package/assets/machine/hooks/lib/release.cjs +58 -0
  31. package/assets/machine/hooks/lib/repo.cjs +138 -0
  32. package/assets/machine/hooks/lib/sanitize.cjs +37 -0
  33. package/assets/machine/hooks/lib/selfupdate.cjs +354 -0
  34. package/assets/machine/hooks/lib/shell.cjs +722 -0
  35. package/assets/machine/hooks/lib/template.cjs +70 -0
  36. package/assets/machine/hooks/lib/token.cjs +110 -0
  37. package/assets/machine/hooks/lib/validate-pr-body.cjs +21 -0
  38. package/assets/machine/hooks/pyle.cjs +302 -0
  39. package/assets/rules/nomos.md +59 -0
  40. package/assets/rules/praxis.md +38 -0
  41. package/assets/skills/code-review/SKILL.md +124 -0
  42. package/assets/skills/commit-changes/SKILL.md +49 -0
  43. package/assets/skills/deliver/SKILL.md +114 -0
  44. package/assets/skills/deliver/references/parallel.md +37 -0
  45. package/assets/skills/doc/SKILL.md +140 -0
  46. package/assets/skills/doc/doc.mjs +277 -0
  47. package/assets/skills/issue-board/SKILL.md +84 -0
  48. package/assets/skills/issue-board/board.mjs +389 -0
  49. package/assets/skills/issue-board/config.example.json +9 -0
  50. package/assets/skills/issue-board/render.py +189 -0
  51. package/assets/skills/make-pr/SKILL.md +24 -0
  52. package/assets/skills/native-ui/SKILL.md +67 -0
  53. package/assets/skills/native-ui/reference/apple.md +180 -0
  54. package/assets/skills/native-ui/reference/mobile-feel.md +221 -0
  55. package/assets/skills/native-ui/reference/swift.md +289 -0
  56. package/assets/skills/project-memory/SKILL.md +59 -0
  57. package/assets/skills/project-memory/config.example.json +4 -0
  58. package/assets/skills/project-memory/project-memory.mjs +478 -0
  59. package/assets/skills/security-review/SKILL.md +102 -0
  60. package/assets/skills/session-handoff/SKILL.md +23 -0
  61. package/assets/skills/session-handoff/config.example.json +3 -0
  62. package/assets/skills/ui-design/SKILL.md +75 -0
  63. package/assets/skills/ui-design/reference/adapt.md +151 -0
  64. package/assets/skills/ui-design/reference/adapt.native.md +35 -0
  65. package/assets/skills/ui-design/reference/android.md +50 -0
  66. package/assets/skills/ui-design/reference/animate.md +87 -0
  67. package/assets/skills/ui-design/reference/audit.md +76 -0
  68. package/assets/skills/ui-design/reference/audit.native.md +126 -0
  69. package/assets/skills/ui-design/reference/bolder.md +33 -0
  70. package/assets/skills/ui-design/reference/clarify.md +84 -0
  71. package/assets/skills/ui-design/reference/colorize.md +86 -0
  72. package/assets/skills/ui-design/reference/craft-floor.md +25 -0
  73. package/assets/skills/ui-design/reference/critique.md +345 -0
  74. package/assets/skills/ui-design/reference/degraded/asset-producer.md +35 -0
  75. package/assets/skills/ui-design/reference/degraded/documenter.md +23 -0
  76. package/assets/skills/ui-design/reference/degraded/finish-reviewer.md +43 -0
  77. package/assets/skills/ui-design/reference/degraded/manual-edit-applier.md +56 -0
  78. package/assets/skills/ui-design/reference/delight.md +63 -0
  79. package/assets/skills/ui-design/reference/distill.md +98 -0
  80. package/assets/skills/ui-design/reference/doctor.md +49 -0
  81. package/assets/skills/ui-design/reference/document.md +273 -0
  82. package/assets/skills/ui-design/reference/extract.md +52 -0
  83. package/assets/skills/ui-design/reference/harden.md +122 -0
  84. package/assets/skills/ui-design/reference/hooks.md +114 -0
  85. package/assets/skills/ui-design/reference/init.md +47 -0
  86. package/assets/skills/ui-design/reference/ios.md +55 -0
  87. package/assets/skills/ui-design/reference/layout.md +81 -0
  88. package/assets/skills/ui-design/reference/live-setup.md +75 -0
  89. package/assets/skills/ui-design/reference/live.md +326 -0
  90. package/assets/skills/ui-design/reference/new-work.md +350 -0
  91. package/assets/skills/ui-design/reference/onboard.md +85 -0
  92. package/assets/skills/ui-design/reference/operate.md +29 -0
  93. package/assets/skills/ui-design/reference/optimize.md +101 -0
  94. package/assets/skills/ui-design/reference/overdrive.md +83 -0
  95. package/assets/skills/ui-design/reference/polish.md +77 -0
  96. package/assets/skills/ui-design/reference/quieter.md +95 -0
  97. package/assets/skills/ui-design/reference/routing.md +37 -0
  98. package/assets/skills/ui-design/reference/shape.md +43 -0
  99. package/assets/skills/ui-design/reference/styles/brutalist.md +45 -0
  100. package/assets/skills/ui-design/reference/styles/design-md.md +70 -0
  101. package/assets/skills/ui-design/reference/styles/direction.md +95 -0
  102. package/assets/skills/ui-design/reference/styles/full-output.md +42 -0
  103. package/assets/skills/ui-design/reference/styles/minimalist.md +64 -0
  104. package/assets/skills/ui-design/reference/styles/premium.md +65 -0
  105. package/assets/skills/ui-design/reference/styles/redesign.md +59 -0
  106. package/assets/skills/ui-design/reference/typeset.md +73 -0
  107. package/assets/skills/ui-design/reference/visualize.md +156 -0
  108. package/assets/skills/ui-design/scripts/ENGINE-LICENSE +191 -0
  109. package/assets/skills/ui-design/scripts/VERSION +1 -0
  110. package/assets/skills/ui-design/scripts/bin/darwin-arm64/impeccable +0 -0
  111. package/assets/skills/ui-design/scripts/command-metadata.json +94 -0
  112. package/assets/skills/ui-design/scripts/data/font-index-failures.json +121 -0
  113. package/assets/skills/ui-design/scripts/data/font-index.json +1 -0
  114. package/assets/skills/ui-design/scripts/impeccable +206 -0
  115. package/assets/skills/ui-design/scripts/impeccable.cmd +214 -0
  116. package/assets/skills/ui-design/scripts/live-browser-dom.js +167 -0
  117. package/assets/skills/ui-design/scripts/live-browser-ignores.js +242 -0
  118. package/assets/skills/ui-design/scripts/live-browser-session.js +144 -0
  119. package/assets/skills/ui-design/scripts/live-browser.js +12990 -0
  120. package/assets/skills/ui-design/scripts/modern-screenshot.umd.js +14 -0
  121. package/assets/skills/ui-design/scripts/ui-design +6 -0
  122. package/assets/skills/ui-design/scripts/ui-design.cmd +3 -0
  123. package/assets/skills/ui-design/scripts/ui-design.mjs +124 -0
  124. package/assets/skills/ui-mockup/SKILL.md +68 -0
  125. package/assets/skills/ui-mockup/reference/brandkit.md +101 -0
  126. package/assets/skills/ui-mockup/reference/image-to-code.md +83 -0
  127. package/assets/skills/ui-mockup/reference/mobile-comps.md +94 -0
  128. package/assets/skills/ui-mockup/reference/web-comps.md +83 -0
  129. package/assets/skills/ui-motion/SKILL.md +112 -0
  130. package/assets/skills/ui-motion/reference/expo.md +224 -0
  131. package/assets/skills/ui-motion/reference/opportunities.md +81 -0
  132. package/assets/skills/ui-motion/reference/prototype.md +238 -0
  133. package/assets/skills/ui-motion/reference/review.md +163 -0
  134. package/assets/skills/ui-motion/reference/toasts.md +144 -0
  135. package/assets/skills/ui-motion/reference/ui-libraries.md +71 -0
  136. package/assets/skills/ui-motion/reference/vocabulary.md +130 -0
  137. package/assets/skills/ui-motion/reference/web.md +294 -0
  138. package/assets/skills/ui-patterns/SKILL.md +105 -0
  139. package/assets/skills/ui-patterns/references/stacks/html-tailwind.md +40 -0
  140. package/assets/skills/ui-patterns/references/stacks/nextjs.md +52 -0
  141. package/assets/skills/ui-patterns/references/stacks/nuxt.md +100 -0
  142. package/assets/skills/ui-patterns/references/stacks/react-native.md +48 -0
  143. package/assets/skills/ui-patterns/references/stacks/react.md +49 -0
  144. package/assets/skills/ui-patterns/references/stacks/shadcn.md +57 -0
  145. package/assets/skills/ui-patterns/references/stacks/vue.md +37 -0
  146. package/assets/techne/.claude-plugin/marketplace.json +31 -0
  147. package/assets/techne/.claude-plugin/plugin.json +24 -0
  148. package/assets/techne/.mcp.json +8 -0
  149. package/assets/techne/commands/build-fix.md +48 -0
  150. package/assets/techne/commands/refactor-clean.md +46 -0
  151. package/assets/techne/commands/test-coverage.md +42 -0
  152. package/assets/techne/hooks/hooks.json +49 -0
  153. package/assets/techne/rules/angular/coding-style.md +49 -0
  154. package/assets/techne/rules/angular/hooks.md +23 -0
  155. package/assets/techne/rules/angular/patterns.md +48 -0
  156. package/assets/techne/rules/angular/security.md +26 -0
  157. package/assets/techne/rules/angular/testing.md +46 -0
  158. package/assets/techne/rules/arkts/coding-style.md +63 -0
  159. package/assets/techne/rules/arkts/hooks.md +38 -0
  160. package/assets/techne/rules/arkts/patterns.md +42 -0
  161. package/assets/techne/rules/arkts/security.md +35 -0
  162. package/assets/techne/rules/arkts/testing.md +39 -0
  163. package/assets/techne/rules/common/agents.md +6 -0
  164. package/assets/techne/rules/common/code-review.md +15 -0
  165. package/assets/techne/rules/common/coding-style.md +13 -0
  166. package/assets/techne/rules/common/development-workflow.md +5 -0
  167. package/assets/techne/rules/common/git-workflow.md +30 -0
  168. package/assets/techne/rules/common/hooks.md +7 -0
  169. package/assets/techne/rules/common/patterns.md +3 -0
  170. package/assets/techne/rules/common/performance.md +3 -0
  171. package/assets/techne/rules/common/security.md +5 -0
  172. package/assets/techne/rules/common/testing.md +3 -0
  173. package/assets/techne/rules/cpp/coding-style.md +31 -0
  174. package/assets/techne/rules/cpp/hooks.md +26 -0
  175. package/assets/techne/rules/cpp/patterns.md +31 -0
  176. package/assets/techne/rules/cpp/security.md +37 -0
  177. package/assets/techne/rules/cpp/testing.md +31 -0
  178. package/assets/techne/rules/csharp/coding-style.md +30 -0
  179. package/assets/techne/rules/csharp/hooks.md +24 -0
  180. package/assets/techne/rules/csharp/patterns.md +28 -0
  181. package/assets/techne/rules/csharp/security.md +32 -0
  182. package/assets/techne/rules/csharp/testing.md +27 -0
  183. package/assets/techne/rules/dart/coding-style.md +47 -0
  184. package/assets/techne/rules/dart/hooks.md +26 -0
  185. package/assets/techne/rules/dart/patterns.md +38 -0
  186. package/assets/techne/rules/dart/security.md +44 -0
  187. package/assets/techne/rules/dart/testing.md +39 -0
  188. package/assets/techne/rules/fsharp/coding-style.md +34 -0
  189. package/assets/techne/rules/fsharp/hooks.md +25 -0
  190. package/assets/techne/rules/fsharp/patterns.md +43 -0
  191. package/assets/techne/rules/fsharp/security.md +32 -0
  192. package/assets/techne/rules/fsharp/testing.md +27 -0
  193. package/assets/techne/rules/golang/coding-style.md +30 -0
  194. package/assets/techne/rules/golang/hooks.md +17 -0
  195. package/assets/techne/rules/golang/patterns.md +43 -0
  196. package/assets/techne/rules/golang/security.md +33 -0
  197. package/assets/techne/rules/golang/testing.md +20 -0
  198. package/assets/techne/rules/java/coding-style.md +51 -0
  199. package/assets/techne/rules/java/hooks.md +18 -0
  200. package/assets/techne/rules/java/patterns.md +55 -0
  201. package/assets/techne/rules/java/security.md +33 -0
  202. package/assets/techne/rules/java/testing.md +33 -0
  203. package/assets/techne/rules/kotlin/coding-style.md +50 -0
  204. package/assets/techne/rules/kotlin/hooks.md +17 -0
  205. package/assets/techne/rules/kotlin/patterns.md +44 -0
  206. package/assets/techne/rules/kotlin/security.md +34 -0
  207. package/assets/techne/rules/kotlin/testing.md +38 -0
  208. package/assets/techne/rules/nuxt/coding-style.md +20 -0
  209. package/assets/techne/rules/nuxt/hooks.md +16 -0
  210. package/assets/techne/rules/nuxt/patterns.md +46 -0
  211. package/assets/techne/rules/nuxt/security.md +19 -0
  212. package/assets/techne/rules/nuxt/testing.md +15 -0
  213. package/assets/techne/rules/perl/coding-style.md +33 -0
  214. package/assets/techne/rules/perl/hooks.md +22 -0
  215. package/assets/techne/rules/perl/patterns.md +43 -0
  216. package/assets/techne/rules/perl/security.md +39 -0
  217. package/assets/techne/rules/perl/testing.md +42 -0
  218. package/assets/techne/rules/php/coding-style.md +30 -0
  219. package/assets/techne/rules/php/hooks.md +24 -0
  220. package/assets/techne/rules/php/patterns.md +26 -0
  221. package/assets/techne/rules/php/security.md +27 -0
  222. package/assets/techne/rules/php/testing.md +28 -0
  223. package/assets/techne/rules/python/coding-style.md +38 -0
  224. package/assets/techne/rules/python/fastapi.md +57 -0
  225. package/assets/techne/rules/python/hooks.md +19 -0
  226. package/assets/techne/rules/python/patterns.md +37 -0
  227. package/assets/techne/rules/python/security.md +26 -0
  228. package/assets/techne/rules/python/testing.md +32 -0
  229. package/assets/techne/rules/react/coding-style.md +24 -0
  230. package/assets/techne/rules/react/hooks.md +62 -0
  231. package/assets/techne/rules/react/patterns.md +48 -0
  232. package/assets/techne/rules/react/security.md +45 -0
  233. package/assets/techne/rules/react/testing.md +42 -0
  234. package/assets/techne/rules/react-native/accessibility.md +14 -0
  235. package/assets/techne/rules/react-native/coding-style.md +16 -0
  236. package/assets/techne/rules/react-native/hooks.md +16 -0
  237. package/assets/techne/rules/react-native/patterns.md +18 -0
  238. package/assets/techne/rules/react-native/performance.md +14 -0
  239. package/assets/techne/rules/react-native/production-readiness.md +16 -0
  240. package/assets/techne/rules/react-native/security.md +16 -0
  241. package/assets/techne/rules/react-native/testing.md +14 -0
  242. package/assets/techne/rules/ruby/coding-style.md +40 -0
  243. package/assets/techne/rules/ruby/hooks.md +33 -0
  244. package/assets/techne/rules/ruby/patterns.md +33 -0
  245. package/assets/techne/rules/ruby/security.md +39 -0
  246. package/assets/techne/rules/ruby/testing.md +35 -0
  247. package/assets/techne/rules/rust/coding-style.md +41 -0
  248. package/assets/techne/rules/rust/hooks.md +16 -0
  249. package/assets/techne/rules/rust/patterns.md +42 -0
  250. package/assets/techne/rules/rust/security.md +33 -0
  251. package/assets/techne/rules/rust/testing.md +30 -0
  252. package/assets/techne/rules/swift/coding-style.md +30 -0
  253. package/assets/techne/rules/swift/hooks.md +20 -0
  254. package/assets/techne/rules/swift/patterns.md +30 -0
  255. package/assets/techne/rules/swift/security.md +22 -0
  256. package/assets/techne/rules/swift/testing.md +28 -0
  257. package/assets/techne/rules/typescript/coding-style.md +38 -0
  258. package/assets/techne/rules/typescript/hooks.md +14 -0
  259. package/assets/techne/rules/typescript/patterns.md +12 -0
  260. package/assets/techne/rules/typescript/security.md +14 -0
  261. package/assets/techne/rules/typescript/testing.md +12 -0
  262. package/assets/techne/rules/vue/coding-style.md +19 -0
  263. package/assets/techne/rules/vue/hooks.md +13 -0
  264. package/assets/techne/rules/vue/patterns.md +29 -0
  265. package/assets/techne/rules/vue/security.md +11 -0
  266. package/assets/techne/rules/vue/testing.md +11 -0
  267. package/assets/techne/rules/web/coding-style.md +25 -0
  268. package/assets/techne/rules/web/design-quality.md +21 -0
  269. package/assets/techne/rules/web/hooks.md +39 -0
  270. package/assets/techne/rules/web/patterns.md +23 -0
  271. package/assets/techne/rules/web/performance.md +25 -0
  272. package/assets/techne/rules/web/security.md +23 -0
  273. package/assets/techne/rules/web/testing.md +21 -0
  274. package/assets/techne/scripts/hooks/config-guard.js +50 -0
  275. package/assets/techne/scripts/hooks/edit-tracker.js +26 -0
  276. package/assets/techne/scripts/hooks/lib/shell.js +204 -0
  277. package/assets/techne/scripts/hooks/no-verify-guard.js +205 -0
  278. package/assets/techne/scripts/hooks/run.js +92 -0
  279. package/assets/techne/scripts/hooks/stop-checks.js +136 -0
  280. package/assets/techne/skills/angular/SKILL.md +34 -0
  281. package/assets/techne/skills/angular/reference/components-and-templates.md +63 -0
  282. package/assets/techne/skills/angular/reference/dependency-injection.md +44 -0
  283. package/assets/techne/skills/angular/reference/forms.md +97 -0
  284. package/assets/techne/skills/angular/reference/routing.md +50 -0
  285. package/assets/techne/skills/angular/reference/signals-and-state.md +59 -0
  286. package/assets/techne/skills/angular/reference/styling-motion-a11y.md +54 -0
  287. package/assets/techne/skills/angular/reference/testing.md +52 -0
  288. package/assets/techne/skills/angular/reference/tooling.md +31 -0
  289. package/assets/techne/skills/cpp/SKILL.md +27 -0
  290. package/assets/techne/skills/cpp/reference/coding-standards.md +160 -0
  291. package/assets/techne/skills/databases/SKILL.md +35 -0
  292. package/assets/techne/skills/databases/reference/clickhouse.md +102 -0
  293. package/assets/techne/skills/databases/reference/migrations.md +94 -0
  294. package/assets/techne/skills/databases/reference/mysql.md +101 -0
  295. package/assets/techne/skills/databases/reference/postgres.md +72 -0
  296. package/assets/techne/skills/databases/reference/prisma.md +105 -0
  297. package/assets/techne/skills/databases/reference/redis.md +108 -0
  298. package/assets/techne/skills/delivery/SKILL.md +35 -0
  299. package/assets/techne/skills/delivery/reference/deployment-patterns.md +58 -0
  300. package/assets/techne/skills/delivery/reference/docker-patterns.md +77 -0
  301. package/assets/techne/skills/delivery/reference/git-workflow.md +64 -0
  302. package/assets/techne/skills/delivery/reference/github-ops.md +67 -0
  303. package/assets/techne/skills/delivery/reference/jira-integration.md +53 -0
  304. package/assets/techne/skills/delivery/reference/kubernetes-patterns.md +67 -0
  305. package/assets/techne/skills/dotnet/SKILL.md +27 -0
  306. package/assets/techne/skills/dotnet/reference/dotnet-core.md +131 -0
  307. package/assets/techne/skills/flutter/SKILL.md +29 -0
  308. package/assets/techne/skills/flutter/reference/code-review.md +76 -0
  309. package/assets/techne/skills/flutter/reference/patterns.md +201 -0
  310. package/assets/techne/skills/go/SKILL.md +28 -0
  311. package/assets/techne/skills/go/reference/patterns.md +87 -0
  312. package/assets/techne/skills/go/reference/testing.md +142 -0
  313. package/assets/techne/skills/java/SKILL.md +29 -0
  314. package/assets/techne/skills/java/reference/java-standards.md +117 -0
  315. package/assets/techne/skills/java/reference/springboot.md +108 -0
  316. package/assets/techne/skills/kotlin/SKILL.md +35 -0
  317. package/assets/techne/skills/kotlin/reference/android-clean-architecture.md +115 -0
  318. package/assets/techne/skills/kotlin/reference/compose-multiplatform-patterns.md +113 -0
  319. package/assets/techne/skills/kotlin/reference/kotlin-coroutines-flows.md +93 -0
  320. package/assets/techne/skills/kotlin/reference/kotlin-patterns.md +74 -0
  321. package/assets/techne/skills/kotlin/reference/kotlin-testing.md +115 -0
  322. package/assets/techne/skills/ml/SKILL.md +34 -0
  323. package/assets/techne/skills/ml/reference/ai-regression-testing.md +99 -0
  324. package/assets/techne/skills/ml/reference/cost-aware-llm-pipeline.md +133 -0
  325. package/assets/techne/skills/ml/reference/eval-harness.md +94 -0
  326. package/assets/techne/skills/ml/reference/mle-workflow.md +177 -0
  327. package/assets/techne/skills/ml/reference/prompt-optimizer.md +107 -0
  328. package/assets/techne/skills/ml/reference/pytorch-patterns.md +164 -0
  329. package/assets/techne/skills/php/SKILL.md +27 -0
  330. package/assets/techne/skills/php/reference/laravel.md +142 -0
  331. package/assets/techne/skills/python/SKILL.md +33 -0
  332. package/assets/techne/skills/python/reference/django.md +104 -0
  333. package/assets/techne/skills/python/reference/fastapi.md +118 -0
  334. package/assets/techne/skills/python/reference/python-core.md +88 -0
  335. package/assets/techne/skills/python/reference/python-testing.md +105 -0
  336. package/assets/techne/skills/quality/SKILL.md +34 -0
  337. package/assets/techne/skills/quality/reference/benchmark.md +55 -0
  338. package/assets/techne/skills/quality/reference/browser-qa.md +60 -0
  339. package/assets/techne/skills/quality/reference/coding-standards.md +88 -0
  340. package/assets/techne/skills/quality/reference/e2e-testing.md +99 -0
  341. package/assets/techne/skills/quality/reference/tdd-workflow.md +89 -0
  342. package/assets/techne/skills/quality/reference/verification-loop.md +80 -0
  343. package/assets/techne/skills/react/SKILL.md +30 -0
  344. package/assets/techne/skills/react/reference/nextjs-turbopack.md +42 -0
  345. package/assets/techne/skills/react/reference/react-patterns.md +139 -0
  346. package/assets/techne/skills/react/reference/react-performance.md +101 -0
  347. package/assets/techne/skills/react/reference/react-testing.md +139 -0
  348. package/assets/techne/skills/react-native/SKILL.md +28 -0
  349. package/assets/techne/skills/react-native/reference/expo-patterns.md +196 -0
  350. package/assets/techne/skills/research/SKILL.md +35 -0
  351. package/assets/techne/skills/research/reference/architecture-decision-records.md +65 -0
  352. package/assets/techne/skills/research/reference/codebase-onboarding.md +44 -0
  353. package/assets/techne/skills/research/reference/deep-research.md +50 -0
  354. package/assets/techne/skills/research/reference/iterative-retrieval.md +62 -0
  355. package/assets/techne/skills/research/reference/product-lens.md +38 -0
  356. package/assets/techne/skills/research/reference/search-first.md +50 -0
  357. package/assets/techne/skills/rust/SKILL.md +28 -0
  358. package/assets/techne/skills/rust/reference/patterns.md +108 -0
  359. package/assets/techne/skills/rust/reference/testing.md +142 -0
  360. package/assets/techne/skills/services/SKILL.md +32 -0
  361. package/assets/techne/skills/services/reference/api-contracts.md +139 -0
  362. package/assets/techne/skills/services/reference/backend-layers.md +95 -0
  363. package/assets/techne/skills/services/reference/errors-and-resilience.md +146 -0
  364. package/assets/techne/skills/services/reference/hexagonal-boundaries.md +93 -0
  365. package/assets/techne/skills/services/reference/mcp-servers.md +50 -0
  366. package/assets/techne/skills/services/reference/nestjs.md +96 -0
  367. package/assets/techne/skills/swift/SKILL.md +29 -0
  368. package/assets/techne/skills/swift/reference/concurrency.md +83 -0
  369. package/assets/techne/skills/swift/reference/swiftui.md +139 -0
  370. package/assets/techne/skills/vue/SKILL.md +29 -0
  371. package/assets/techne/skills/vue/reference/nuxt4-patterns.md +90 -0
  372. package/assets/techne/skills/vue/reference/ui-to-vue.md +90 -0
  373. package/assets/techne/skills/vue/reference/vue-patterns.md +151 -0
  374. package/assets/techne/skills/web/SKILL.md +30 -0
  375. package/assets/techne/skills/web/reference/bun-runtime.md +55 -0
  376. package/assets/techne/skills/web/reference/frontend-patterns.md +54 -0
  377. package/assets/techne/skills/web/reference/seo.md +77 -0
  378. package/assets/techne/skills/web/reference/vite-patterns.md +96 -0
  379. package/bin/native.cjs +30 -0
  380. package/native/aarch64-apple-darwin/exonous +0 -0
  381. package/native/aarch64-unknown-linux-gnu/exonous +0 -0
  382. package/native/x86_64-apple-darwin/exonous +0 -0
  383. package/native/x86_64-pc-windows-msvc/exonous.exe +0 -0
  384. package/native/x86_64-unknown-linux-gnu/exonous +0 -0
  385. package/package.json +1 -6
@@ -0,0 +1,131 @@
1
+ # .NET / C# core
2
+
3
+ ## Immutability and nullability
4
+
5
+ ```csharp
6
+ public sealed record Money(decimal Amount, string Currency);
7
+
8
+ public sealed class CreateOrderRequest
9
+ {
10
+ public required string CustomerId { get; init; }
11
+ public required IReadOnlyList<OrderLine> Lines { get; init; }
12
+ }
13
+ ```
14
+
15
+ Enable nullable reference types; express optional returns as `T?` or `Result<T>`.
16
+
17
+ ## Dependency injection
18
+
19
+ ```csharp
20
+ public interface IOrderRepository
21
+ {
22
+ Task<Order?> FindByIdAsync(Guid id, CancellationToken cancellationToken);
23
+ Task AddAsync(Order order, CancellationToken cancellationToken);
24
+ }
25
+
26
+ builder.Services.AddScoped<IOrderRepository, SqlOrderRepository>();
27
+ builder.Services.AddScoped<IOrderService, OrderService>();
28
+ ```
29
+
30
+ Primary constructors (C# 12+) are fine when all dependencies are injected interfaces.
31
+
32
+ ## Async
33
+
34
+ ```csharp
35
+ public async Task<OrderSummary> BuildSummaryAsync(Guid id, CancellationToken cancellationToken)
36
+ {
37
+ var order = await _orders.FindByIdAsync(id, cancellationToken)
38
+ ?? throw new NotFoundException(id);
39
+
40
+ var buyer = await _customers.GetAsync(order.CustomerId, cancellationToken);
41
+ return OrderSummary.From(order, buyer);
42
+ }
43
+ ```
44
+
45
+ Parallel independent IO:
46
+
47
+ ```csharp
48
+ await Task.WhenAll(fetchOrders, fetchMetrics);
49
+ ```
50
+
51
+ Never block on `Task` in ASP.NET request threads.
52
+
53
+ ## Options
54
+
55
+ ```csharp
56
+ public sealed class EmailOptions
57
+ {
58
+ public const string SectionName = "Email";
59
+ public required string Host { get; init; }
60
+ public int Port { get; init; } = 587;
61
+ }
62
+
63
+ builder.Services.Configure<EmailOptions>(
64
+ builder.Configuration.GetSection(EmailOptions.SectionName));
65
+ ```
66
+
67
+ Inject `IOptions<EmailOptions>` or `IOptionsMonitor<EmailOptions>` for reload-safe settings.
68
+
69
+ ## Result instead of exceptions (expected failures)
70
+
71
+ ```csharp
72
+ public readonly record struct Result<T>(bool Ok, T? Value, string? Error)
73
+ {
74
+ public static Result<T> Success(T value) => new(true, value, null);
75
+ public static Result<T> Fail(string message) => new(false, default, message);
76
+ }
77
+ ```
78
+
79
+ Use for validation/business rejections; reserve exceptions for truly exceptional faults.
80
+
81
+ ## EF Core repository sketch
82
+
83
+ ```csharp
84
+ public async Task<Order?> FindByIdAsync(Guid id, CancellationToken cancellationToken)
85
+ {
86
+ return await _db.Orders
87
+ .Include(o => o.Lines)
88
+ .AsNoTracking()
89
+ .FirstOrDefaultAsync(o => o.Id == id, cancellationToken);
90
+ }
91
+ ```
92
+
93
+ Track entities only inside command handlers that mutate state.
94
+
95
+ ## Middleware
96
+
97
+ Register custom middleware with `app.UseMiddleware<RequestTimingMiddleware>()`; log elapsed ms and status code; avoid swallowing exceptions.
98
+
99
+ ## Minimal APIs
100
+
101
+ ```csharp
102
+ var orders = app.MapGroup("/api/orders").RequireAuthorization().WithTags("Orders");
103
+
104
+ orders.MapGet("/{id:guid}", async (Guid id, IOrderRepository repo, CancellationToken ct) =>
105
+ {
106
+ var order = await repo.FindByIdAsync(id, ct);
107
+ return order is null ? Results.NotFound() : Results.Ok(order);
108
+ });
109
+ ```
110
+
111
+ Use `TypedResults` for OpenAPI metadata; validate bodies with `[AsParameters]` or explicit records + `Results.ValidationProblem`.
112
+
113
+ ## Guard clauses
114
+
115
+ Validate arguments first (`ThrowIfNull`, range checks) so happy path stays flat.
116
+
117
+ ## Anti-patterns
118
+
119
+ | Issue | Remedy |
120
+ |-------|--------|
121
+ | `async void` (non-events) | return `Task` |
122
+ | `.Result` / `.Wait()` | `await` |
123
+ | empty `catch` | log + throw or map to problem detail |
124
+ | `new SqlConnection` in controller | injected factory/repository |
125
+ | `dynamic` in domain | strong types/generics |
126
+ | mutable static fields | scoped/singleton services |
127
+
128
+ ## Tooling
129
+
130
+ - `dotnet format` in CI; analyzers (nullable, CA rules) as errors where team agrees.
131
+ - Integration tests: `WebApplicationFactory` with test containers or SQLite provider per **techne:databases** guidance.
@@ -0,0 +1,29 @@
1
+ ---
2
+ name: flutter
3
+ description: Flutter and Dart application engineering — null-safe idioms, immutable state (sealed/freezed), widget architecture, BLoC/Riverpod/Provider patterns, GoRouter guards, Dio networking, errors, testing, and review checklists. Use when implementing or reviewing Flutter features, navigation, async UI, or Dart architecture.
4
+ ---
5
+
6
+ Dart and Flutter patterns for production apps: data flow, widgets, routing, HTTP, and quality gates. Platform chrome, adaptive UI, and native feel → **native-ui**; deep accessibility audits → **ui-design** (`audit`, `harden`).
7
+
8
+ ## Non-negotiable rules
9
+
10
+ 1. **Null-safe idioms** — Avoid `!`; use `?.`, `??`, early returns, and Dart 3 patterns; reserve `late` for guaranteed init (e.g. `AnimationController` in `initState`).
11
+ 2. **Explicit async state** — Sealed hierarchies or `freezed` unions for loading/success/failure; no overlapping `isLoading` + `hasError` booleans.
12
+ 3. **Widget classes, not builders** — Extract `_buildX()` helpers into `StatelessWidget`/`ConsumerWidget` subclasses; push `const` through the tree.
13
+ 4. **Narrow rebuilds** — Watch providers/blocs only in the smallest subtree; keep static chrome `const`.
14
+ 5. **Context safety** — After every `await` in widgets, guard with `mounted` / `context.mounted` before navigation, snackbars, or `setState`.
15
+ 6. **Layer separation** — Widgets render; state containers (Cubit, Notifier, etc.) orchestrate; repositories talk to APIs/DB — inject dependencies, no god objects.
16
+ 7. **Routing** — One declarative router (typically GoRouter); auth redirects and deep links centralized; typed route args, not raw maps.
17
+ 8. **HTTP** — Timeouts on the client; auth header interceptor; at most **one** token-refresh retry per request (flag in `extra`).
18
+ 9. **Lists** — `ListView.builder` / `GridView.builder` (or pagination) for large datasets; no unbounded `children:` lists.
19
+ 10. **Theming** — Colors and text from `Theme.of(context)`; no scattered magic hex in widgets.
20
+ 11. **Analysis** — Root `analysis_options.yaml` with strict casts/inference/raw-types; `flutter analyze` clean in CI.
21
+ 12. **Secrets** — Tokens in platform secure storage; config via `--dart-define` or env excluded from VCS; never log credentials.
22
+ 13. **Review routing** — Systematic review → **exo-qa** / code-review skill; security pass → **exo-security**; library APIs → **biblos** MCP.
23
+
24
+ ## References
25
+
26
+ | File | Load when |
27
+ |------|-----------|
28
+ | [reference/patterns.md](reference/patterns.md) | Writing features — state, widgets, GoRouter, Dio, errors, tests |
29
+ | [reference/code-review.md](reference/code-review.md) | Reviewing a PR or auditing project health across Dart/Flutter layers |
@@ -0,0 +1,76 @@
1
+ # Flutter / Dart review checklist
2
+
3
+ Library-agnostic gates for PR review. Adapt rows to the project’s state library (BLoC, Riverpod, Provider, signals, etc.).
4
+
5
+ ## Project and Dart hygiene
6
+
7
+ - Feature-first or layer-first layout; UI free of business rules.
8
+ - `analysis_options.yaml`: strict casts/inference/raw-types; shared in monorepos.
9
+ - No `print` in production — structured logging.
10
+ - Generated `*.g.dart` / `*.freezed.dart` committed or gitignored consistently.
11
+ - `package:` imports; `final`/`const` by default; typed catches (`on SpecificException`).
12
+ - No ignored futures without `unawaited`; no broad `catch (e)` without rethrow policy.
13
+
14
+ ## Widgets
15
+
16
+ - `build` under ~100 lines; hot paths split into widget classes.
17
+ - `const` constructors and literals where fields are final.
18
+ - Keys: `ValueKey`/`ObjectKey` in reorderable lists; never `UniqueKey()` inside `build`.
19
+ - Theme-driven color/text; responsive overflow handled (`Flexible`, `FittedBox`).
20
+ - No network/IO/list sorting inside `build`; subscriptions not created per frame.
21
+
22
+ ## State management
23
+
24
+ - Dependencies injected into cubits/notifiers/controllers — not constructed internally.
25
+ - Immutable snapshots (`copyWith`, freezed, records) for BLoC/Riverpod-style flows.
26
+ - Reactive stores mutate only through their API (`@action`, signal setters, etc.).
27
+ - Async flows expose distinct loading/success/error variants; UI handles all branches.
28
+ - Consumers scoped narrowly; selectors/`buildWhen`/`select` to limit rebuilds.
29
+ - Streams/`listen` canceled in `dispose`/`close`; timers cleared.
30
+ - Ephemeral UI stays local; shared state lifted minimally.
31
+
32
+ ## Performance
33
+
34
+ - Builder constructors for long lists; pagination when datasets grow.
35
+ - Images: cache + decode size (`cacheWidth`/`cacheHeight`); placeholders on failure.
36
+ - `RepaintBoundary` around independently animating subtrees.
37
+ - Avoid `Opacity` in animations — prefer fade transitions.
38
+
39
+ ## Navigation
40
+
41
+ - Single routing approach; typed parameters; guards not copy-pasted per screen.
42
+ - Deep links validated before navigation; back behavior verified on Android/iOS.
43
+
44
+ ## Security and data
45
+
46
+ - Secrets off-device or in secure storage; API keys via compile-time env, not source.
47
+ - HTTPS only; sanitize deep links; validate forms before API calls.
48
+ - No sensitive values in logs.
49
+
50
+ ## Testing and CI
51
+
52
+ - Unit coverage on domain/state; widget tests for interactions; integration for critical flows.
53
+ - State transition tests include error/retry paths.
54
+ - `flutter analyze` and tests block merge.
55
+
56
+ ## Accessibility and i18n (spot-check)
57
+
58
+ - Semantic labels on custom controls; 48×48 minimum taps; contrast ≥ 4.5:1 for body text.
59
+ - User strings through l10n; locale-aware dates/numbers.
60
+ - Full visual/a11y pass → **ui-design**; platform-native patterns → **native-ui**.
61
+
62
+ ## Dependencies
63
+
64
+ - Prefer maintained pub packages (pub points, recent releases, verified publisher).
65
+ - Caret constraints unless pin required; avoid production `dependency_overrides` without ticket.
66
+ - Monorepo: no `src/` imports across packages; workspace resolution for internals.
67
+
68
+ ## State library cheat sheet
69
+
70
+ | Concern | BLoC | Riverpod | Provider |
71
+ |---------|------|----------|----------|
72
+ | Container | Cubit/Bloc | Notifier | ChangeNotifier |
73
+ | UI hook | BlocBuilder | ConsumerWidget | Consumer |
74
+ | Narrow rebuild | BlocSelector | `.select` | Selector |
75
+ | Side effect | BlocListener | `ref.listen` | listener callback |
76
+ | Test | `blocTest` | `ProviderContainer` | direct instance |
@@ -0,0 +1,201 @@
1
+ # Flutter implementation patterns
2
+
3
+ ## Null safety and records
4
+
5
+ ```dart
6
+ String label(Account? account) => switch (account) {
7
+ Account(:final name, :final email) => '$name <$email>',
8
+ null => 'Guest',
9
+ };
10
+
11
+ Future<SummaryBundle> loadSummary(UserRepo users, OrderRepo orders) async {
12
+ final (people, purchases) = await (users.all(), orders.recent()).wait;
13
+ return SummaryBundle(users: people, orders: purchases);
14
+ }
15
+ ```
16
+
17
+ ## Immutable state
18
+
19
+ ```dart
20
+ sealed class LoadState<T> {}
21
+ final class Idle<T> extends LoadState<T> {}
22
+ final class Pending<T> extends LoadState<T> {}
23
+ final class Ready<T> extends LoadState<T> { const Ready(this.value); final T value; }
24
+ final class Failed<T> extends LoadState<T> { const Failed(this.reason); final Object reason; }
25
+
26
+ Widget body(LoadState<User> state) => switch (state) {
27
+ Idle() => const SizedBox.shrink(),
28
+ Pending() => const CircularProgressIndicator(),
29
+ Ready(:final value) => ProfileCard(user: value),
30
+ Failed(:final reason) => ErrorBanner(reason.toString()),
31
+ };
32
+ ```
33
+
34
+ `freezed` + json_serializable when you need `copyWith`/serialization without boilerplate.
35
+
36
+ ## Widget architecture
37
+
38
+ Isolate reactive subtrees:
39
+
40
+ ```dart
41
+ class DashboardPage extends StatelessWidget {
42
+ const DashboardPage({super.key});
43
+ @override
44
+ Widget build(BuildContext context) {
45
+ return const Scaffold(
46
+ body: Column(children: [
47
+ StaticHeader(),
48
+ _LiveCounter(),
49
+ StaticFooter(),
50
+ ]),
51
+ );
52
+ }
53
+ }
54
+
55
+ class _LiveCounter extends ConsumerWidget {
56
+ const _LiveCounter();
57
+ @override
58
+ Widget build(BuildContext context, WidgetRef ref) {
59
+ final n = ref.watch(counterProvider);
60
+ return Text('$n');
61
+ }
62
+ }
63
+ ```
64
+
65
+ ## BLoC sketch
66
+
67
+ ```dart
68
+ class SignInCubit extends Cubit<SignInState> {
69
+ SignInCubit(this._auth) : super(const SignInState.idle());
70
+ final AuthGateway _auth;
71
+
72
+ Future<void> submit(String email, String password) async {
73
+ emit(const SignInState.busy());
74
+ try {
75
+ final profile = await _auth.signIn(email, password);
76
+ emit(SignInState.done(profile));
77
+ } on AuthFailure catch (err) {
78
+ emit(SignInState.problem(err.message));
79
+ }
80
+ }
81
+ }
82
+ ```
83
+
84
+ ## Riverpod sketch
85
+
86
+ ```dart
87
+ @riverpod
88
+ Future<List<CatalogItem>> catalog(CatalogRef ref) async {
89
+ return ref.watch(catalogGatewayProvider).fetch();
90
+ }
91
+
92
+ @riverpod
93
+ class Basket extends _$Basket {
94
+ @override
95
+ List<BasketLine> build() => [];
96
+
97
+ void increment(CatalogItem item) {
98
+ final hit = state.where((l) => l.sku == item.id).firstOrNull;
99
+ state = hit == null
100
+ ? [...state, BasketLine(sku: item.id, qty: 1)]
101
+ : [for (final l in state) if (l.sku == item.id) l.copyWith(qty: l.qty + 1) else l];
102
+ }
103
+ }
104
+ ```
105
+
106
+ Derive totals with a separate provider; use `firstWhereOrNull` when joining optional catalogs.
107
+
108
+ ## GoRouter + auth
109
+
110
+ ```dart
111
+ final appRouter = GoRouter(
112
+ refreshListenable: GoRouterRefreshStream(signInCubit.stream),
113
+ redirect: (ctx, loc) {
114
+ final signedIn = ctx.read<SignInCubit>().state is SignInDone;
115
+ final onLogin = loc.matchedLocation == '/login';
116
+ if (!signedIn && !onLogin) return '/login';
117
+ if (signedIn && onLogin) return '/';
118
+ return null;
119
+ },
120
+ routes: [
121
+ GoRoute(path: '/login', builder: (_, __) => const LoginScreen()),
122
+ ShellRoute(
123
+ builder: (_, __, child) => AppScaffold(child: child),
124
+ routes: [
125
+ GoRoute(path: '/', builder: (_, __) => const HomeScreen()),
126
+ GoRoute(
127
+ path: '/item/:sku',
128
+ builder: (ctx, state) => ItemScreen(sku: state.pathParameters['sku']!),
129
+ ),
130
+ ],
131
+ ),
132
+ ],
133
+ );
134
+ ```
135
+
136
+ ## Dio client
137
+
138
+ ```dart
139
+ final client = Dio(BaseOptions(
140
+ baseUrl: const String.fromEnvironment('API_BASE'),
141
+ connectTimeout: const Duration(seconds: 10),
142
+ receiveTimeout: const Duration(seconds: 30),
143
+ ));
144
+
145
+ client.interceptors.add(InterceptorsWrapper(
146
+ onRequest: (opts, next) async {
147
+ final token = await vault.read('access');
148
+ if (token != null) opts.headers['Authorization'] = 'Bearer $token';
149
+ next.next(opts);
150
+ },
151
+ onError: (err, next) async {
152
+ final retried = err.requestOptions.extra['_retried'] == true;
153
+ if (!retried && err.response?.statusCode == 401 && await refreshTokens()) {
154
+ err.requestOptions.extra['_retried'] = true;
155
+ return next.resolve(await client.fetch(err.requestOptions));
156
+ }
157
+ next.next(err);
158
+ },
159
+ ));
160
+ ```
161
+
162
+ ## Errors in `main`
163
+
164
+ ```dart
165
+ void main() {
166
+ FlutterError.onError = (details) {
167
+ FlutterError.presentError(details);
168
+ reporter.recordFlutterFatalError(details);
169
+ };
170
+ PlatformDispatcher.instance.onError = (error, stack) {
171
+ reporter.recordError(error, stack, fatal: true);
172
+ return true;
173
+ };
174
+ runApp(const RootApp());
175
+ }
176
+ ```
177
+
178
+ Set `ErrorWidget.builder` in release for user-safe fallbacks.
179
+
180
+ ## Testing snippets
181
+
182
+ ```dart
183
+ blocTest<SignInCubit, SignInState>(
184
+ 'busy then problem on bad password',
185
+ build: () => SignInCubit(FakeAuth(reject: true)),
186
+ act: (c) => c.submit('a@b.c', 'bad'),
187
+ expect: () => [const SignInState.busy(), isA<SignInProblem>()],
188
+ );
189
+
190
+ testWidgets('badge count', (tester) async {
191
+ await tester.pumpWidget(
192
+ ProviderScope(
193
+ overrides: [basketProvider.overrideWith(() => FakeBasket(qty: 2))],
194
+ child: const MaterialApp(home: BasketBadge()),
195
+ ),
196
+ );
197
+ expect(find.text('2'), findsOneWidget);
198
+ });
199
+ ```
200
+
201
+ Use fakes over heavy mocks; test state transitions, not private fields.
@@ -0,0 +1,28 @@
1
+ ---
2
+ name: go
3
+ description: Idiomatic Go structure, errors, concurrency, and testing—table-driven tests, race detector, fuzzing, benchmarks. Use when writing or reviewing Go services, CLIs, packages, or `go test` / module layout.
4
+ ---
5
+
6
+ Go favors boring, obvious code: explicit errors, small interfaces at call sites, and concurrency tied to `context`. Pair with **atlas** for repo layout, **biblos** for stdlib and third-party APIs, **techne:services** for HTTP/API design, **techne:quality** for broader TDD gates, and **code-review** / **exo-qa** before merge.
7
+
8
+ ## Non-negotiable rules
9
+
10
+ 1. **Readability beats cleverness** — straight-line control flow; return early on errors so the happy path stays shallow.
11
+ 2. **Every error gets a decision** — wrap with `%w` and operation context; classify with `errors.Is` / `errors.As`; never assign to `_` unless documented (e.g. best-effort close).
12
+ 3. **Take interfaces, return structs** — define narrow interfaces where they are consumed, not in provider packages.
13
+ 4. **`context.Context` first** on RPC, DB, and HTTP paths — derive timeouts; propagate cancel; shut down with `Shutdown` and a bounded wait, not abrupt `Close` on servers.
14
+ 5. **Goroutines must finish** — tie work to context or wait groups; use buffered sends or `select` on `ctx.Done()` so cancelled callers cannot leak workers.
15
+ 6. **Zero values should work** — lazy-init maps/slices inside methods; avoid mutable package-level singletons; inject `*sql.DB`, loggers, and clients via constructors.
16
+ 7. **Preallocate when size is known** — `make([]T, 0, n)`; build strings with `strings.Builder` or `strings.Join` in hot loops.
17
+ 8. **Table-driven tests** — one `TestX` with `[]struct{ name, … }` and `t.Run`; copy loop variables before `t.Parallel()` subtests.
18
+ 9. **Helpers call `t.Helper()`** — register cleanup with `t.Cleanup`; use `t.TempDir`, `httptest`, and interface fakes instead of testing unexported symbols.
19
+ 10. **CI runs `go test -race ./...`** — cover critical paths toward 100%, public packages ≥90%, rest ≥80%; fuzz parsers and decoders where inputs are untrusted.
20
+ 11. **Gate merges with vet, staticcheck, golangci-lint** — `gofmt` / `goimports` on every change; `go mod tidy` before commit.
21
+ 12. **Functional options for optional config** — keep constructors stable; one receiver style (pointer or value) per type.
22
+
23
+ ## References
24
+
25
+ | File | Load when |
26
+ |------|-----------|
27
+ | [reference/patterns.md](reference/patterns.md) | Packages, errors, interfaces, concurrency, memory, tooling, anti-patterns |
28
+ | [reference/testing.md](reference/testing.md) | TDD loop, tables, mocks, golden files, HTTP tests, bench/fuzz, coverage |
@@ -0,0 +1,87 @@
1
+ # Go patterns
2
+
3
+ ## Layout and packages
4
+
5
+ Typical service repo: `cmd/<app>/main.go`, `internal/` for private app code, `pkg/` only for libraries meant for external importers, `api/` for OpenAPI/proto, `testdata/` for fixtures. Package names: short, lowercase, no `util` dumping grounds.
6
+
7
+ Inject dependencies through structs and constructors—do not open DB pools in `init()` from environment variables.
8
+
9
+ ## Errors
10
+
11
+ Sentinel vars for stable domain cases (`ErrNotFound`). Typed errors when callers need fields. Wrap at each layer with a short verb phrase:
12
+
13
+ ```go
14
+ if err != nil {
15
+ return nil, fmt.Errorf("load profile %q: %w", id, err)
16
+ }
17
+ ```
18
+
19
+ Prefer early return over nested `if err != nil`.
20
+
21
+ ## Interfaces
22
+
23
+ Keep interfaces tiny (often one method). Consumer packages declare what they need:
24
+
25
+ ```go
26
+ type Ledger interface {
27
+ Post(ctx context.Context, entry Entry) error
28
+ }
29
+ ```
30
+
31
+ Optional behavior: type assert to a secondary interface (e.g. `Flusher`) instead of widening the base API.
32
+
33
+ ## Concurrency
34
+
35
+ **Worker pool:** fixed goroutines reading `jobs` until closed; `WaitGroup` for drain.
36
+
37
+ **Fan-out:** `errgroup.WithContext` cancels siblings on first error; capture loop indices before `g.Go`.
38
+
39
+ **HTTP client:** `NewRequestWithContext`, always `defer resp.Body.Close()`, set timeouts on the client or context.
40
+
41
+ **Shutdown:** trap `SIGINT`/`SIGTERM`, `Shutdown` with ~30s context, then exit.
42
+
43
+ Avoid sending on unbuffered channels without a receiver; prefer buffer size 1 plus cancel branch when exposing async helpers.
44
+
45
+ ## Struct patterns
46
+
47
+ **Functional options:** `type Option func(*Server)` with defaults inside `New`, variadic `opts ...Option`.
48
+
49
+ **Embedding:** compose behavior (logging, metrics) without deep inheritance trees.
50
+
51
+ ## Performance habits
52
+
53
+ | Situation | Approach |
54
+ |-----------|----------|
55
+ | Known output count | Pre-sized slice |
56
+ | Repeated temp buffers | `sync.Pool` with reset in defer |
57
+ | String assembly in loop | `strings.Builder` |
58
+ | Map/set membership hot path | `map[T]struct{}` |
59
+
60
+ Profile before `sync.Pool`; misuse adds complexity.
61
+
62
+ ## Tooling
63
+
64
+ ```bash
65
+ go build ./...
66
+ go test -race -cover ./...
67
+ go vet ./...
68
+ staticcheck ./...
69
+ golangci-lint run
70
+ go mod tidy && go mod verify
71
+ gofmt -w . && goimports -w .
72
+ ```
73
+
74
+ Enable errcheck, staticcheck, govet (shadow), ineffassign in CI linter config.
75
+
76
+ ## Anti-patterns
77
+
78
+ | Avoid | Prefer |
79
+ |-------|--------|
80
+ | `panic` for expected errors | Return `error` |
81
+ | Context stored on structs | Context as first param |
82
+ | Naked returns in long funcs | Named returns only when signature is tiny |
83
+ | Mixed value/pointer receivers | One style per type |
84
+ | Returning `interface{}` from domain APIs | Concrete structs |
85
+ | Global `var db *sql.DB` | Struct field + constructor |
86
+
87
+ Cross-stack HTTP and middleware conventions → **techne:services**.
@@ -0,0 +1,142 @@
1
+ # Go testing
2
+
3
+ ## TDD loop
4
+
5
+ 1. Sketch signature or interface.
6
+ 2. Write failing test (table row or subtest).
7
+ 3. Minimal implementation until green.
8
+ 4. Refactor with `-race` still passing.
9
+
10
+ Broader red-green discipline → **techne:quality**.
11
+
12
+ ## Table-driven template
13
+
14
+ ```go
15
+ func TestNormalizeEmail(t *testing.T) {
16
+ cases := []struct {
17
+ name string
18
+ in string
19
+ want string
20
+ err bool
21
+ }{
22
+ {"trim lower", " A@B.com ", "a@b.com", false},
23
+ {"empty", "", "", true},
24
+ }
25
+ for _, tc := range cases {
26
+ t.Run(tc.name, func(t *testing.T) {
27
+ got, err := NormalizeEmail(tc.in)
28
+ if tc.err {
29
+ if err == nil {
30
+ t.Fatal("expected error")
31
+ }
32
+ return
33
+ }
34
+ if err != nil {
35
+ t.Fatalf("unexpected: %v", err)
36
+ }
37
+ if got != tc.want {
38
+ t.Fatalf("got %q want %q", got, tc.want)
39
+ }
40
+ })
41
+ }
42
+ }
43
+ ```
44
+
45
+ Use `reflect.DeepEqual` only when no clearer field asserts exist.
46
+
47
+ ## Organization
48
+
49
+ - Group related flows under `t.Run` blocks sharing setup.
50
+ - `t.Parallel()` only when cases do not share mutable fixtures.
51
+ - Helpers: `t.Helper()`, fail with `t.Fatalf`, register `t.Cleanup` for closes.
52
+
53
+ ## Golden files
54
+
55
+ Store expected bytes under `testdata/*.golden`. Gate updates behind a flag:
56
+
57
+ ```go
58
+ var updateGoldens = flag.Bool("update", false, "rewrite golden files")
59
+
60
+ if *updateGoldens {
61
+ os.WriteFile(goldenPath, got, 0o644)
62
+ }
63
+ ```
64
+
65
+ Run `go test -update` locally; never commit refreshed goldens without reviewing diff.
66
+
67
+ ## Mocks
68
+
69
+ Define small interfaces in the consumer package; tests supply stub structs with function fields:
70
+
71
+ ```go
72
+ type stubStore struct {
73
+ load func(id string) (*User, error)
74
+ }
75
+ func (s stubStore) Load(id string) (*User, error) { return s.load(id) }
76
+ ```
77
+
78
+ Prefer real sqlite/postgres test containers for integration paths when feasible.
79
+
80
+ ## HTTP handlers
81
+
82
+ ```go
83
+ req := httptest.NewRequest(http.MethodGet, "/health", nil)
84
+ rec := httptest.NewRecorder()
85
+ Handler(rec, req)
86
+ if rec.Code != http.StatusOK {
87
+ t.Fatalf("status %d", rec.Code)
88
+ }
89
+ ```
90
+
91
+ Table-drive method, path, body, expected status and JSON snippets.
92
+
93
+ ## Benchmarks and fuzz
94
+
95
+ ```go
96
+ func BenchmarkEncode(b *testing.B) {
97
+ payload := mkPayload(1024)
98
+ b.ReportAllocs()
99
+ for i := 0; i < b.N; i++ {
100
+ _, _ = Encode(payload)
101
+ }
102
+ }
103
+ ```
104
+
105
+ Run `go test -bench=. -benchmem`. Fuzz decoders with seed corpus plus `go test -fuzz=FuzzDecode -fuzztime=30s`; assert invariants (roundtrip, no panic on reject).
106
+
107
+ ## Coverage
108
+
109
+ ```bash
110
+ go test -race -coverprofile=coverage.out ./...
111
+ go tool cover -func=coverage.out
112
+ go tool cover -html=coverage.out
113
+ ```
114
+
115
+ | Layer | Target |
116
+ |-------|--------|
117
+ | Money / auth / invariants | 100% |
118
+ | Exported API | ≥90% |
119
+ | Everything else | ≥80% |
120
+
121
+ Exclude generated mocks from coverage via build tags when needed.
122
+
123
+ ## Commands cheat sheet
124
+
125
+ ```bash
126
+ go test ./...
127
+ go test -run TestUser/Create ./...
128
+ go test -short ./...
129
+ go test -count=10 ./... # flake hunt
130
+ go test -timeout 30s ./...
131
+ ```
132
+
133
+ ## Practices
134
+
135
+ | Do | Skip |
136
+ |----|------|
137
+ | Assert behavior through public API | Importing `_test` packages to poke privates |
138
+ | `t.Cleanup` for files and servers | `time.Sleep` for readiness—poll or channels |
139
+ | Descriptive subtest names | Ignoring flaky tests |
140
+ | Error-path table rows | Mocking every leaf when one integration test suffices |
141
+
142
+ Security-sensitive parsing → add fuzz + **security-review** / **exo-security** pass.