groundwork-method 0.0.1 → 0.10.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 (629) hide show
  1. package/CHANGELOG.md +781 -0
  2. package/LICENSE +21 -0
  3. package/README.md +44 -29
  4. package/bin/groundwork.js +1654 -0
  5. package/dist/src/generators/add-capability/generator.d.ts +8 -0
  6. package/dist/src/generators/add-capability/generator.js +60 -0
  7. package/dist/src/generators/add-capability/generator.js.map +1 -0
  8. package/dist/src/generators/cli-app/generator.d.ts +9 -0
  9. package/dist/src/generators/cli-app/generator.js +140 -0
  10. package/dist/src/generators/cli-app/generator.js.map +1 -0
  11. package/dist/src/generators/docs-site/generator.d.ts +5 -0
  12. package/dist/src/generators/docs-site/generator.js +441 -0
  13. package/dist/src/generators/docs-site/generator.js.map +1 -0
  14. package/dist/src/generators/electron-app/generator.d.ts +6 -0
  15. package/dist/src/generators/electron-app/generator.js +261 -0
  16. package/dist/src/generators/electron-app/generator.js.map +1 -0
  17. package/dist/src/generators/flutter-app/generator.d.ts +6 -0
  18. package/dist/src/generators/flutter-app/generator.js +314 -0
  19. package/dist/src/generators/flutter-app/generator.js.map +1 -0
  20. package/dist/src/generators/go-microservice/generator.d.ts +8 -0
  21. package/dist/src/generators/go-microservice/generator.js +232 -0
  22. package/dist/src/generators/go-microservice/generator.js.map +1 -0
  23. package/dist/src/generators/nextjs-app/generator.d.ts +8 -0
  24. package/dist/src/generators/nextjs-app/generator.js +294 -0
  25. package/dist/src/generators/nextjs-app/generator.js.map +1 -0
  26. package/dist/src/generators/python-microservice/generator.d.ts +13 -0
  27. package/dist/src/generators/python-microservice/generator.js +265 -0
  28. package/dist/src/generators/python-microservice/generator.js.map +1 -0
  29. package/dist/src/generators/shared/brand-tokens.d.ts +89 -0
  30. package/dist/src/generators/shared/brand-tokens.js +308 -0
  31. package/dist/src/generators/shared/brand-tokens.js.map +1 -0
  32. package/dist/src/generators/shared/capabilities.d.ts +101 -0
  33. package/dist/src/generators/shared/capabilities.js +279 -0
  34. package/dist/src/generators/shared/capabilities.js.map +1 -0
  35. package/dist/src/generators/shared/provenance.d.ts +2 -0
  36. package/dist/src/generators/shared/provenance.js +85 -0
  37. package/dist/src/generators/shared/provenance.js.map +1 -0
  38. package/dist/src/generators/shared/scaffold-helpers.d.ts +72 -0
  39. package/dist/src/generators/shared/scaffold-helpers.js +309 -0
  40. package/dist/src/generators/shared/scaffold-helpers.js.map +1 -0
  41. package/dist/src/generators/system-test-runner/generator.d.ts +23 -0
  42. package/dist/src/generators/system-test-runner/generator.js +125 -0
  43. package/dist/src/generators/system-test-runner/generator.js.map +1 -0
  44. package/dist/src/generators/workspace-dev-cli/generator.d.ts +7 -0
  45. package/dist/src/generators/workspace-dev-cli/generator.js +138 -0
  46. package/dist/src/generators/workspace-dev-cli/generator.js.map +1 -0
  47. package/generators.json +57 -0
  48. package/lib/repo-map/grammars/tree-sitter-c.wasm +0 -0
  49. package/lib/repo-map/grammars/tree-sitter-cpp.wasm +0 -0
  50. package/lib/repo-map/grammars/tree-sitter-csharp.wasm +0 -0
  51. package/lib/repo-map/grammars/tree-sitter-dart.wasm +0 -0
  52. package/lib/repo-map/grammars/tree-sitter-go.wasm +0 -0
  53. package/lib/repo-map/grammars/tree-sitter-java.wasm +0 -0
  54. package/lib/repo-map/grammars/tree-sitter-javascript.wasm +0 -0
  55. package/lib/repo-map/grammars/tree-sitter-kotlin.wasm +0 -0
  56. package/lib/repo-map/grammars/tree-sitter-lua.wasm +0 -0
  57. package/lib/repo-map/grammars/tree-sitter-php.wasm +0 -0
  58. package/lib/repo-map/grammars/tree-sitter-python.wasm +0 -0
  59. package/lib/repo-map/grammars/tree-sitter-ruby.wasm +0 -0
  60. package/lib/repo-map/grammars/tree-sitter-rust.wasm +0 -0
  61. package/lib/repo-map/grammars/tree-sitter-scala.wasm +0 -0
  62. package/lib/repo-map/grammars/tree-sitter-swift.wasm +0 -0
  63. package/lib/repo-map/grammars/tree-sitter-tsx.wasm +0 -0
  64. package/lib/repo-map/grammars/tree-sitter-typescript.wasm +0 -0
  65. package/lib/repo-map/index.js +386 -0
  66. package/lib/repo-map/languages.js +514 -0
  67. package/lib/repo-map/pagerank.js +59 -0
  68. package/migrations/README.md +60 -0
  69. package/migrations/_template/cli-migration.js +27 -0
  70. package/migrations/gw-bet-prose-redesign.js +105 -0
  71. package/migrations/gw-drop-test-manifest.js +37 -0
  72. package/migrations/gw-register-serena-mcp.js +42 -0
  73. package/migrations/gw-relocate-hidden-skills.js +40 -0
  74. package/migrations/gw-seed-config-toml.js +24 -0
  75. package/migrations/index.json +40 -0
  76. package/package.json +70 -6
  77. package/src/AGENTS.md +36 -0
  78. package/src/config/config.toml +30 -0
  79. package/src/config/groundwork-state.json +5 -0
  80. package/src/docs/llms.txt +72 -0
  81. package/src/docs/principles/ai-native/agent-native-systems.md +90 -0
  82. package/src/docs/principles/ai-native/agentic-systems.md +78 -0
  83. package/src/docs/principles/ai-native/ai-engineering.md +100 -0
  84. package/src/docs/principles/ai-native/ai-native-product.md +76 -0
  85. package/src/docs/principles/delivery/cost-engineering.md +89 -0
  86. package/src/docs/principles/delivery/day-2-operational-baseline.md +57 -0
  87. package/src/docs/principles/delivery/devex.md +88 -0
  88. package/src/docs/principles/delivery/platform.md +101 -0
  89. package/src/docs/principles/delivery/progressive-delivery.md +92 -0
  90. package/src/docs/principles/design/ai-native-design.md +73 -0
  91. package/src/docs/principles/design/design-foundations.md +80 -0
  92. package/src/docs/principles/design/design-systems-and-tokens.md +72 -0
  93. package/src/docs/principles/design/interaction-and-motion.md +69 -0
  94. package/src/docs/principles/design/layout-and-space.md +72 -0
  95. package/src/docs/principles/design/usability-and-ux.md +68 -0
  96. package/src/docs/principles/design/visual-design.md +84 -0
  97. package/src/docs/principles/foundations/code-craft.md +86 -0
  98. package/src/docs/principles/foundations/continuous-discovery.md +75 -0
  99. package/src/docs/principles/foundations/documentation.md +102 -0
  100. package/src/docs/principles/foundations/prioritization-and-appetite.md +78 -0
  101. package/src/docs/principles/foundations/product-engineering.md +90 -0
  102. package/src/docs/principles/foundations/product-risks.md +89 -0
  103. package/src/docs/principles/foundations/requirements-and-specs.md +80 -0
  104. package/src/docs/principles/foundations/success-metrics.md +66 -0
  105. package/src/docs/principles/foundations/testing.md +82 -0
  106. package/src/docs/principles/index.md +23 -0
  107. package/src/docs/principles/quality/accessibility.md +88 -0
  108. package/src/docs/principles/quality/observability.md +84 -0
  109. package/src/docs/principles/quality/performance.md +84 -0
  110. package/src/docs/principles/quality/privacy.md +92 -0
  111. package/src/docs/principles/quality/reliability.md +89 -0
  112. package/src/docs/principles/quality/security.md +78 -0
  113. package/src/docs/principles/stack/postgres.md +100 -0
  114. package/src/docs/principles/system-design/api-design.md +86 -0
  115. package/src/docs/principles/system-design/architecture-decisions.md +81 -0
  116. package/src/docs/principles/system-design/code-structure.md +104 -0
  117. package/src/docs/principles/system-design/data-engineering.md +87 -0
  118. package/src/docs/principles/system-design/durable-execution.md +89 -0
  119. package/src/docs/principles/system-design/evolutionary-architecture.md +81 -0
  120. package/src/docs/principles/system-design/identity-and-access.md +76 -0
  121. package/src/docs/principles/system-design/integration-patterns.md +84 -0
  122. package/src/docs/principles/system-design/real-time.md +83 -0
  123. package/src/docs/principles/system-design/surface-architecture.md +74 -0
  124. package/src/docs/ways-of-working/documentation.md +69 -0
  125. package/src/docs/ways-of-working/how-we-work.md +76 -0
  126. package/src/docs/ways-of-working/units-of-work.md +40 -0
  127. package/src/engineer-skills/groundwork-electron-engineer/SKILL.md +118 -0
  128. package/src/engineer-skills/groundwork-electron-engineer/references/ipc-contracts.md +138 -0
  129. package/src/engineer-skills/groundwork-electron-engineer/references/packaging-and-updates.md +82 -0
  130. package/src/engineer-skills/groundwork-electron-engineer/references/process-model.md +94 -0
  131. package/src/engineer-skills/groundwork-electron-engineer/references/security.md +107 -0
  132. package/src/engineer-skills/groundwork-electron-engineer/references/testing-and-smoke.md +107 -0
  133. package/src/engineer-skills/groundwork-electron-engineer/references/theming-and-tokens.md +74 -0
  134. package/src/engineer-skills/groundwork-electron-engineer/sync-anchor.md +14 -0
  135. package/src/engineer-skills/groundwork-flutter-engineer/SKILL.md +108 -0
  136. package/src/engineer-skills/groundwork-flutter-engineer/references/accessibility.md +92 -0
  137. package/src/engineer-skills/groundwork-flutter-engineer/references/architecture.md +189 -0
  138. package/src/engineer-skills/groundwork-flutter-engineer/references/data-and-contracts.md +136 -0
  139. package/src/engineer-skills/groundwork-flutter-engineer/references/navigation.md +122 -0
  140. package/src/engineer-skills/groundwork-flutter-engineer/references/platform-channels.md +93 -0
  141. package/src/engineer-skills/groundwork-flutter-engineer/references/releases-and-distribution.md +84 -0
  142. package/src/engineer-skills/groundwork-flutter-engineer/references/state-management.md +166 -0
  143. package/src/engineer-skills/groundwork-flutter-engineer/references/testing.md +135 -0
  144. package/src/engineer-skills/groundwork-flutter-engineer/references/theming-and-design-tokens.md +109 -0
  145. package/src/engineer-skills/groundwork-flutter-engineer/references/widgets-and-composition.md +123 -0
  146. package/src/engineer-skills/groundwork-flutter-engineer/sync-anchor.md +15 -0
  147. package/src/engineer-skills/groundwork-go-engineer/SKILL.md +171 -0
  148. package/src/engineer-skills/groundwork-go-engineer/references/api-design.md +82 -0
  149. package/src/engineer-skills/groundwork-go-engineer/references/architecture.md +42 -0
  150. package/src/engineer-skills/groundwork-go-engineer/references/capability-ports.md +50 -0
  151. package/src/engineer-skills/groundwork-go-engineer/references/code-craft-security.md +34 -0
  152. package/src/engineer-skills/groundwork-go-engineer/references/concurrency.md +108 -0
  153. package/src/engineer-skills/groundwork-go-engineer/references/go-services.md +77 -0
  154. package/src/engineer-skills/groundwork-go-engineer/references/http-handlers.md +172 -0
  155. package/src/engineer-skills/groundwork-go-engineer/references/implementation-patterns.md +156 -0
  156. package/src/engineer-skills/groundwork-go-engineer/references/integration-realtime-data.md +57 -0
  157. package/src/engineer-skills/groundwork-go-engineer/references/observability.md +49 -0
  158. package/src/engineer-skills/groundwork-go-engineer/references/postgres.md +41 -0
  159. package/src/engineer-skills/groundwork-go-engineer/references/reliability-performance.md +105 -0
  160. package/src/engineer-skills/groundwork-go-engineer/references/testing.md +139 -0
  161. package/src/engineer-skills/groundwork-go-engineer/sync-anchor.md +11 -0
  162. package/src/engineer-skills/groundwork-nextjs-engineer/SKILL.md +107 -0
  163. package/src/engineer-skills/groundwork-nextjs-engineer/references/architecture.md +323 -0
  164. package/src/engineer-skills/groundwork-nextjs-engineer/references/data-fetching.md +458 -0
  165. package/src/engineer-skills/groundwork-nextjs-engineer/references/documentation.md +324 -0
  166. package/src/engineer-skills/groundwork-nextjs-engineer/references/error-boundaries.md +383 -0
  167. package/src/engineer-skills/groundwork-nextjs-engineer/references/mutations-and-forms.md +396 -0
  168. package/src/engineer-skills/groundwork-nextjs-engineer/references/performance-and-deployment.md +947 -0
  169. package/src/engineer-skills/groundwork-nextjs-engineer/references/routing-and-navigation.md +405 -0
  170. package/src/engineer-skills/groundwork-nextjs-engineer/references/server-components.md +394 -0
  171. package/src/engineer-skills/groundwork-nextjs-engineer/references/tailwind-and-styling.md +134 -0
  172. package/src/engineer-skills/groundwork-nextjs-engineer/references/testing.md +433 -0
  173. package/src/engineer-skills/groundwork-nextjs-engineer/references/type-system.md +368 -0
  174. package/src/engineer-skills/groundwork-nextjs-engineer/references/ux-principles.md +278 -0
  175. package/src/engineer-skills/groundwork-nextjs-engineer/references/visual-language.md +69 -0
  176. package/src/engineer-skills/groundwork-nextjs-engineer/sync-anchor.md +9 -0
  177. package/src/engineer-skills/groundwork-python-engineer/SKILL.md +196 -0
  178. package/src/engineer-skills/groundwork-python-engineer/references/api-standards.md +88 -0
  179. package/src/engineer-skills/groundwork-python-engineer/references/architecture.md +57 -0
  180. package/src/engineer-skills/groundwork-python-engineer/references/async-patterns.md +103 -0
  181. package/src/engineer-skills/groundwork-python-engineer/references/capability-ports.md +44 -0
  182. package/src/engineer-skills/groundwork-python-engineer/references/database.md +88 -0
  183. package/src/engineer-skills/groundwork-python-engineer/references/documentation-mcp.md +167 -0
  184. package/src/engineer-skills/groundwork-python-engineer/references/implementation-patterns.md +166 -0
  185. package/src/engineer-skills/groundwork-python-engineer/references/ml-pipelines.md +119 -0
  186. package/src/engineer-skills/groundwork-python-engineer/references/ml-systems-ai-engineering.md +74 -0
  187. package/src/engineer-skills/groundwork-python-engineer/references/observability.md +57 -0
  188. package/src/engineer-skills/groundwork-python-engineer/references/resilience.md +126 -0
  189. package/src/engineer-skills/groundwork-python-engineer/references/testing.md +177 -0
  190. package/src/engineer-skills/groundwork-python-engineer/sync-anchor.md +13 -0
  191. package/src/generators/add-capability/generator.ts +70 -0
  192. package/src/generators/add-capability/schema.json +30 -0
  193. package/src/generators/capabilities/llm/capability.json +28 -0
  194. package/src/generators/capabilities/llm/providers/anthropic/footprint.json +13 -0
  195. package/src/generators/capabilities/llm/providers/anthropic/stacks/go/internal/llm/llm.go.template +102 -0
  196. package/src/generators/capabilities/llm/providers/anthropic/stacks/python/src/__packageName__/adapters/llm.py.template +61 -0
  197. package/src/generators/capabilities/llm/providers/local/footprint.json +13 -0
  198. package/src/generators/capabilities/llm/providers/local/stacks/go/internal/llm/llm.go.template +102 -0
  199. package/src/generators/capabilities/llm/providers/local/stacks/python/src/__packageName__/adapters/llm.py.template +53 -0
  200. package/src/generators/capabilities/llm/providers/localai/footprint.json +29 -0
  201. package/src/generators/capabilities/llm/providers/localai/stacks/go/internal/llm/llm.go.template +102 -0
  202. package/src/generators/capabilities/llm/providers/localai/stacks/python/src/__packageName__/adapters/llm.py.template +53 -0
  203. package/src/generators/capabilities/llm/providers/none/footprint.json +9 -0
  204. package/src/generators/capabilities/llm/providers/none/stacks/go/internal/llm/llm.go.template +35 -0
  205. package/src/generators/capabilities/llm/providers/none/stacks/python/src/__packageName__/adapters/llm.py.template +25 -0
  206. package/src/generators/capabilities/llm/providers/ollama/footprint.json +20 -0
  207. package/src/generators/capabilities/llm/providers/ollama/stacks/go/internal/llm/llm.go.template +102 -0
  208. package/src/generators/capabilities/llm/providers/ollama/stacks/python/src/__packageName__/adapters/llm.py.template +53 -0
  209. package/src/generators/capabilities/llm/providers/openai/footprint.json +13 -0
  210. package/src/generators/capabilities/llm/providers/openai/stacks/go/internal/llm/llm.go.template +98 -0
  211. package/src/generators/capabilities/llm/providers/openai/stacks/python/src/__packageName__/adapters/llm.py.template +60 -0
  212. package/src/generators/capabilities/llm/stacks/go/internal/core/service/llm.go.template +12 -0
  213. package/src/generators/capabilities/llm/stacks/go/internal/llm/llm_test.go.template +33 -0
  214. package/src/generators/capabilities/llm/stacks/python/src/__packageName__/core/llm.py.template +15 -0
  215. package/src/generators/capabilities/llm/stacks/python/tests/contracts/test_llm.py.template +37 -0
  216. package/src/generators/cli-app/files/README.md.template +76 -0
  217. package/src/generators/cli-app/files/build.mjs.template +15 -0
  218. package/src/generators/cli-app/files/package.json.template +21 -0
  219. package/src/generators/cli-app/files/src/cli.ts.template +67 -0
  220. package/src/generators/cli-app/files/src/commands/hello.ts.template +17 -0
  221. package/src/generators/cli-app/files/src/commands/status.ts.template +23 -0
  222. package/src/generators/cli-app/files/src/core/client.test.ts.template +80 -0
  223. package/src/generators/cli-app/files/src/core/client.ts.template +64 -0
  224. package/src/generators/cli-app/files/src/registry.test.ts.template +35 -0
  225. package/src/generators/cli-app/files/src/registry.ts.template +31 -0
  226. package/src/generators/cli-app/files/tsconfig.json.template +16 -0
  227. package/src/generators/cli-app/files/tsconfig.test.json.template +11 -0
  228. package/src/generators/cli-app/generator.ts +138 -0
  229. package/src/generators/cli-app/schema.json +24 -0
  230. package/src/generators/docs-site/files/.gitignore.ejs +40 -0
  231. package/src/generators/docs-site/files/app/docs/__slug__/page.tsx +101 -0
  232. package/src/generators/docs-site/files/app/docs/layout.tsx +14 -0
  233. package/src/generators/docs-site/files/app/docs.css +43 -0
  234. package/src/generators/docs-site/files/app/layout.tsx +24 -0
  235. package/src/generators/docs-site/files/app/page.tsx +135 -0
  236. package/src/generators/docs-site/files/app/source.ts +8 -0
  237. package/src/generators/docs-site/files/components/mermaid.tsx +67 -0
  238. package/src/generators/docs-site/files/next.config.mjs +10 -0
  239. package/src/generators/docs-site/files/package.json +32 -0
  240. package/src/generators/docs-site/files/pnpm-workspace.yaml +7 -0
  241. package/src/generators/docs-site/files/postcss.config.mjs +6 -0
  242. package/src/generators/docs-site/files/source.config.ts +77 -0
  243. package/src/generators/docs-site/files/tailwind.config.js +10 -0
  244. package/src/generators/docs-site/files/tsconfig.json +27 -0
  245. package/src/generators/docs-site/generator.ts +476 -0
  246. package/src/generators/docs-site/schema.json +17 -0
  247. package/src/generators/electron-app/docs/principles/stack/electron/index.md +47 -0
  248. package/src/generators/electron-app/docs/principles/stack/electron/ipc-contracts.md +71 -0
  249. package/src/generators/electron-app/docs/principles/stack/electron/packaging-and-updates.md +59 -0
  250. package/src/generators/electron-app/docs/principles/stack/electron/process-model.md +53 -0
  251. package/src/generators/electron-app/docs/principles/stack/electron/security.md +70 -0
  252. package/src/generators/electron-app/docs/principles/stack/typescript/frontend.md +65 -0
  253. package/src/generators/electron-app/files/.gitignore.template +20 -0
  254. package/src/generators/electron-app/files/README.md.template +125 -0
  255. package/src/generators/electron-app/files/electron.vite.config.ts +31 -0
  256. package/src/generators/electron-app/files/eslint.config.mjs +92 -0
  257. package/src/generators/electron-app/files/forge.config.ts.template +44 -0
  258. package/src/generators/electron-app/files/package.json.template +54 -0
  259. package/src/generators/electron-app/files/playwright.config.ts +18 -0
  260. package/src/generators/electron-app/files/project.json.template +65 -0
  261. package/src/generators/electron-app/files/src/main/core-client.test.ts +81 -0
  262. package/src/generators/electron-app/files/src/main/core-client.ts +55 -0
  263. package/src/generators/electron-app/files/src/main/index.ts +157 -0
  264. package/src/generators/electron-app/files/src/main/ipc.ts +52 -0
  265. package/src/generators/electron-app/files/src/main/policy.test.ts +71 -0
  266. package/src/generators/electron-app/files/src/main/policy.ts +73 -0
  267. package/src/generators/electron-app/files/src/preload/index.ts +23 -0
  268. package/src/generators/electron-app/files/src/renderer/index.html.template +20 -0
  269. package/src/generators/electron-app/files/src/renderer/src/App.test.tsx +61 -0
  270. package/src/generators/electron-app/files/src/renderer/src/App.tsx.template +43 -0
  271. package/src/generators/electron-app/files/src/renderer/src/assets/main.css +40 -0
  272. package/src/generators/electron-app/files/src/renderer/src/env.d.ts +14 -0
  273. package/src/generators/electron-app/files/src/renderer/src/main.tsx +25 -0
  274. package/src/generators/electron-app/files/src/shared/ipc.ts +54 -0
  275. package/src/generators/electron-app/files/tests/smoke/app.spec.ts.template +68 -0
  276. package/src/generators/electron-app/files/tool/electron_exec.sh.template +83 -0
  277. package/src/generators/electron-app/files/tsconfig.json +7 -0
  278. package/src/generators/electron-app/files/tsconfig.node.json +27 -0
  279. package/src/generators/electron-app/files/tsconfig.web.json +22 -0
  280. package/src/generators/electron-app/files/vitest.config.ts +32 -0
  281. package/src/generators/electron-app/files/vitest.setup.ts +1 -0
  282. package/src/generators/electron-app/generator.ts +288 -0
  283. package/src/generators/electron-app/schema.json +23 -0
  284. package/src/generators/flutter-app/docs/principles/stack/flutter/architecture.md +78 -0
  285. package/src/generators/flutter-app/docs/principles/stack/flutter/index.md +38 -0
  286. package/src/generators/flutter-app/docs/principles/stack/flutter/platform-channels.md +51 -0
  287. package/src/generators/flutter-app/docs/principles/stack/flutter/releases-and-distribution.md +59 -0
  288. package/src/generators/flutter-app/docs/principles/stack/flutter/state-management.md +85 -0
  289. package/src/generators/flutter-app/docs/principles/stack/flutter/testing.md +74 -0
  290. package/src/generators/flutter-app/docs/principles/stack/flutter/widgets-and-composition.md +69 -0
  291. package/src/generators/flutter-app/files/.gitignore.template +30 -0
  292. package/src/generators/flutter-app/files/README.md.template +100 -0
  293. package/src/generators/flutter-app/files/analysis_options.yaml.template +18 -0
  294. package/src/generators/flutter-app/files/integration_test/app_test.dart.template +30 -0
  295. package/src/generators/flutter-app/files/lib/app.dart.template +24 -0
  296. package/src/generators/flutter-app/files/lib/config/app_config.dart +15 -0
  297. package/src/generators/flutter-app/files/lib/data/repositories/status_repository.dart +36 -0
  298. package/src/generators/flutter-app/files/lib/data/services/api_client.dart +71 -0
  299. package/src/generators/flutter-app/files/lib/domain/models/health_status.dart +23 -0
  300. package/src/generators/flutter-app/files/lib/main.dart +11 -0
  301. package/src/generators/flutter-app/files/lib/router.dart +23 -0
  302. package/src/generators/flutter-app/files/lib/ui/core/theme/app_theme.dart +110 -0
  303. package/src/generators/flutter-app/files/lib/ui/home/home_view.dart +89 -0
  304. package/src/generators/flutter-app/files/lib/ui/home/home_view_model.dart.template +38 -0
  305. package/src/generators/flutter-app/files/project.json.template +51 -0
  306. package/src/generators/flutter-app/files/pubspec.yaml.template +47 -0
  307. package/src/generators/flutter-app/files/test/api_client_test.dart.template +63 -0
  308. package/src/generators/flutter-app/files/test/fakes/fake_status_repository.dart.template +19 -0
  309. package/src/generators/flutter-app/files/test/home_view_test.dart.template +58 -0
  310. package/src/generators/flutter-app/files/tool/flutter_exec.sh.template +60 -0
  311. package/src/generators/flutter-app/generator.ts +362 -0
  312. package/src/generators/flutter-app/schema.json +23 -0
  313. package/src/generators/go-microservice/docs/principles/stack/go/concurrency.md +123 -0
  314. package/src/generators/go-microservice/docs/principles/stack/go/index.md +70 -0
  315. package/src/generators/go-microservice/docs/principles/stack/go/testing.md +152 -0
  316. package/src/generators/go-microservice/files/.air.toml.template +38 -0
  317. package/src/generators/go-microservice/files/.env.template +4 -0
  318. package/src/generators/go-microservice/files/.golangci.yml.template +82 -0
  319. package/src/generators/go-microservice/files/Dockerfile.dev.template +12 -0
  320. package/src/generators/go-microservice/files/asyncapi-pubsub.yaml.template +33 -0
  321. package/src/generators/go-microservice/files/asyncapi-ws.yaml.template +34 -0
  322. package/src/generators/go-microservice/files/cmd/api/main.go.template +149 -0
  323. package/src/generators/go-microservice/files/cmd/api/main_test.go.template +99 -0
  324. package/src/generators/go-microservice/files/cmd/worker/cleanup/main.go.template +39 -0
  325. package/src/generators/go-microservice/files/db/schema.sql.template +24 -0
  326. package/src/generators/go-microservice/files/go.mod.template +39 -0
  327. package/src/generators/go-microservice/files/internal/config/config.go.template +52 -0
  328. package/src/generators/go-microservice/files/internal/config/otel.go.template +93 -0
  329. package/src/generators/go-microservice/files/internal/core/domain/errors.go.template +16 -0
  330. package/src/generators/go-microservice/files/internal/core/domain/model.go.template +28 -0
  331. package/src/generators/go-microservice/files/internal/core/domain/user.go.template +13 -0
  332. package/src/generators/go-microservice/files/internal/core/pagination.go.template +16 -0
  333. package/src/generators/go-microservice/files/internal/core/service/app_service.go.template +79 -0
  334. package/src/generators/go-microservice/files/internal/core/service/event_hub.go.template +9 -0
  335. package/src/generators/go-microservice/files/internal/core/service/message_queue.go.template +10 -0
  336. package/src/generators/go-microservice/files/internal/core/service/outbox_repository.go.template +31 -0
  337. package/src/generators/go-microservice/files/internal/core/service/repository.go.template +23 -0
  338. package/src/generators/go-microservice/files/internal/core/service/user_repository.go.template +15 -0
  339. package/src/generators/go-microservice/files/internal/core/service/user_service.go.template +43 -0
  340. package/src/generators/go-microservice/files/internal/entrypoints/api/app_handler.go.template +108 -0
  341. package/src/generators/go-microservice/files/internal/entrypoints/api/auth_middleware_test.go.template +52 -0
  342. package/src/generators/go-microservice/files/internal/entrypoints/api/clerk_webhook.go.template +202 -0
  343. package/src/generators/go-microservice/files/internal/entrypoints/api/clerk_webhook_test.go.template +82 -0
  344. package/src/generators/go-microservice/files/internal/entrypoints/api/health_handler.go.template +80 -0
  345. package/src/generators/go-microservice/files/internal/entrypoints/api/idempotency/middleware.go.template +87 -0
  346. package/src/generators/go-microservice/files/internal/entrypoints/api/idempotency/middleware_test.go.template +76 -0
  347. package/src/generators/go-microservice/files/internal/entrypoints/api/idempotency/repository.go.template +37 -0
  348. package/src/generators/go-microservice/files/internal/entrypoints/api/middleware_auth.go.template +40 -0
  349. package/src/generators/go-microservice/files/internal/entrypoints/api/middleware_loadshed.go.template +38 -0
  350. package/src/generators/go-microservice/files/internal/entrypoints/api/middleware_logging.go.template +40 -0
  351. package/src/generators/go-microservice/files/internal/entrypoints/api/middleware_ratelimit.go.template +48 -0
  352. package/src/generators/go-microservice/files/internal/entrypoints/api/middleware_test.go.template +81 -0
  353. package/src/generators/go-microservice/files/internal/entrypoints/api/router.go.template +105 -0
  354. package/src/generators/go-microservice/files/internal/entrypoints/api/types.go.template +70 -0
  355. package/src/generators/go-microservice/files/internal/entrypoints/api/websocket_handler.go.template +39 -0
  356. package/src/generators/go-microservice/files/internal/httpclient/http_client.go.template +87 -0
  357. package/src/generators/go-microservice/files/internal/kafka/kafka.go.template +34 -0
  358. package/src/generators/go-microservice/files/internal/postgres/postgres.go.template +195 -0
  359. package/src/generators/go-microservice/files/internal/postgres/postgres_test.go.template +156 -0
  360. package/src/generators/go-microservice/files/internal/postgres/user_repository.go.template +56 -0
  361. package/src/generators/go-microservice/files/internal/pubsub/gcp_pubsub.go.template +35 -0
  362. package/src/generators/go-microservice/files/internal/websocket/client.go.template +151 -0
  363. package/src/generators/go-microservice/files/internal/websocket/hub.go.template +261 -0
  364. package/src/generators/go-microservice/files/scripts/apply-schema.sh.template +21 -0
  365. package/src/generators/go-microservice/files/tools/tools.go.template +10 -0
  366. package/src/generators/go-microservice/generator.ts +240 -0
  367. package/src/generators/go-microservice/schema.json +63 -0
  368. package/src/generators/nextjs-app/docs/principles/stack/typescript/frontend.md +65 -0
  369. package/src/generators/nextjs-app/files/.dockerignore.template +7 -0
  370. package/src/generators/nextjs-app/files/.env.example.template +24 -0
  371. package/src/generators/nextjs-app/files/.gitignore.template +5 -0
  372. package/src/generators/nextjs-app/files/Dockerfile +53 -0
  373. package/src/generators/nextjs-app/files/app/(auth)/sign-in/__sign-in__/page.tsx.template +9 -0
  374. package/src/generators/nextjs-app/files/app/(auth)/sign-up/__sign-up__/page.tsx.template +9 -0
  375. package/src/generators/nextjs-app/files/app/api/config/route.ts.template +39 -0
  376. package/src/generators/nextjs-app/files/app/api/healthz/route.test.ts +15 -0
  377. package/src/generators/nextjs-app/files/app/api/healthz/route.ts +5 -0
  378. package/src/generators/nextjs-app/files/app/api/proxy/__path__/route.test.ts.template +55 -0
  379. package/src/generators/nextjs-app/files/app/api/proxy/__path__/route.ts.template +126 -0
  380. package/src/generators/nextjs-app/files/app/error.tsx +39 -0
  381. package/src/generators/nextjs-app/files/app/global-error.tsx +68 -0
  382. package/src/generators/nextjs-app/files/app/globals.css +105 -0
  383. package/src/generators/nextjs-app/files/app/layout.tsx +59 -0
  384. package/src/generators/nextjs-app/files/app/loading.tsx +13 -0
  385. package/src/generators/nextjs-app/files/app/not-found.tsx +30 -0
  386. package/src/generators/nextjs-app/files/app/page.tsx +20 -0
  387. package/src/generators/nextjs-app/files/components/providers/default.tsx +19 -0
  388. package/src/generators/nextjs-app/files/components/providers/production.tsx +32 -0
  389. package/src/generators/nextjs-app/files/components/providers/telemetry.tsx +76 -0
  390. package/src/generators/nextjs-app/files/components/render-smoke.test.tsx +29 -0
  391. package/src/generators/nextjs-app/files/components/theme-provider.tsx +11 -0
  392. package/src/generators/nextjs-app/files/components.json +21 -0
  393. package/src/generators/nextjs-app/files/eslint.config.mjs +120 -0
  394. package/src/generators/nextjs-app/files/hooks/use-toast.ts +7 -0
  395. package/src/generators/nextjs-app/files/instrumentation.ts +90 -0
  396. package/src/generators/nextjs-app/files/lib/api/fetcher.ts.template +130 -0
  397. package/src/generators/nextjs-app/files/lib/config.ts +21 -0
  398. package/src/generators/nextjs-app/files/lib/logger.ts +29 -0
  399. package/src/generators/nextjs-app/files/lib/schemas/index.ts +19 -0
  400. package/src/generators/nextjs-app/files/lib/utils.ts +6 -0
  401. package/src/generators/nextjs-app/files/next.config.mjs +9 -0
  402. package/src/generators/nextjs-app/files/package.json +70 -0
  403. package/src/generators/nextjs-app/files/postcss.config.mjs +8 -0
  404. package/src/generators/nextjs-app/files/proxy.test.ts.template +30 -0
  405. package/src/generators/nextjs-app/files/proxy.ts +31 -0
  406. package/src/generators/nextjs-app/files/public/.gitkeep +1 -0
  407. package/src/generators/nextjs-app/files/tsconfig.json +42 -0
  408. package/src/generators/nextjs-app/files/vitest.config.mts +15 -0
  409. package/src/generators/nextjs-app/files/vitest.setup.ts +7 -0
  410. package/src/generators/nextjs-app/generator.ts +307 -0
  411. package/src/generators/nextjs-app/schema.json +44 -0
  412. package/src/generators/python-microservice/docs/principles/stack/python/async.md +168 -0
  413. package/src/generators/python-microservice/docs/principles/stack/python/documentation.md +240 -0
  414. package/src/generators/python-microservice/docs/principles/stack/python/mcp.md +147 -0
  415. package/src/generators/python-microservice/docs/principles/stack/python/resilience.md +193 -0
  416. package/src/generators/python-microservice/docs/principles/stack/python/testing.md +281 -0
  417. package/src/generators/python-microservice/files/.env.example.template +30 -0
  418. package/src/generators/python-microservice/files/Dockerfile.template +36 -0
  419. package/src/generators/python-microservice/files/db/schema.sql.template +19 -0
  420. package/src/generators/python-microservice/files/pyproject.toml.template +76 -0
  421. package/src/generators/python-microservice/files/scripts/apply-schema.sh.template +25 -0
  422. package/src/generators/python-microservice/files/src/__packageName__/adapters/comfyui.py.template +87 -0
  423. package/src/generators/python-microservice/files/src/__packageName__/adapters/config.py.template +48 -0
  424. package/src/generators/python-microservice/files/src/__packageName__/adapters/database.py.template +21 -0
  425. package/src/generators/python-microservice/files/src/__packageName__/adapters/message_queue.py.template +29 -0
  426. package/src/generators/python-microservice/files/src/__packageName__/adapters/repository.py.template +130 -0
  427. package/src/generators/python-microservice/files/src/__packageName__/adapters/telemetry.py.template +68 -0
  428. package/src/generators/python-microservice/files/src/__packageName__/adapters/websocket_hub.py.template +36 -0
  429. package/src/generators/python-microservice/files/src/__packageName__/core/domain/entities.py.template +22 -0
  430. package/src/generators/python-microservice/files/src/__packageName__/core/domain/exceptions.py.template +43 -0
  431. package/src/generators/python-microservice/files/src/__packageName__/core/ports.py.template +42 -0
  432. package/src/generators/python-microservice/files/src/__packageName__/core/service/example_service.py.template +68 -0
  433. package/src/generators/python-microservice/files/src/__packageName__/entrypoints/api/dependencies.py.template +50 -0
  434. package/src/generators/python-microservice/files/src/__packageName__/entrypoints/api/middleware.py.template +131 -0
  435. package/src/generators/python-microservice/files/src/__packageName__/entrypoints/api/router.py.template +37 -0
  436. package/src/generators/python-microservice/files/src/__packageName__/entrypoints/api/websocket_handler.py.template +20 -0
  437. package/src/generators/python-microservice/files/src/__packageName__/entrypoints/worker/cleanup.py.template +35 -0
  438. package/src/generators/python-microservice/files/src/__packageName__/entrypoints/worker/worker.py.template +28 -0
  439. package/src/generators/python-microservice/files/src/__packageName__/main.py.template +108 -0
  440. package/src/generators/python-microservice/files/tests/test_main.py.template +74 -0
  441. package/src/generators/python-microservice/files/tests/test_middleware.py.template +109 -0
  442. package/src/generators/python-microservice/files/tests/test_worker.py.template +16 -0
  443. package/src/generators/python-microservice/generator.ts +286 -0
  444. package/src/generators/python-microservice/schema.json +86 -0
  445. package/src/generators/shared/brand-tokens.ts +301 -0
  446. package/src/generators/shared/capabilities.ts +349 -0
  447. package/src/generators/shared/provenance.ts +61 -0
  448. package/src/generators/shared/scaffold-helpers.ts +309 -0
  449. package/src/generators/system-test-runner/files/tests/bets/.gitkeep +0 -0
  450. package/src/generators/system-test-runner/files/tests/bets/_archive/.gitkeep +0 -0
  451. package/src/generators/system-test-runner/files/tests/conftest.py.template +503 -0
  452. package/src/generators/system-test-runner/files/tests/pyproject.toml.template +20 -0
  453. package/src/generators/system-test-runner/files/tests/system/pages/__init__.py.template +9 -0
  454. package/src/generators/system-test-runner/files/tests/system/pages/base_page.py.template +36 -0
  455. package/src/generators/system-test-runner/files/tests/system/test_a11y_smoke.py.template +132 -0
  456. package/src/generators/system-test-runner/files/tests/system/test_contract_conformance.py.template +140 -0
  457. package/src/generators/system-test-runner/files/tests/system/test_layout_geometry.py.template +109 -0
  458. package/src/generators/system-test-runner/files/tests/system/test_render_smoke.py.template +227 -0
  459. package/src/generators/system-test-runner/files/tests/system/test_system.py.template +158 -0
  460. package/src/generators/system-test-runner/files/tests/system/test_token_conformance.py.template +206 -0
  461. package/src/generators/system-test-runner/files/tests/system/test_visual_regression.py.template +104 -0
  462. package/src/generators/system-test-runner/generator.ts +142 -0
  463. package/src/generators/system-test-runner/schema.json +24 -0
  464. package/src/generators/workspace-dev-cli/cli-src/build.mjs +42 -0
  465. package/src/generators/workspace-dev-cli/cli-src/dist/dev-bundle.js +2168 -0
  466. package/src/generators/workspace-dev-cli/cli-src/src/commands/bet.ts +442 -0
  467. package/src/generators/workspace-dev-cli/cli-src/src/commands/completion.ts +87 -0
  468. package/src/generators/workspace-dev-cli/cli-src/src/commands/doctor.ts +139 -0
  469. package/src/generators/workspace-dev-cli/cli-src/src/commands/lifecycle.ts +548 -0
  470. package/src/generators/workspace-dev-cli/cli-src/src/commands/quality.ts +127 -0
  471. package/src/generators/workspace-dev-cli/cli-src/src/commands/surface.ts +214 -0
  472. package/src/generators/workspace-dev-cli/cli-src/src/index.ts +127 -0
  473. package/src/generators/workspace-dev-cli/cli-src/src/registry.ts +194 -0
  474. package/src/generators/workspace-dev-cli/cli-src/src/theme/color.ts +130 -0
  475. package/src/generators/workspace-dev-cli/cli-src/src/theme/render.ts +158 -0
  476. package/src/generators/workspace-dev-cli/cli-src/src/theme/tokens.ts +122 -0
  477. package/src/generators/workspace-dev-cli/cli-src/src/util/context.ts +43 -0
  478. package/src/generators/workspace-dev-cli/cli-src/src/util/extensions.ts +99 -0
  479. package/src/generators/workspace-dev-cli/cli-src/src/util/paths.ts +46 -0
  480. package/src/generators/workspace-dev-cli/cli-src/src/util/proc.ts +106 -0
  481. package/src/generators/workspace-dev-cli/cli-src/src/util/prompt.ts +108 -0
  482. package/src/generators/workspace-dev-cli/cli-src/src/util/runners.ts +70 -0
  483. package/src/generators/workspace-dev-cli/cli-src/src/util/services.ts +221 -0
  484. package/src/generators/workspace-dev-cli/cli-src/src/util/version.ts +21 -0
  485. package/src/generators/workspace-dev-cli/cli-src/tsconfig.json +16 -0
  486. package/src/generators/workspace-dev-cli/files/.agents/skills/workspace-cli/SKILL.md.template +74 -0
  487. package/src/generators/workspace-dev-cli/files/dev.template +16 -0
  488. package/src/generators/workspace-dev-cli/files/docker-compose.yml.template +20 -0
  489. package/src/generators/workspace-dev-cli/files/scripts/cli/templates/milestone-test.pytmpl.template +46 -0
  490. package/src/generators/workspace-dev-cli/files/scripts/cli/templates/slice-test.pytmpl.template +38 -0
  491. package/src/generators/workspace-dev-cli/generator.ts +136 -0
  492. package/src/generators/workspace-dev-cli/schema.json +22 -0
  493. package/src/hidden-skills/code-intelligence.md +129 -0
  494. package/src/hidden-skills/groundwork-architect/SKILL.md +114 -0
  495. package/src/hidden-skills/groundwork-architect/references/agentic-systems.md +44 -0
  496. package/src/hidden-skills/groundwork-architect/references/ai-native-architecture.md +37 -0
  497. package/src/hidden-skills/groundwork-architect/references/api-and-contracts.md +45 -0
  498. package/src/hidden-skills/groundwork-architect/references/core-and-boundaries.md +45 -0
  499. package/src/hidden-skills/groundwork-architect/references/data-architecture.md +33 -0
  500. package/src/hidden-skills/groundwork-architect/references/decision-records.md +34 -0
  501. package/src/hidden-skills/groundwork-architect/references/durable-execution.md +45 -0
  502. package/src/hidden-skills/groundwork-architect/references/evolutionary-architecture.md +37 -0
  503. package/src/hidden-skills/groundwork-architect/references/identity-and-access.md +41 -0
  504. package/src/hidden-skills/groundwork-architect/references/integration-patterns.md +39 -0
  505. package/src/hidden-skills/groundwork-architect/references/observability.md +36 -0
  506. package/src/hidden-skills/groundwork-architect/references/performance-and-scale.md +41 -0
  507. package/src/hidden-skills/groundwork-architect/references/platform-and-delivery.md +47 -0
  508. package/src/hidden-skills/groundwork-architect/references/realtime-and-async.md +28 -0
  509. package/src/hidden-skills/groundwork-architect/references/reliability.md +31 -0
  510. package/src/hidden-skills/groundwork-architect/references/security-and-trust.md +47 -0
  511. package/src/hidden-skills/groundwork-architect/references/surface-architecture.md +40 -0
  512. package/src/hidden-skills/groundwork-architect/sync-anchor.md +34 -0
  513. package/src/hidden-skills/groundwork-architecture/architecture-template.md +50 -0
  514. package/src/hidden-skills/groundwork-architecture/instructions.md +139 -0
  515. package/src/hidden-skills/groundwork-architecture/phases/01-context-ingestion.md +18 -0
  516. package/src/hidden-skills/groundwork-architecture/phases/02-technical-constraints.md +27 -0
  517. package/src/hidden-skills/groundwork-architecture/phases/03-service-design.md +19 -0
  518. package/src/hidden-skills/groundwork-architecture/phases/04-data-flow-communication.md +23 -0
  519. package/src/hidden-skills/groundwork-architecture/phases/05-component-boundaries-contracts.md +17 -0
  520. package/src/hidden-skills/groundwork-architecture/phases/06-draft-review-present.md +38 -0
  521. package/src/hidden-skills/groundwork-architecture/phases/07-commit.md +33 -0
  522. package/src/hidden-skills/groundwork-architecture/templates/architecture-cache.md +43 -0
  523. package/src/hidden-skills/groundwork-architecture-extract/instructions.md +163 -0
  524. package/src/hidden-skills/groundwork-architecture-extract/templates/architecture-extract-cache.md +21 -0
  525. package/src/hidden-skills/groundwork-bet/briefs/slice-worker.md +191 -0
  526. package/src/hidden-skills/groundwork-bet/instructions.md +88 -0
  527. package/src/hidden-skills/groundwork-bet/templates/bet-progress-test.md +126 -0
  528. package/src/hidden-skills/groundwork-bet/templates/change-proposal.md +38 -0
  529. package/src/hidden-skills/groundwork-bet/templates/decomposition/meta.json +4 -0
  530. package/src/hidden-skills/groundwork-bet/templates/decomposition/milestone-index.md +35 -0
  531. package/src/hidden-skills/groundwork-bet/templates/decomposition/slice.md +35 -0
  532. package/src/hidden-skills/groundwork-bet/templates/pitch.md +45 -0
  533. package/src/hidden-skills/groundwork-bet/templates/technical-design/01-ui-design.md +51 -0
  534. package/src/hidden-skills/groundwork-bet/templates/technical-design/02-data-flows.md +36 -0
  535. package/src/hidden-skills/groundwork-bet/templates/technical-design/03-api-design.md +90 -0
  536. package/src/hidden-skills/groundwork-bet/templates/technical-design/04-data-design.md +29 -0
  537. package/src/hidden-skills/groundwork-bet/workflows/01-discovery.md +198 -0
  538. package/src/hidden-skills/groundwork-bet/workflows/02-design.md +168 -0
  539. package/src/hidden-skills/groundwork-bet/workflows/03-decomposition.md +246 -0
  540. package/src/hidden-skills/groundwork-bet/workflows/04-delivery.md +193 -0
  541. package/src/hidden-skills/groundwork-bet/workflows/05-validation.md +199 -0
  542. package/src/hidden-skills/groundwork-design-system/instructions.md +125 -0
  543. package/src/hidden-skills/groundwork-design-system/templates/brand-tokens.md +182 -0
  544. package/src/hidden-skills/groundwork-design-system/templates/design-system-cache.md +64 -0
  545. package/src/hidden-skills/groundwork-design-system/tracks/_foundation.md +136 -0
  546. package/src/hidden-skills/groundwork-design-system/tracks/agentic-protocol.md +269 -0
  547. package/src/hidden-skills/groundwork-design-system/tracks/cli.md +355 -0
  548. package/src/hidden-skills/groundwork-design-system/tracks/graphical-ui.md +330 -0
  549. package/src/hidden-skills/groundwork-design-system-extract/instructions.md +124 -0
  550. package/src/hidden-skills/groundwork-design-system-extract/templates/design-system-extract-cache.md +19 -0
  551. package/src/hidden-skills/groundwork-designer/SKILL.md +108 -0
  552. package/src/hidden-skills/groundwork-designer/references/accessibility.md +33 -0
  553. package/src/hidden-skills/groundwork-designer/references/ai-native-design.md +37 -0
  554. package/src/hidden-skills/groundwork-designer/references/design-review.md +29 -0
  555. package/src/hidden-skills/groundwork-designer/references/design-systems-and-tokens.md +33 -0
  556. package/src/hidden-skills/groundwork-designer/references/interaction-and-motion.md +37 -0
  557. package/src/hidden-skills/groundwork-designer/references/layout-and-space.md +33 -0
  558. package/src/hidden-skills/groundwork-designer/references/usability-and-ux.md +33 -0
  559. package/src/hidden-skills/groundwork-designer/references/visual-craft.md +49 -0
  560. package/src/hidden-skills/groundwork-designer/sync-anchor.md +20 -0
  561. package/src/hidden-skills/groundwork-doc-sync/instructions.md +100 -0
  562. package/src/hidden-skills/groundwork-elicit/instructions.md +66 -0
  563. package/src/hidden-skills/groundwork-elicit/methods.md +65 -0
  564. package/src/hidden-skills/groundwork-infra-adopt/instructions.md +168 -0
  565. package/src/hidden-skills/groundwork-infra-adopt/templates/infra-adopt-cache.md +21 -0
  566. package/src/hidden-skills/groundwork-mvp/instructions.md +223 -0
  567. package/src/hidden-skills/groundwork-mvp/templates/mvp-cache.md +9 -0
  568. package/src/hidden-skills/groundwork-patch/instructions.md +40 -0
  569. package/src/hidden-skills/groundwork-persona/instructions.md +54 -0
  570. package/src/hidden-skills/groundwork-product/SKILL.md +102 -0
  571. package/src/hidden-skills/groundwork-product/references/ai-native-product.md +45 -0
  572. package/src/hidden-skills/groundwork-product/references/discovery-and-opportunity.md +38 -0
  573. package/src/hidden-skills/groundwork-product/references/product-risks.md +52 -0
  574. package/src/hidden-skills/groundwork-product/references/requirements-and-specs.md +39 -0
  575. package/src/hidden-skills/groundwork-product/references/scope-and-sequencing.md +35 -0
  576. package/src/hidden-skills/groundwork-product/references/shaping-and-appetite.md +48 -0
  577. package/src/hidden-skills/groundwork-product/references/success-metrics-and-signals.md +37 -0
  578. package/src/hidden-skills/groundwork-product/sync-anchor.md +19 -0
  579. package/src/hidden-skills/groundwork-product-brief/instructions.md +231 -0
  580. package/src/hidden-skills/groundwork-product-brief-extract/instructions.md +139 -0
  581. package/src/hidden-skills/groundwork-product-brief-extract/templates/product-brief-extract-cache.md +17 -0
  582. package/src/hidden-skills/groundwork-review/checklists/architecture.md +93 -0
  583. package/src/hidden-skills/groundwork-review/checklists/bet-pitch.md +94 -0
  584. package/src/hidden-skills/groundwork-review/checklists/decomposition.md +135 -0
  585. package/src/hidden-skills/groundwork-review/checklists/design-system.md +85 -0
  586. package/src/hidden-skills/groundwork-review/checklists/domain-entity.md +66 -0
  587. package/src/hidden-skills/groundwork-review/checklists/implementation-readiness.md +46 -0
  588. package/src/hidden-skills/groundwork-review/checklists/infrastructure.md +68 -0
  589. package/src/hidden-skills/groundwork-review/checklists/maturity.md +71 -0
  590. package/src/hidden-skills/groundwork-review/checklists/product-brief.md +69 -0
  591. package/src/hidden-skills/groundwork-review/checklists/technical-design.md +112 -0
  592. package/src/hidden-skills/groundwork-review/instructions.md +181 -0
  593. package/src/hidden-skills/groundwork-scaffold/instructions.md +254 -0
  594. package/src/hidden-skills/groundwork-scaffold/phases/01-ingestion-service-mapping.md +87 -0
  595. package/src/hidden-skills/groundwork-scaffold/phases/02-scaffolding-execution.md +15 -0
  596. package/src/hidden-skills/groundwork-scaffold/phases/03-service-documentation-api-stubs.md +100 -0
  597. package/src/hidden-skills/groundwork-scaffold/phases/04-infrastructure-verification.md +17 -0
  598. package/src/hidden-skills/groundwork-scaffold/phases/05-draft-review.md +19 -0
  599. package/src/hidden-skills/groundwork-scaffold/phases/06-commit.md +19 -0
  600. package/src/hidden-skills/groundwork-scaffold/templates/scaffold-cache.md +23 -0
  601. package/src/hidden-skills/groundwork-scan/instructions.md +164 -0
  602. package/src/hidden-skills/groundwork-scan/references/digest-schema.md +66 -0
  603. package/src/hidden-skills/groundwork-scan/references/exclusions.md +44 -0
  604. package/src/hidden-skills/groundwork-scan/templates/architecture-findings.md +42 -0
  605. package/src/hidden-skills/groundwork-scan/templates/design-findings.md +23 -0
  606. package/src/hidden-skills/groundwork-scan/templates/overview.md +26 -0
  607. package/src/hidden-skills/groundwork-scan/templates/product-findings.md +23 -0
  608. package/src/hidden-skills/groundwork-scan/templates/scan-state.json +19 -0
  609. package/src/hidden-skills/groundwork-stack-forge/instructions.md +150 -0
  610. package/src/hidden-skills/groundwork-stack-forge/references/authoring-engineer-skills.md +107 -0
  611. package/src/hidden-skills/groundwork-surface-activation/instructions.md +138 -0
  612. package/src/hidden-skills/groundwork-update/briefs/reconcile-worker.md +196 -0
  613. package/src/hidden-skills/groundwork-update/instructions.md +200 -0
  614. package/src/hidden-skills/groundwork-writer/SKILL.md +278 -0
  615. package/src/hidden-skills/maturity-model.md +125 -0
  616. package/src/hidden-skills/operating-contract.md +400 -0
  617. package/src/hidden-skills/repo-map-schema.md +90 -0
  618. package/src/hidden-skills/templates/adr.md +57 -0
  619. package/src/hidden-skills/templates/capability-ports.md +71 -0
  620. package/src/hidden-skills/templates/discovery-notes.md +33 -0
  621. package/src/hidden-skills/templates/domain-entity.md +80 -0
  622. package/src/hidden-skills/templates/gap-ledger.md +21 -0
  623. package/src/hidden-skills/templates/handoff.md +37 -0
  624. package/src/hidden-skills/templates/maturity.md +39 -0
  625. package/src/hidden-skills/templates/surfaces.md +207 -0
  626. package/src/skills/groundwork-check/SKILL.md +56 -0
  627. package/src/skills/groundwork-check/instructions.md +70 -0
  628. package/src/skills/groundwork-orchestrator/SKILL.md +176 -0
  629. package/src/skills/groundwork-orchestrator/workflow-index.md +50 -0
@@ -0,0 +1,362 @@
1
+ import {
2
+ formatFiles,
3
+ generateFiles,
4
+ Tree,
5
+ names,
6
+ } from '@nx/devkit';
7
+ import * as path from 'path';
8
+ import { recordGeneratorProvenance } from '../shared/provenance';
9
+ import {
10
+ promoteEngineerSkill,
11
+ deployStackDocs,
12
+ registerRunner,
13
+ } from '../shared/scaffold-helpers';
14
+
15
+ export interface FlutterAppGeneratorSchema {
16
+ name: string;
17
+ org?: string;
18
+ }
19
+
20
+ const BRAND_TOKENS_PATH = '.groundwork/config/brand-tokens.json';
21
+
22
+ /** Palette roles the visual block commits to (templates/brand-tokens.md). */
23
+ const PALETTE_ROLES = [
24
+ 'primary',
25
+ 'accent',
26
+ 'surface',
27
+ 'surfaceAlt',
28
+ 'textBody',
29
+ 'success',
30
+ 'error',
31
+ 'warning',
32
+ 'info',
33
+ ] as const;
34
+
35
+ /** Neutral defaults used when no visual block (or no tokens at all) exists.
36
+ * Mirrors how cli-app degrades to a Tier-1 identity: the app still themes
37
+ * coherently, it just wears a restrained default brand. */
38
+ const NEUTRAL_PALETTE: Record<string, { light: string; dark: string }> = {
39
+ primary: { light: '#3b6fd4', dark: '#7da7ef' },
40
+ accent: { light: '#7a5fd4', dark: '#b3a1f0' },
41
+ surface: { light: '#fafafa', dark: '#17181c' },
42
+ surfaceAlt: { light: '#f0f1f4', dark: '#1f2127' },
43
+ textBody: { light: '#26282e', dark: '#e4e6eb' },
44
+ success: { light: '#2f9e6e', dark: '#5fc398' },
45
+ error: { light: '#cf4444', dark: '#ef7f7f' },
46
+ warning: { light: '#c08a1f', dark: '#e0b35f' },
47
+ info: { light: '#3b6fd4', dark: '#7da7ef' },
48
+ };
49
+
50
+ const NEUTRAL_TYPOGRAPHY = {
51
+ display: { family: 'Inter', weight: 600 },
52
+ body: { family: 'Inter', weight: 400 },
53
+ };
54
+
55
+ const NEUTRAL_RADIUS_PX = 8;
56
+
57
+ /** Convert an OKLCH colour to sRGB hex. The visual block allows palette values
58
+ * in OKLCH or #rrggbb (templates/brand-tokens.md); Dart's Color needs ARGB, so
59
+ * the projection resolves OKLCH at generation time rather than shipping a
60
+ * colour-math dependency into the app. Standard OKLab → linear sRGB → gamma. */
61
+ function oklchToHex(l: number, c: number, hDeg: number): string {
62
+ const hRad = (hDeg * Math.PI) / 180;
63
+ const a = c * Math.cos(hRad);
64
+ const b = c * Math.sin(hRad);
65
+
66
+ const l_ = l + 0.3963377774 * a + 0.2158037573 * b;
67
+ const m_ = l - 0.1055613458 * a - 0.0638541728 * b;
68
+ const s_ = l - 0.0894841775 * a - 1.291485548 * b;
69
+
70
+ const L = l_ ** 3;
71
+ const M = m_ ** 3;
72
+ const S = s_ ** 3;
73
+
74
+ const lin = [
75
+ 4.0767416621 * L - 3.3077115913 * M + 0.2309699292 * S,
76
+ -1.2684380046 * L + 2.6097574011 * M - 0.3413193965 * S,
77
+ -0.0041960863 * L - 0.7034186147 * M + 1.707614701 * S,
78
+ ];
79
+
80
+ const toByte = (x: number): number => {
81
+ const clamped = Math.min(1, Math.max(0, x));
82
+ const srgb =
83
+ clamped <= 0.0031308
84
+ ? 12.92 * clamped
85
+ : 1.055 * Math.pow(clamped, 1 / 2.4) - 0.055;
86
+ return Math.round(Math.min(1, Math.max(0, srgb)) * 255);
87
+ };
88
+
89
+ return lin
90
+ .map((x) => toByte(x).toString(16).padStart(2, '0'))
91
+ .join('');
92
+ }
93
+
94
+ /** Resolve a CSS colour string (#rgb, #rrggbb, or oklch(...)) to rrggbb hex.
95
+ * Returns null when the value cannot be resolved, so callers fall back to the
96
+ * neutral default instead of emitting broken Dart. */
97
+ function cssColorToHex(value: unknown): string | null {
98
+ if (typeof value !== 'string') return null;
99
+ const v = value.trim();
100
+
101
+ const hex6 = v.match(/^#([0-9a-fA-F]{6})$/);
102
+ if (hex6) return hex6[1].toLowerCase();
103
+
104
+ const hex3 = v.match(/^#([0-9a-fA-F]{3})$/);
105
+ if (hex3) {
106
+ return hex3[1]
107
+ .toLowerCase()
108
+ .split('')
109
+ .map((ch) => ch + ch)
110
+ .join('');
111
+ }
112
+
113
+ const oklch = v.match(
114
+ /^oklch\(\s*([\d.]+)(%?)\s+([\d.]+)\s+([\d.]+)(?:deg)?\s*\)$/i,
115
+ );
116
+ if (oklch) {
117
+ const l = parseFloat(oklch[1]) / (oklch[2] === '%' ? 100 : 1);
118
+ const c = parseFloat(oklch[3]);
119
+ const h = parseFloat(oklch[4]);
120
+ if ([l, c, h].every((n) => Number.isFinite(n))) return oklchToHex(l, c, h);
121
+ }
122
+
123
+ return null;
124
+ }
125
+
126
+ /** Dart Color literal from an rrggbb hex string. Tolerates a leading `#`
127
+ * (the neutral-default palette carries CSS-style values) so no path can
128
+ * emit a malformed literal like `Color(0xFF#3B6FD4)`. */
129
+ function dartColor(hex: string): string {
130
+ return `Color(0xFF${hex.replace(/^#/, '').toUpperCase()})`;
131
+ }
132
+
133
+ /** Parse a radius descriptor like "8px" / "0.5rem" / "12" into logical pixels. */
134
+ function radiusToLogicalPx(value: unknown): number {
135
+ if (typeof value !== 'string' && typeof value !== 'number') {
136
+ return NEUTRAL_RADIUS_PX;
137
+ }
138
+ const m = String(value)
139
+ .trim()
140
+ .match(/^([\d.]+)\s*(px|rem)?$/i);
141
+ if (!m) return NEUTRAL_RADIUS_PX;
142
+ const n = parseFloat(m[1]);
143
+ if (!Number.isFinite(n)) return NEUTRAL_RADIUS_PX;
144
+ return (m[2] || 'px').toLowerCase() === 'rem' ? n * 16 : n;
145
+ }
146
+
147
+ interface ResolvedBrand {
148
+ palette: Record<string, { light: string; dark: string }>; // rrggbb hex
149
+ typography: {
150
+ display: { family: string; weight: number };
151
+ body: { family: string; weight: number };
152
+ };
153
+ radiusPx: number;
154
+ source: 'visual-block' | 'identity-only' | 'default';
155
+ }
156
+
157
+ /** Project the design system's brand tokens into theme inputs. Three cases,
158
+ * mirroring the cli-app's token handling:
159
+ * - a Tier 2 `visual` block → full projection (palette roles, typography, shape)
160
+ * - Tier-1-only tokens → palette seeded from identity.primary/accent
161
+ * - no tokens → the neutral default */
162
+ function resolveBrand(tree: Tree): ResolvedBrand {
163
+ const palette: Record<string, { light: string; dark: string }> = {};
164
+ for (const role of PALETTE_ROLES) {
165
+ palette[role] = { ...NEUTRAL_PALETTE[role] };
166
+ }
167
+ const typography = {
168
+ display: { ...NEUTRAL_TYPOGRAPHY.display },
169
+ body: { ...NEUTRAL_TYPOGRAPHY.body },
170
+ };
171
+ let radiusPx = NEUTRAL_RADIUS_PX;
172
+ let source: ResolvedBrand['source'] = 'default';
173
+
174
+ if (!tree.exists(BRAND_TOKENS_PATH)) {
175
+ return { palette, typography, radiusPx, source };
176
+ }
177
+
178
+ let raw: any = null;
179
+ try {
180
+ raw = JSON.parse(tree.read(BRAND_TOKENS_PATH, 'utf-8') || '{}');
181
+ } catch {
182
+ return { palette, typography, radiusPx, source }; // malformed — neutral
183
+ }
184
+
185
+ const visual = raw?.visual;
186
+ if (visual && typeof visual === 'object') {
187
+ source = 'visual-block';
188
+ for (const role of PALETTE_ROLES) {
189
+ const entry = visual.palette?.[role];
190
+ const light = cssColorToHex(entry?.light);
191
+ const dark = cssColorToHex(entry?.dark);
192
+ if (light) palette[role].light = light;
193
+ if (dark) palette[role].dark = dark;
194
+ }
195
+ if (visual.typography?.display?.family) {
196
+ typography.display.family = String(visual.typography.display.family);
197
+ typography.display.weight =
198
+ Number(visual.typography.display.weight) || typography.display.weight;
199
+ }
200
+ if (visual.typography?.body?.family) {
201
+ typography.body.family = String(visual.typography.body.family);
202
+ typography.body.weight =
203
+ Number(visual.typography.body.weight) || typography.body.weight;
204
+ }
205
+ radiusPx = radiusToLogicalPx(visual.shape?.radiusBase);
206
+ return { palette, typography, radiusPx, source };
207
+ }
208
+
209
+ // Tier-1-only tokens: derive the brand colours from identity, keep the
210
+ // neutral chrome. This is the mechanical Tier-1 projection the brand-tokens
211
+ // contract requires of every consumer.
212
+ const identity = raw?.identity;
213
+ if (identity && typeof identity === 'object') {
214
+ source = 'identity-only';
215
+ const primary = cssColorToHex(identity.primary);
216
+ const accent = cssColorToHex(identity.accent);
217
+ if (primary) {
218
+ palette.primary = { light: primary, dark: primary };
219
+ palette.info = { light: primary, dark: primary };
220
+ }
221
+ if (accent) palette.accent = { light: accent, dark: accent };
222
+ }
223
+
224
+ return { palette, typography, radiusPx, source };
225
+ }
226
+
227
+ /** Render the generated Dart theme module. The palette file is the projection
228
+ * artifact (regenerate, never hand-edit); app_theme.dart (a static template)
229
+ * builds ThemeData from it. */
230
+ function renderBrandPalette(brand: ResolvedBrand): string {
231
+ const lines: string[] = [];
232
+ lines.push('// GENERATED by the GroundWork flutter-app generator from');
233
+ lines.push(
234
+ '// .groundwork/config/brand-tokens.json — do not hand-edit this file.',
235
+ );
236
+ lines.push('//');
237
+ lines.push(
238
+ '// Re-run the design system to evolve the brand, then regenerate (or update',
239
+ );
240
+ lines.push(
241
+ '// this file to match brand-tokens.json). Widgets never read these constants',
242
+ );
243
+ lines.push(
244
+ '// directly: they consume Theme.of(context), built in app_theme.dart.',
245
+ );
246
+ lines.push(
247
+ '// See docs/principles/stack/flutter/widgets-and-composition.md — theming is',
248
+ );
249
+ lines.push('// a projection, not an authoring surface.');
250
+ lines.push(`// Projection source: ${brand.source}.`);
251
+ lines.push("import 'package:flutter/material.dart';");
252
+ lines.push('');
253
+ lines.push("/// The design system's visual block, projected into Dart.");
254
+ lines.push('abstract final class BrandPalette {');
255
+ lines.push(' // Palette roles — light theme.');
256
+ for (const role of PALETTE_ROLES) {
257
+ lines.push(
258
+ ` static const Color ${role}Light = ${dartColor(brand.palette[role].light)};`,
259
+ );
260
+ }
261
+ lines.push('');
262
+ lines.push(' // Palette roles — dark theme.');
263
+ for (const role of PALETTE_ROLES) {
264
+ lines.push(
265
+ ` static const Color ${role}Dark = ${dartColor(brand.palette[role].dark)};`,
266
+ );
267
+ }
268
+ lines.push('');
269
+ lines.push(' // Typography families (bundle the font assets to take effect).');
270
+ lines.push(
271
+ ` static const String displayFontFamily = '${brand.typography.display.family.replace(/'/g, '')}';`,
272
+ );
273
+ lines.push(
274
+ ` static const int displayFontWeight = ${brand.typography.display.weight};`,
275
+ );
276
+ lines.push(
277
+ ` static const String bodyFontFamily = '${brand.typography.body.family.replace(/'/g, '')}';`,
278
+ );
279
+ lines.push(
280
+ ` static const int bodyFontWeight = ${brand.typography.body.weight};`,
281
+ );
282
+ lines.push('');
283
+ lines.push(' // Shape.');
284
+ lines.push(` static const double radiusBase = ${brand.radiusPx.toFixed(1)};`);
285
+ lines.push('}');
286
+ lines.push('');
287
+ return lines.join('\n');
288
+ }
289
+
290
+ export default async function (tree: Tree, options: FlutterAppGeneratorSchema) {
291
+ const serviceNames = names(options.name);
292
+ const projectRoot = `services/${serviceNames.fileName}`;
293
+ // Dart package names are lower_snake_case; the workspace slug is kebab-case.
294
+ const pubspecName = serviceNames.fileName.replace(/-/g, '_');
295
+ const org = options.org || 'com.example';
296
+
297
+ const templateOptions = {
298
+ ...options,
299
+ ...serviceNames,
300
+ pubspecName,
301
+ org,
302
+ tmpl: '', // required by generateFiles
303
+ };
304
+
305
+ generateFiles(
306
+ tree,
307
+ path.join(__dirname, '..', '..', '..', '..', 'src', 'generators', 'flutter-app', 'files'),
308
+ projectRoot,
309
+ templateOptions,
310
+ );
311
+
312
+ // Project brand-tokens.json's visual block into the Dart theme module.
313
+ tree.write(
314
+ `${projectRoot}/lib/ui/core/theme/brand_palette.dart`,
315
+ renderBrandPalette(resolveBrand(tree)),
316
+ );
317
+
318
+ deployStackDocs(tree, path.join(__dirname, '..', '..', '..', '..', 'src', 'generators', 'flutter-app', 'docs'));
319
+
320
+ // A Flutter app lives on pubspec and the Dart toolchain, not npm, and it has
321
+ // no Docker boot. It never joins docker-compose.yml or the package.json
322
+ // workspaces list; instead it registers as a native runner so `./dev` can
323
+ // report and tail it. autostart is false — `flutter run` needs a target
324
+ // device/emulator chosen interactively, so it is registered and runnable but
325
+ // not part of the unattended `./dev start` boot set.
326
+ registerRunner(tree, {
327
+ name: serviceNames.fileName,
328
+ kind: 'surface',
329
+ cmd: 'bash tool/flutter_exec.sh run',
330
+ cwd: projectRoot,
331
+ autostart: false,
332
+ });
333
+
334
+ promoteEngineerSkill(tree, 'groundwork-flutter-engineer');
335
+
336
+ await formatFiles(tree);
337
+
338
+ recordGeneratorProvenance(tree, 'flutter-app', options as unknown as Record<string, unknown>);
339
+
340
+ return () => {
341
+ const { execSync } = require('child_process');
342
+ try {
343
+ execSync('command -v flutter', { stdio: 'ignore', shell: '/bin/bash' });
344
+ } catch {
345
+ console.warn(
346
+ `flutter SDK not found — generation is complete, but the toolchain tiers are skipped.\n` +
347
+ `Install the Flutter SDK, then run: npx nx run ${serviceNames.fileName}:bootstrap`,
348
+ );
349
+ return;
350
+ }
351
+ try {
352
+ execSync(`bash tool/flutter_exec.sh bootstrap`, {
353
+ cwd: projectRoot,
354
+ stdio: 'inherit',
355
+ });
356
+ } catch (e) {
357
+ console.warn(
358
+ `Failed to bootstrap ${projectRoot}. Run 'npx nx run ${serviceNames.fileName}:bootstrap' manually.`,
359
+ );
360
+ }
361
+ };
362
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "$schema": "http://json-schema.org/schema",
3
+ "id": "flutter-app",
4
+ "title": "Flutter App",
5
+ "type": "object",
6
+ "properties": {
7
+ "name": {
8
+ "type": "string",
9
+ "description": "The name of the Flutter application (surface slug)",
10
+ "$default": {
11
+ "$source": "argv",
12
+ "index": 0
13
+ },
14
+ "x-prompt": "What name would you like to use for the app?"
15
+ },
16
+ "org": {
17
+ "type": "string",
18
+ "description": "Reverse-domain organization identifier used for the Android/iOS bundle id at bootstrap time",
19
+ "default": "com.example"
20
+ }
21
+ },
22
+ "required": ["name"]
23
+ }
@@ -0,0 +1,123 @@
1
+ ---
2
+ title: Concurrency
3
+ description: Goroutine lifecycle, errgroup, context cancellation, and supervised concurrency in Go services.
4
+ status: active
5
+ last_reviewed: 2026-05-26
6
+ ---
7
+ # Concurrency
8
+
9
+ ## TL;DR
10
+
11
+ Every goroutine we launch has an owner. We use `errgroup.WithContext` as the default supervision primitive, pass context everywhere, and never leave a goroutine running past the lifetime of the work it was started for.
12
+
13
+ ## Why this matters
14
+
15
+ A goroutine is cheap to start and invisible when it leaks. Service memory that grows slowly but never recovers is almost always leaked goroutines holding references. Cancellation signals that never propagate are why graceful shutdowns stall. Getting goroutine ownership right is not defensive programming — it is the minimum bar for production Go code.
16
+
17
+ ## The core rules
18
+
19
+ ### Never use bare `go func()`
20
+
21
+ A bare `go func()` that fires and forgets is a goroutine with no owner and no cancellation path. We don't write them. Every `go` statement launches a goroutine that is either:
22
+
23
+ 1. Tracked by an `errgroup.Group` or `sync.WaitGroup` that the caller waits on, or
24
+ 2. A long-lived background worker started at program entry and shut down via a dedicated `context.Context` and `sync.WaitGroup` on the composition root.
25
+
26
+ ### `errgroup.WithContext` is the default
27
+
28
+ For any fan-out work — fetching multiple resources concurrently, processing items in parallel — `errgroup.WithContext` is the idiomatic choice:
29
+
30
+ ```go
31
+ g, ctx := errgroup.WithContext(ctx)
32
+
33
+ g.Go(func() error {
34
+ return fetchTranscript(ctx, id)
35
+ })
36
+ g.Go(func() error {
37
+ return fetchMetadata(ctx, id)
38
+ })
39
+
40
+ if err := g.Wait(); err != nil {
41
+ return fmt.Errorf("fetching resources: %w", err)
42
+ }
43
+ ```
44
+
45
+ When the first goroutine returns an error, the derived `ctx` is cancelled, signalling the others to stop. `g.Wait()` collects and returns the first non-nil error after all goroutines exit.
46
+
47
+ ### Context propagation is non-negotiable
48
+
49
+ Every function that launches goroutines accepts a `context.Context` and passes it down. Every goroutine checks `ctx.Done()` on any blocking operation — I/O, channel receives, sleeps:
50
+
51
+ ```go
52
+ select {
53
+ case result := <-ch:
54
+ process(result)
55
+ case <-ctx.Done():
56
+ return ctx.Err()
57
+ }
58
+ ```
59
+
60
+ A goroutine that ignores its context will run past cancellation, block graceful shutdown, and mask errors. There are no exceptions.
61
+
62
+ ### Limit concurrency with semaphores
63
+
64
+ Unconstrained fan-out (one goroutine per item in a slice) exhausts file descriptors and saturates downstream services. Use a semaphore channel to bound parallelism:
65
+
66
+ ```go
67
+ const maxConcurrency = 10
68
+ sem := make(chan struct{}, maxConcurrency)
69
+
70
+ g, ctx := errgroup.WithContext(ctx)
71
+ for _, item := range items {
72
+ item := item
73
+ sem <- struct{}{}
74
+ g.Go(func() error {
75
+ defer func() { <-sem }()
76
+ return process(ctx, item)
77
+ })
78
+ }
79
+ if err := g.Wait(); err != nil {
80
+ return fmt.Errorf("processing items: %w", err)
81
+ }
82
+ ```
83
+
84
+ ### Shared state: channels first, mutexes second
85
+
86
+ When goroutines need to coordinate, pass ownership via channels rather than sharing pointers through mutexes. Channels make the ownership transfer explicit and visible. Use a `sync.Mutex` when a channel would be awkward — for example, protecting a map that is read from many goroutines and written to occasionally.
87
+
88
+ Never access shared state without synchronisation. The Go race detector (`-race`) is a required gate in CI.
89
+
90
+ ## Graceful shutdown
91
+
92
+ Background workers started at program entry must respect the root context. The composition root in `cmd/` creates a context cancelled by `SIGTERM`/`SIGINT`, and every long-lived worker selects on `ctx.Done()` to exit:
93
+
94
+ ```go
95
+ func (w *Worker) Run(ctx context.Context) error {
96
+ for {
97
+ select {
98
+ case <-ctx.Done():
99
+ return nil
100
+ case job := <-w.queue:
101
+ if err := w.process(ctx, job); err != nil {
102
+ // log, metric, continue — or propagate if fatal
103
+ }
104
+ }
105
+ }
106
+ }
107
+ ```
108
+
109
+ The composition root waits on all workers before the process exits. A service that kills itself with `os.Exit` rather than waiting for goroutines to drain is a service that drops in-flight requests and corrupts state.
110
+
111
+ ## Anti-patterns
112
+
113
+ - **Fire-and-forget goroutines.** If you don't track it, you don't own it.
114
+ - **Sharing context derivations across goroutines.** Each goroutine that needs cancellation derives its own from the parent via `errgroup.WithContext` or `context.WithCancel`.
115
+ - **Goroutines in `init()` or package-level `var`.** Goroutines belong in functions with explicit lifecycle management.
116
+ - **Infinite retry loops without backoff and cancellation.** A retry loop that ignores `ctx.Done()` will spin forever after shutdown.
117
+ - **Mutexes without deferred unlock.** Always `defer mu.Unlock()` immediately after acquiring the lock.
118
+
119
+ ## Further reading
120
+
121
+ - [sync/errgroup package](https://pkg.go.dev/golang.org/x/sync/errgroup) — the official docs with examples.
122
+ - *The Go Memory Model* (golang.org/ref/mem) — what happens before what, and why it matters.
123
+ - *Concurrency in Go*, Katherine Cox-Buday — patterns and pitfalls from production experience.
@@ -0,0 +1,70 @@
1
+ ---
2
+ title: Go Services
3
+ description: Idiomatic Go, a pure core with swappable edges, error handling, concurrency, and the shape of a Go microservice.
4
+ status: active
5
+ last_reviewed: 2026-05-26
6
+ ---
7
+ # Go Services
8
+
9
+ ## TL;DR
10
+
11
+ Our Go code is boring on purpose. It leans into the standard library, uses interfaces only where they earn their keep, treats errors as values with context, and structures every service as a pure core wrapped by swappable edges — the inward-dependency rule written the Go way.
12
+
13
+ ## Why this matters
14
+
15
+ Go rewards the engineer who resists cleverness. A Go codebase that reads like the standard library is one that new engineers — and AI agents — can contribute to the day they arrive. A Go codebase that imports a dozen frameworks and wraps every primitive in a "clean" abstraction is one where understanding costs precede any productive work. Keeping the core service legible is the highest-leverage investment we make.
16
+
17
+ ## Our principles
18
+
19
+ ### 1. Standard library first
20
+
21
+ `net/http`, `context`, `database/sql` — the standard library is the default, and we reach for a third-party package only when the standard library demonstrably cannot do the job. Frameworks that "wrap" the standard library to make it "easier" usually make it harder to reason about and harder for a new reader to follow.
22
+
23
+ ### 2. A pure core, swappable edges
24
+
25
+ Every service is a thin HTTP handler at the edge that extracts and validates inputs, an application service that orchestrates, domain types that hold rules, and interfaces — `Repository`, `MessageQueue`, `TextGenerator` — declared in the core package that consumes them, with Postgres-backed (and other technology-named) implementations at the edge. Packages nest under `internal/`: `internal/core/domain` and `internal/core/service` (the latter holds both the orchestration **and** the interfaces it calls), technology-named edge packages (`internal/postgres`, `internal/kafka`, `internal/pubsub`, `internal/httpclient`, `internal/websocket`, `internal/llm`), and `internal/entrypoints/api` for the HTTP edge, with composition roots in `cmd/`. Exported interfaces declared at the point of use, concrete edge types returned. `depguard` (in `.golangci.yml.template`) fails the build if `internal/core/...` imports an edge package — the inward-flow rule is a real gate, not a convention.
26
+
27
+ ### 3. Errors are values, and they carry context
28
+
29
+ We wrap errors with `fmt.Errorf("doing X: %w", err)` when adding context, and we inspect them with `errors.Is` and `errors.As` at the boundary. We *never* `panic` in service code; `panic` is reserved for truly unrecoverable conditions (a nil interface where the type system should have prevented it) and is recovered only at the HTTP boundary. Sentinel errors are defined where the caller must branch on them; structured error types are defined where the caller needs detail.
30
+
31
+ ### 4. Context is threaded everywhere
32
+
33
+ Every function that does I/O takes a `context.Context` as its first parameter. Cancellation and deadlines are respected. A goroutine that outlives its parent context without explicit opt-in is a bug. `context.Background()` appears only at program entry points and in tests.
34
+
35
+ ### 5. Concurrency is simple or explicit
36
+
37
+ `go` statements that fire-and-forget are banned; every goroutine is tracked by a `sync.WaitGroup`, an `errgroup.Group`, or a channel that signals completion. Leaked goroutines are how a service slowly eats its memory. Shared state is accessed through channels by default, through mutexes when a channel would be awkward, and never through silence.
38
+
39
+ ### 6. Interfaces are defined by consumers
40
+
41
+ We define interfaces in the package that consumes them — the "accept interfaces, return structs" rule. A package that defines an interface for its own use is leaking its internals as a public contract. Small interfaces (one to three methods) compose well; wide interfaces are a smell.
42
+
43
+ ### 7. Dependency injection is manual and explicit
44
+
45
+ We do not use runtime dependency-injection frameworks. Dependencies are passed into constructors, and the composition happens in a `cmd/` entry point. This is the "composition root" pattern, and in Go it is both trivial and powerful — every dependency is visible at build time, and cycles are impossible by construction.
46
+
47
+ ### 8. Tests use the real thing where possible
48
+
49
+ Service tests spin up a real Postgres container via Testcontainers and exercise the handler through HTTP. We mock only the expensive external edges (model clients, third-party APIs). See [Testing](testing.md) for Go-specific patterns.
50
+
51
+ ## Related docs
52
+
53
+ - [Concurrency](concurrency.md) — goroutine lifecycle, errgroup, and supervised concurrency.
54
+ - [Testing](testing.md) — Go honeycomb testing with Testcontainers and httptest.
55
+
56
+ ## Anti-patterns we reject
57
+
58
+ - **Framework-flavoured Go.** Heavy router libraries, "web framework" abstractions, ORMs that rewrite your queries. The standard library is enough.
59
+ - **`interface{}` or `any` as a type.** Except at the boundary of reflection-based code, `any` is a signal you lost the type war. Name the type.
60
+ - **Package-level mutable state.** Config, loggers, metrics registries stored in package variables. Inject them, always.
61
+ - **Goroutines without supervision.** If you launch it, you own its lifetime. Track it.
62
+ - **`init()` functions that do work.** `init` is for registering, not for running. Work belongs in `main`.
63
+ - **Pointer-to-struct when a value would do.** Pointers imply "this may be nil or may be mutated." If neither is true, pass the value.
64
+
65
+ ## Further reading
66
+
67
+ - *The Go Programming Language*, Donovan & Kernighan — the canonical text.
68
+ - *100 Go Mistakes and How to Avoid Them*, Teiva Harsanyi — a cadastre of the gotchas that bite real codebases.
69
+ - *Dave Cheney's blog* ([dave.cheney.net](https://dave.cheney.net)) — the single best source on Go idioms, errors, and testing.
70
+ - *The Go Memory Model* (golang.org/ref/mem) — read it at least once if you are writing concurrent code.