groundwork-method 0.0.1 → 0.11.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 (647) hide show
  1. package/CHANGELOG.md +823 -0
  2. package/LICENSE +21 -0
  3. package/README.md +44 -29
  4. package/bin/groundwork.js +1723 -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 +173 -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 +79 -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 +108 -0
  106. package/src/docs/principles/index.md +24 -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 +123 -0
  128. package/src/engineer-skills/groundwork-electron-engineer/references/documentation.md +126 -0
  129. package/src/engineer-skills/groundwork-electron-engineer/references/ipc-contracts.md +138 -0
  130. package/src/engineer-skills/groundwork-electron-engineer/references/observability.md +37 -0
  131. package/src/engineer-skills/groundwork-electron-engineer/references/packaging-and-updates.md +82 -0
  132. package/src/engineer-skills/groundwork-electron-engineer/references/performance-and-reliability.md +80 -0
  133. package/src/engineer-skills/groundwork-electron-engineer/references/process-model.md +94 -0
  134. package/src/engineer-skills/groundwork-electron-engineer/references/security.md +107 -0
  135. package/src/engineer-skills/groundwork-electron-engineer/references/testing-and-smoke.md +129 -0
  136. package/src/engineer-skills/groundwork-electron-engineer/references/theming-and-tokens.md +74 -0
  137. package/src/engineer-skills/groundwork-electron-engineer/sync-anchor.md +22 -0
  138. package/src/engineer-skills/groundwork-flutter-engineer/SKILL.md +114 -0
  139. package/src/engineer-skills/groundwork-flutter-engineer/references/accessibility.md +92 -0
  140. package/src/engineer-skills/groundwork-flutter-engineer/references/architecture.md +189 -0
  141. package/src/engineer-skills/groundwork-flutter-engineer/references/data-and-contracts.md +136 -0
  142. package/src/engineer-skills/groundwork-flutter-engineer/references/documentation.md +122 -0
  143. package/src/engineer-skills/groundwork-flutter-engineer/references/navigation.md +122 -0
  144. package/src/engineer-skills/groundwork-flutter-engineer/references/observability.md +37 -0
  145. package/src/engineer-skills/groundwork-flutter-engineer/references/performance-and-reliability.md +100 -0
  146. package/src/engineer-skills/groundwork-flutter-engineer/references/platform-channels.md +93 -0
  147. package/src/engineer-skills/groundwork-flutter-engineer/references/releases-and-distribution.md +84 -0
  148. package/src/engineer-skills/groundwork-flutter-engineer/references/security.md +96 -0
  149. package/src/engineer-skills/groundwork-flutter-engineer/references/state-management.md +166 -0
  150. package/src/engineer-skills/groundwork-flutter-engineer/references/testing.md +160 -0
  151. package/src/engineer-skills/groundwork-flutter-engineer/references/theming-and-design-tokens.md +109 -0
  152. package/src/engineer-skills/groundwork-flutter-engineer/references/widgets-and-composition.md +123 -0
  153. package/src/engineer-skills/groundwork-flutter-engineer/sync-anchor.md +24 -0
  154. package/src/engineer-skills/groundwork-go-engineer/SKILL.md +174 -0
  155. package/src/engineer-skills/groundwork-go-engineer/references/api-design.md +82 -0
  156. package/src/engineer-skills/groundwork-go-engineer/references/architecture.md +42 -0
  157. package/src/engineer-skills/groundwork-go-engineer/references/capability-ports.md +50 -0
  158. package/src/engineer-skills/groundwork-go-engineer/references/code-craft-security.md +34 -0
  159. package/src/engineer-skills/groundwork-go-engineer/references/concurrency.md +108 -0
  160. package/src/engineer-skills/groundwork-go-engineer/references/documentation.md +130 -0
  161. package/src/engineer-skills/groundwork-go-engineer/references/go-services.md +77 -0
  162. package/src/engineer-skills/groundwork-go-engineer/references/http-handlers.md +172 -0
  163. package/src/engineer-skills/groundwork-go-engineer/references/implementation-patterns.md +156 -0
  164. package/src/engineer-skills/groundwork-go-engineer/references/integration-realtime-data.md +57 -0
  165. package/src/engineer-skills/groundwork-go-engineer/references/observability.md +49 -0
  166. package/src/engineer-skills/groundwork-go-engineer/references/postgres.md +41 -0
  167. package/src/engineer-skills/groundwork-go-engineer/references/reliability-performance.md +105 -0
  168. package/src/engineer-skills/groundwork-go-engineer/references/testing.md +201 -0
  169. package/src/engineer-skills/groundwork-go-engineer/sync-anchor.md +20 -0
  170. package/src/engineer-skills/groundwork-nextjs-engineer/SKILL.md +112 -0
  171. package/src/engineer-skills/groundwork-nextjs-engineer/references/accessibility.md +111 -0
  172. package/src/engineer-skills/groundwork-nextjs-engineer/references/architecture.md +323 -0
  173. package/src/engineer-skills/groundwork-nextjs-engineer/references/data-fetching.md +458 -0
  174. package/src/engineer-skills/groundwork-nextjs-engineer/references/documentation.md +324 -0
  175. package/src/engineer-skills/groundwork-nextjs-engineer/references/error-boundaries.md +383 -0
  176. package/src/engineer-skills/groundwork-nextjs-engineer/references/mutations-and-forms.md +396 -0
  177. package/src/engineer-skills/groundwork-nextjs-engineer/references/observability.md +48 -0
  178. package/src/engineer-skills/groundwork-nextjs-engineer/references/performance-and-deployment.md +947 -0
  179. package/src/engineer-skills/groundwork-nextjs-engineer/references/routing-and-navigation.md +405 -0
  180. package/src/engineer-skills/groundwork-nextjs-engineer/references/security.md +131 -0
  181. package/src/engineer-skills/groundwork-nextjs-engineer/references/server-components.md +394 -0
  182. package/src/engineer-skills/groundwork-nextjs-engineer/references/tailwind-and-styling.md +134 -0
  183. package/src/engineer-skills/groundwork-nextjs-engineer/references/testing.md +491 -0
  184. package/src/engineer-skills/groundwork-nextjs-engineer/references/type-system.md +368 -0
  185. package/src/engineer-skills/groundwork-nextjs-engineer/references/ux-principles.md +230 -0
  186. package/src/engineer-skills/groundwork-nextjs-engineer/references/visual-language.md +69 -0
  187. package/src/engineer-skills/groundwork-nextjs-engineer/sync-anchor.md +16 -0
  188. package/src/engineer-skills/groundwork-python-engineer/SKILL.md +199 -0
  189. package/src/engineer-skills/groundwork-python-engineer/references/api-standards.md +88 -0
  190. package/src/engineer-skills/groundwork-python-engineer/references/architecture.md +57 -0
  191. package/src/engineer-skills/groundwork-python-engineer/references/async-patterns.md +103 -0
  192. package/src/engineer-skills/groundwork-python-engineer/references/capability-ports.md +44 -0
  193. package/src/engineer-skills/groundwork-python-engineer/references/database.md +88 -0
  194. package/src/engineer-skills/groundwork-python-engineer/references/documentation-mcp.md +167 -0
  195. package/src/engineer-skills/groundwork-python-engineer/references/implementation-patterns.md +166 -0
  196. package/src/engineer-skills/groundwork-python-engineer/references/ml-pipelines.md +119 -0
  197. package/src/engineer-skills/groundwork-python-engineer/references/ml-systems-ai-engineering.md +74 -0
  198. package/src/engineer-skills/groundwork-python-engineer/references/observability.md +57 -0
  199. package/src/engineer-skills/groundwork-python-engineer/references/resilience.md +126 -0
  200. package/src/engineer-skills/groundwork-python-engineer/references/security.md +148 -0
  201. package/src/engineer-skills/groundwork-python-engineer/references/testing.md +216 -0
  202. package/src/engineer-skills/groundwork-python-engineer/sync-anchor.md +20 -0
  203. package/src/generators/add-capability/generator.ts +70 -0
  204. package/src/generators/add-capability/schema.json +30 -0
  205. package/src/generators/capabilities/llm/capability.json +28 -0
  206. package/src/generators/capabilities/llm/providers/anthropic/footprint.json +13 -0
  207. package/src/generators/capabilities/llm/providers/anthropic/stacks/go/internal/llm/llm.go.template +102 -0
  208. package/src/generators/capabilities/llm/providers/anthropic/stacks/python/src/__packageName__/adapters/llm.py.template +61 -0
  209. package/src/generators/capabilities/llm/providers/local/footprint.json +13 -0
  210. package/src/generators/capabilities/llm/providers/local/stacks/go/internal/llm/llm.go.template +102 -0
  211. package/src/generators/capabilities/llm/providers/local/stacks/python/src/__packageName__/adapters/llm.py.template +53 -0
  212. package/src/generators/capabilities/llm/providers/localai/footprint.json +29 -0
  213. package/src/generators/capabilities/llm/providers/localai/stacks/go/internal/llm/llm.go.template +102 -0
  214. package/src/generators/capabilities/llm/providers/localai/stacks/python/src/__packageName__/adapters/llm.py.template +53 -0
  215. package/src/generators/capabilities/llm/providers/none/footprint.json +9 -0
  216. package/src/generators/capabilities/llm/providers/none/stacks/go/internal/llm/llm.go.template +35 -0
  217. package/src/generators/capabilities/llm/providers/none/stacks/python/src/__packageName__/adapters/llm.py.template +25 -0
  218. package/src/generators/capabilities/llm/providers/ollama/footprint.json +20 -0
  219. package/src/generators/capabilities/llm/providers/ollama/stacks/go/internal/llm/llm.go.template +102 -0
  220. package/src/generators/capabilities/llm/providers/ollama/stacks/python/src/__packageName__/adapters/llm.py.template +53 -0
  221. package/src/generators/capabilities/llm/providers/openai/footprint.json +13 -0
  222. package/src/generators/capabilities/llm/providers/openai/stacks/go/internal/llm/llm.go.template +98 -0
  223. package/src/generators/capabilities/llm/providers/openai/stacks/python/src/__packageName__/adapters/llm.py.template +60 -0
  224. package/src/generators/capabilities/llm/stacks/go/internal/core/service/llm.go.template +12 -0
  225. package/src/generators/capabilities/llm/stacks/go/internal/llm/llm_test.go.template +33 -0
  226. package/src/generators/capabilities/llm/stacks/python/src/__packageName__/core/llm.py.template +15 -0
  227. package/src/generators/capabilities/llm/stacks/python/tests/contracts/test_llm.py.template +37 -0
  228. package/src/generators/cli-app/files/README.md.template +76 -0
  229. package/src/generators/cli-app/files/build.mjs.template +15 -0
  230. package/src/generators/cli-app/files/package.json.template +21 -0
  231. package/src/generators/cli-app/files/src/cli.ts.template +67 -0
  232. package/src/generators/cli-app/files/src/commands/hello.ts.template +17 -0
  233. package/src/generators/cli-app/files/src/commands/status.ts.template +23 -0
  234. package/src/generators/cli-app/files/src/core/client.test.ts.template +80 -0
  235. package/src/generators/cli-app/files/src/core/client.ts.template +64 -0
  236. package/src/generators/cli-app/files/src/registry.test.ts.template +35 -0
  237. package/src/generators/cli-app/files/src/registry.ts.template +31 -0
  238. package/src/generators/cli-app/files/tsconfig.json.template +16 -0
  239. package/src/generators/cli-app/files/tsconfig.test.json.template +11 -0
  240. package/src/generators/cli-app/generator.ts +138 -0
  241. package/src/generators/cli-app/schema.json +24 -0
  242. package/src/generators/docs-site/files/.gitignore.ejs +40 -0
  243. package/src/generators/docs-site/files/app/docs/__slug__/page.tsx +101 -0
  244. package/src/generators/docs-site/files/app/docs/layout.tsx +14 -0
  245. package/src/generators/docs-site/files/app/docs.css +43 -0
  246. package/src/generators/docs-site/files/app/layout.tsx +24 -0
  247. package/src/generators/docs-site/files/app/page.tsx +135 -0
  248. package/src/generators/docs-site/files/app/source.ts +8 -0
  249. package/src/generators/docs-site/files/components/mermaid.tsx +67 -0
  250. package/src/generators/docs-site/files/next.config.mjs +10 -0
  251. package/src/generators/docs-site/files/package.json +32 -0
  252. package/src/generators/docs-site/files/pnpm-workspace.yaml +7 -0
  253. package/src/generators/docs-site/files/postcss.config.mjs +6 -0
  254. package/src/generators/docs-site/files/source.config.ts +77 -0
  255. package/src/generators/docs-site/files/tailwind.config.js +10 -0
  256. package/src/generators/docs-site/files/tsconfig.json +27 -0
  257. package/src/generators/docs-site/generator.ts +476 -0
  258. package/src/generators/docs-site/schema.json +17 -0
  259. package/src/generators/electron-app/docs/principles/stack/electron/index.md +49 -0
  260. package/src/generators/electron-app/docs/principles/stack/electron/ipc-contracts.md +71 -0
  261. package/src/generators/electron-app/docs/principles/stack/electron/packaging-and-updates.md +59 -0
  262. package/src/generators/electron-app/docs/principles/stack/electron/process-model.md +53 -0
  263. package/src/generators/electron-app/docs/principles/stack/electron/security.md +70 -0
  264. package/src/generators/electron-app/docs/principles/stack/typescript/frontend.md +65 -0
  265. package/src/generators/electron-app/files/.gitignore.template +20 -0
  266. package/src/generators/electron-app/files/README.md.template +125 -0
  267. package/src/generators/electron-app/files/electron.vite.config.ts +31 -0
  268. package/src/generators/electron-app/files/eslint.config.mjs +92 -0
  269. package/src/generators/electron-app/files/forge.config.ts.template +44 -0
  270. package/src/generators/electron-app/files/package.json.template +54 -0
  271. package/src/generators/electron-app/files/playwright.config.ts +18 -0
  272. package/src/generators/electron-app/files/project.json.template +65 -0
  273. package/src/generators/electron-app/files/src/main/core-client.test.ts +81 -0
  274. package/src/generators/electron-app/files/src/main/core-client.ts +55 -0
  275. package/src/generators/electron-app/files/src/main/index.ts +157 -0
  276. package/src/generators/electron-app/files/src/main/ipc.ts +52 -0
  277. package/src/generators/electron-app/files/src/main/policy.test.ts +71 -0
  278. package/src/generators/electron-app/files/src/main/policy.ts +73 -0
  279. package/src/generators/electron-app/files/src/preload/index.ts +23 -0
  280. package/src/generators/electron-app/files/src/renderer/index.html.template +20 -0
  281. package/src/generators/electron-app/files/src/renderer/src/App.test.tsx +61 -0
  282. package/src/generators/electron-app/files/src/renderer/src/App.tsx.template +43 -0
  283. package/src/generators/electron-app/files/src/renderer/src/assets/main.css +40 -0
  284. package/src/generators/electron-app/files/src/renderer/src/env.d.ts +14 -0
  285. package/src/generators/electron-app/files/src/renderer/src/main.tsx +25 -0
  286. package/src/generators/electron-app/files/src/shared/ipc.ts +54 -0
  287. package/src/generators/electron-app/files/tests/smoke/app.spec.ts.template +133 -0
  288. package/src/generators/electron-app/files/tool/electron_exec.sh.template +83 -0
  289. package/src/generators/electron-app/files/tsconfig.json +7 -0
  290. package/src/generators/electron-app/files/tsconfig.node.json +27 -0
  291. package/src/generators/electron-app/files/tsconfig.web.json +22 -0
  292. package/src/generators/electron-app/files/vitest.config.ts +32 -0
  293. package/src/generators/electron-app/files/vitest.setup.ts +1 -0
  294. package/src/generators/electron-app/generator.ts +288 -0
  295. package/src/generators/electron-app/schema.json +23 -0
  296. package/src/generators/flutter-app/docs/principles/stack/flutter/architecture.md +78 -0
  297. package/src/generators/flutter-app/docs/principles/stack/flutter/index.md +38 -0
  298. package/src/generators/flutter-app/docs/principles/stack/flutter/platform-channels.md +51 -0
  299. package/src/generators/flutter-app/docs/principles/stack/flutter/releases-and-distribution.md +59 -0
  300. package/src/generators/flutter-app/docs/principles/stack/flutter/state-management.md +85 -0
  301. package/src/generators/flutter-app/docs/principles/stack/flutter/testing.md +86 -0
  302. package/src/generators/flutter-app/docs/principles/stack/flutter/widgets-and-composition.md +69 -0
  303. package/src/generators/flutter-app/files/.gitignore.template +30 -0
  304. package/src/generators/flutter-app/files/README.md.template +100 -0
  305. package/src/generators/flutter-app/files/analysis_options.yaml.template +18 -0
  306. package/src/generators/flutter-app/files/integration_test/app_test.dart.template +64 -0
  307. package/src/generators/flutter-app/files/lib/app.dart.template +24 -0
  308. package/src/generators/flutter-app/files/lib/config/app_config.dart +15 -0
  309. package/src/generators/flutter-app/files/lib/data/repositories/status_repository.dart +36 -0
  310. package/src/generators/flutter-app/files/lib/data/services/api_client.dart +71 -0
  311. package/src/generators/flutter-app/files/lib/domain/models/health_status.dart +23 -0
  312. package/src/generators/flutter-app/files/lib/main.dart +11 -0
  313. package/src/generators/flutter-app/files/lib/router.dart +23 -0
  314. package/src/generators/flutter-app/files/lib/ui/core/theme/app_theme.dart +110 -0
  315. package/src/generators/flutter-app/files/lib/ui/home/home_view.dart +89 -0
  316. package/src/generators/flutter-app/files/lib/ui/home/home_view_model.dart.template +38 -0
  317. package/src/generators/flutter-app/files/project.json.template +51 -0
  318. package/src/generators/flutter-app/files/pubspec.yaml.template +47 -0
  319. package/src/generators/flutter-app/files/test/api_client_test.dart.template +63 -0
  320. package/src/generators/flutter-app/files/test/fakes/fake_status_repository.dart.template +19 -0
  321. package/src/generators/flutter-app/files/test/home_view_test.dart.template +58 -0
  322. package/src/generators/flutter-app/files/tool/flutter_exec.sh.template +60 -0
  323. package/src/generators/flutter-app/generator.ts +362 -0
  324. package/src/generators/flutter-app/schema.json +23 -0
  325. package/src/generators/go-microservice/docs/principles/stack/go/concurrency.md +123 -0
  326. package/src/generators/go-microservice/docs/principles/stack/go/index.md +70 -0
  327. package/src/generators/go-microservice/docs/principles/stack/go/testing.md +168 -0
  328. package/src/generators/go-microservice/files/.air.toml.template +38 -0
  329. package/src/generators/go-microservice/files/.env.template +4 -0
  330. package/src/generators/go-microservice/files/.golangci.yml.template +82 -0
  331. package/src/generators/go-microservice/files/Dockerfile.dev.template +12 -0
  332. package/src/generators/go-microservice/files/asyncapi-pubsub.yaml.template +33 -0
  333. package/src/generators/go-microservice/files/asyncapi-ws.yaml.template +34 -0
  334. package/src/generators/go-microservice/files/cmd/api/main.go.template +149 -0
  335. package/src/generators/go-microservice/files/cmd/api/main_test.go.template +99 -0
  336. package/src/generators/go-microservice/files/cmd/worker/cleanup/main.go.template +39 -0
  337. package/src/generators/go-microservice/files/db/schema.sql.template +24 -0
  338. package/src/generators/go-microservice/files/go.mod.template +39 -0
  339. package/src/generators/go-microservice/files/internal/config/config.go.template +52 -0
  340. package/src/generators/go-microservice/files/internal/config/otel.go.template +93 -0
  341. package/src/generators/go-microservice/files/internal/core/domain/errors.go.template +16 -0
  342. package/src/generators/go-microservice/files/internal/core/domain/model.go.template +28 -0
  343. package/src/generators/go-microservice/files/internal/core/domain/user.go.template +13 -0
  344. package/src/generators/go-microservice/files/internal/core/pagination.go.template +16 -0
  345. package/src/generators/go-microservice/files/internal/core/service/app_service.go.template +79 -0
  346. package/src/generators/go-microservice/files/internal/core/service/event_hub.go.template +9 -0
  347. package/src/generators/go-microservice/files/internal/core/service/message_queue.go.template +10 -0
  348. package/src/generators/go-microservice/files/internal/core/service/outbox_repository.go.template +31 -0
  349. package/src/generators/go-microservice/files/internal/core/service/repository.go.template +23 -0
  350. package/src/generators/go-microservice/files/internal/core/service/user_repository.go.template +15 -0
  351. package/src/generators/go-microservice/files/internal/core/service/user_service.go.template +43 -0
  352. package/src/generators/go-microservice/files/internal/entrypoints/api/app_handler.go.template +108 -0
  353. package/src/generators/go-microservice/files/internal/entrypoints/api/auth_middleware_test.go.template +52 -0
  354. package/src/generators/go-microservice/files/internal/entrypoints/api/clerk_webhook.go.template +202 -0
  355. package/src/generators/go-microservice/files/internal/entrypoints/api/clerk_webhook_test.go.template +82 -0
  356. package/src/generators/go-microservice/files/internal/entrypoints/api/health_handler.go.template +80 -0
  357. package/src/generators/go-microservice/files/internal/entrypoints/api/idempotency/middleware.go.template +87 -0
  358. package/src/generators/go-microservice/files/internal/entrypoints/api/idempotency/middleware_test.go.template +76 -0
  359. package/src/generators/go-microservice/files/internal/entrypoints/api/idempotency/repository.go.template +37 -0
  360. package/src/generators/go-microservice/files/internal/entrypoints/api/middleware_auth.go.template +40 -0
  361. package/src/generators/go-microservice/files/internal/entrypoints/api/middleware_loadshed.go.template +38 -0
  362. package/src/generators/go-microservice/files/internal/entrypoints/api/middleware_logging.go.template +40 -0
  363. package/src/generators/go-microservice/files/internal/entrypoints/api/middleware_ratelimit.go.template +48 -0
  364. package/src/generators/go-microservice/files/internal/entrypoints/api/middleware_test.go.template +81 -0
  365. package/src/generators/go-microservice/files/internal/entrypoints/api/router.go.template +105 -0
  366. package/src/generators/go-microservice/files/internal/entrypoints/api/types.go.template +70 -0
  367. package/src/generators/go-microservice/files/internal/entrypoints/api/websocket_handler.go.template +39 -0
  368. package/src/generators/go-microservice/files/internal/httpclient/http_client.go.template +87 -0
  369. package/src/generators/go-microservice/files/internal/kafka/kafka.go.template +34 -0
  370. package/src/generators/go-microservice/files/internal/postgres/postgres.go.template +195 -0
  371. package/src/generators/go-microservice/files/internal/postgres/postgres_test.go.template +156 -0
  372. package/src/generators/go-microservice/files/internal/postgres/user_repository.go.template +56 -0
  373. package/src/generators/go-microservice/files/internal/pubsub/gcp_pubsub.go.template +35 -0
  374. package/src/generators/go-microservice/files/internal/websocket/client.go.template +151 -0
  375. package/src/generators/go-microservice/files/internal/websocket/hub.go.template +261 -0
  376. package/src/generators/go-microservice/files/scripts/apply-schema.sh.template +21 -0
  377. package/src/generators/go-microservice/files/tools/tools.go.template +10 -0
  378. package/src/generators/go-microservice/generator.ts +240 -0
  379. package/src/generators/go-microservice/schema.json +63 -0
  380. package/src/generators/nextjs-app/docs/principles/stack/typescript/frontend.md +65 -0
  381. package/src/generators/nextjs-app/files/.dockerignore.template +7 -0
  382. package/src/generators/nextjs-app/files/.env.example.template +24 -0
  383. package/src/generators/nextjs-app/files/.gitignore.template +5 -0
  384. package/src/generators/nextjs-app/files/Dockerfile +53 -0
  385. package/src/generators/nextjs-app/files/app/(auth)/sign-in/__sign-in__/page.tsx.template +9 -0
  386. package/src/generators/nextjs-app/files/app/(auth)/sign-up/__sign-up__/page.tsx.template +9 -0
  387. package/src/generators/nextjs-app/files/app/api/config/route.ts.template +39 -0
  388. package/src/generators/nextjs-app/files/app/api/healthz/route.test.ts +15 -0
  389. package/src/generators/nextjs-app/files/app/api/healthz/route.ts +5 -0
  390. package/src/generators/nextjs-app/files/app/api/proxy/__path__/route.test.ts.template +55 -0
  391. package/src/generators/nextjs-app/files/app/api/proxy/__path__/route.ts.template +126 -0
  392. package/src/generators/nextjs-app/files/app/error.tsx +39 -0
  393. package/src/generators/nextjs-app/files/app/global-error.tsx +68 -0
  394. package/src/generators/nextjs-app/files/app/globals.css +105 -0
  395. package/src/generators/nextjs-app/files/app/layout.tsx +59 -0
  396. package/src/generators/nextjs-app/files/app/loading.tsx +13 -0
  397. package/src/generators/nextjs-app/files/app/not-found.tsx +30 -0
  398. package/src/generators/nextjs-app/files/app/page.tsx +20 -0
  399. package/src/generators/nextjs-app/files/components/providers/default.tsx +19 -0
  400. package/src/generators/nextjs-app/files/components/providers/production.tsx +32 -0
  401. package/src/generators/nextjs-app/files/components/providers/telemetry.tsx +76 -0
  402. package/src/generators/nextjs-app/files/components/render-smoke.test.tsx +29 -0
  403. package/src/generators/nextjs-app/files/components/theme-provider.tsx +11 -0
  404. package/src/generators/nextjs-app/files/components.json +21 -0
  405. package/src/generators/nextjs-app/files/eslint.config.mjs +120 -0
  406. package/src/generators/nextjs-app/files/hooks/use-toast.ts +7 -0
  407. package/src/generators/nextjs-app/files/instrumentation.ts +90 -0
  408. package/src/generators/nextjs-app/files/lib/api/fetcher.ts.template +130 -0
  409. package/src/generators/nextjs-app/files/lib/config.ts +21 -0
  410. package/src/generators/nextjs-app/files/lib/logger.ts +29 -0
  411. package/src/generators/nextjs-app/files/lib/schemas/index.ts +19 -0
  412. package/src/generators/nextjs-app/files/lib/utils.ts +6 -0
  413. package/src/generators/nextjs-app/files/next.config.mjs +9 -0
  414. package/src/generators/nextjs-app/files/package.json +70 -0
  415. package/src/generators/nextjs-app/files/postcss.config.mjs +8 -0
  416. package/src/generators/nextjs-app/files/proxy.test.ts.template +30 -0
  417. package/src/generators/nextjs-app/files/proxy.ts +31 -0
  418. package/src/generators/nextjs-app/files/public/.gitkeep +1 -0
  419. package/src/generators/nextjs-app/files/tsconfig.json +42 -0
  420. package/src/generators/nextjs-app/files/vitest.config.mts +15 -0
  421. package/src/generators/nextjs-app/files/vitest.setup.ts +7 -0
  422. package/src/generators/nextjs-app/generator.ts +307 -0
  423. package/src/generators/nextjs-app/schema.json +44 -0
  424. package/src/generators/python-microservice/docs/principles/stack/python/async.md +168 -0
  425. package/src/generators/python-microservice/docs/principles/stack/python/documentation.md +240 -0
  426. package/src/generators/python-microservice/docs/principles/stack/python/mcp.md +147 -0
  427. package/src/generators/python-microservice/docs/principles/stack/python/resilience.md +193 -0
  428. package/src/generators/python-microservice/docs/principles/stack/python/testing.md +322 -0
  429. package/src/generators/python-microservice/files/.env.example.template +30 -0
  430. package/src/generators/python-microservice/files/Dockerfile.template +36 -0
  431. package/src/generators/python-microservice/files/db/schema.sql.template +19 -0
  432. package/src/generators/python-microservice/files/pyproject.toml.template +76 -0
  433. package/src/generators/python-microservice/files/scripts/apply-schema.sh.template +25 -0
  434. package/src/generators/python-microservice/files/src/__packageName__/adapters/comfyui.py.template +87 -0
  435. package/src/generators/python-microservice/files/src/__packageName__/adapters/config.py.template +48 -0
  436. package/src/generators/python-microservice/files/src/__packageName__/adapters/database.py.template +21 -0
  437. package/src/generators/python-microservice/files/src/__packageName__/adapters/message_queue.py.template +29 -0
  438. package/src/generators/python-microservice/files/src/__packageName__/adapters/repository.py.template +130 -0
  439. package/src/generators/python-microservice/files/src/__packageName__/adapters/telemetry.py.template +68 -0
  440. package/src/generators/python-microservice/files/src/__packageName__/adapters/websocket_hub.py.template +36 -0
  441. package/src/generators/python-microservice/files/src/__packageName__/core/domain/entities.py.template +22 -0
  442. package/src/generators/python-microservice/files/src/__packageName__/core/domain/exceptions.py.template +43 -0
  443. package/src/generators/python-microservice/files/src/__packageName__/core/ports.py.template +42 -0
  444. package/src/generators/python-microservice/files/src/__packageName__/core/service/example_service.py.template +68 -0
  445. package/src/generators/python-microservice/files/src/__packageName__/entrypoints/api/dependencies.py.template +50 -0
  446. package/src/generators/python-microservice/files/src/__packageName__/entrypoints/api/middleware.py.template +131 -0
  447. package/src/generators/python-microservice/files/src/__packageName__/entrypoints/api/router.py.template +37 -0
  448. package/src/generators/python-microservice/files/src/__packageName__/entrypoints/api/websocket_handler.py.template +20 -0
  449. package/src/generators/python-microservice/files/src/__packageName__/entrypoints/worker/cleanup.py.template +35 -0
  450. package/src/generators/python-microservice/files/src/__packageName__/entrypoints/worker/worker.py.template +28 -0
  451. package/src/generators/python-microservice/files/src/__packageName__/main.py.template +108 -0
  452. package/src/generators/python-microservice/files/tests/test_main.py.template +74 -0
  453. package/src/generators/python-microservice/files/tests/test_middleware.py.template +109 -0
  454. package/src/generators/python-microservice/files/tests/test_worker.py.template +16 -0
  455. package/src/generators/python-microservice/generator.ts +286 -0
  456. package/src/generators/python-microservice/schema.json +86 -0
  457. package/src/generators/shared/brand-tokens.ts +301 -0
  458. package/src/generators/shared/capabilities.ts +349 -0
  459. package/src/generators/shared/provenance.ts +61 -0
  460. package/src/generators/shared/scaffold-helpers.ts +309 -0
  461. package/src/generators/system-test-runner/NATIVE-CHECK-CONTRACT.md +20 -0
  462. package/src/generators/system-test-runner/files/tests/bets/.gitkeep +0 -0
  463. package/src/generators/system-test-runner/files/tests/bets/_archive/.gitkeep +0 -0
  464. package/src/generators/system-test-runner/files/tests/conftest.py.template +503 -0
  465. package/src/generators/system-test-runner/files/tests/pyproject.toml.template +20 -0
  466. package/src/generators/system-test-runner/files/tests/system/pages/__init__.py.template +9 -0
  467. package/src/generators/system-test-runner/files/tests/system/pages/base_page.py.template +36 -0
  468. package/src/generators/system-test-runner/files/tests/system/test_a11y_smoke.py.template +132 -0
  469. package/src/generators/system-test-runner/files/tests/system/test_contract_conformance.py.template +140 -0
  470. package/src/generators/system-test-runner/files/tests/system/test_layout_geometry.py.template +109 -0
  471. package/src/generators/system-test-runner/files/tests/system/test_render_smoke.py.template +257 -0
  472. package/src/generators/system-test-runner/files/tests/system/test_system.py.template +158 -0
  473. package/src/generators/system-test-runner/files/tests/system/test_token_conformance.py.template +206 -0
  474. package/src/generators/system-test-runner/files/tests/system/test_visual_regression.py.template +104 -0
  475. package/src/generators/system-test-runner/generator.ts +196 -0
  476. package/src/generators/system-test-runner/schema.json +24 -0
  477. package/src/generators/workspace-dev-cli/cli-src/build.mjs +42 -0
  478. package/src/generators/workspace-dev-cli/cli-src/dist/dev-bundle.js +2168 -0
  479. package/src/generators/workspace-dev-cli/cli-src/src/commands/bet.ts +442 -0
  480. package/src/generators/workspace-dev-cli/cli-src/src/commands/completion.ts +87 -0
  481. package/src/generators/workspace-dev-cli/cli-src/src/commands/doctor.ts +139 -0
  482. package/src/generators/workspace-dev-cli/cli-src/src/commands/lifecycle.ts +548 -0
  483. package/src/generators/workspace-dev-cli/cli-src/src/commands/quality.ts +127 -0
  484. package/src/generators/workspace-dev-cli/cli-src/src/commands/surface.ts +214 -0
  485. package/src/generators/workspace-dev-cli/cli-src/src/index.ts +127 -0
  486. package/src/generators/workspace-dev-cli/cli-src/src/registry.ts +194 -0
  487. package/src/generators/workspace-dev-cli/cli-src/src/theme/color.ts +130 -0
  488. package/src/generators/workspace-dev-cli/cli-src/src/theme/render.ts +158 -0
  489. package/src/generators/workspace-dev-cli/cli-src/src/theme/tokens.ts +122 -0
  490. package/src/generators/workspace-dev-cli/cli-src/src/util/context.ts +43 -0
  491. package/src/generators/workspace-dev-cli/cli-src/src/util/extensions.ts +99 -0
  492. package/src/generators/workspace-dev-cli/cli-src/src/util/paths.ts +46 -0
  493. package/src/generators/workspace-dev-cli/cli-src/src/util/proc.ts +106 -0
  494. package/src/generators/workspace-dev-cli/cli-src/src/util/prompt.ts +108 -0
  495. package/src/generators/workspace-dev-cli/cli-src/src/util/runners.ts +70 -0
  496. package/src/generators/workspace-dev-cli/cli-src/src/util/services.ts +221 -0
  497. package/src/generators/workspace-dev-cli/cli-src/src/util/version.ts +21 -0
  498. package/src/generators/workspace-dev-cli/cli-src/tsconfig.json +16 -0
  499. package/src/generators/workspace-dev-cli/files/.agents/skills/workspace-cli/SKILL.md.template +74 -0
  500. package/src/generators/workspace-dev-cli/files/dev.template +16 -0
  501. package/src/generators/workspace-dev-cli/files/docker-compose.yml.template +20 -0
  502. package/src/generators/workspace-dev-cli/files/scripts/cli/templates/milestone-test.pytmpl.template +46 -0
  503. package/src/generators/workspace-dev-cli/files/scripts/cli/templates/slice-test.pytmpl.template +38 -0
  504. package/src/generators/workspace-dev-cli/generator.ts +136 -0
  505. package/src/generators/workspace-dev-cli/schema.json +22 -0
  506. package/src/hidden-skills/code-intelligence.md +135 -0
  507. package/src/hidden-skills/groundwork-architect/SKILL.md +114 -0
  508. package/src/hidden-skills/groundwork-architect/references/agentic-systems.md +44 -0
  509. package/src/hidden-skills/groundwork-architect/references/ai-native-architecture.md +37 -0
  510. package/src/hidden-skills/groundwork-architect/references/api-and-contracts.md +45 -0
  511. package/src/hidden-skills/groundwork-architect/references/core-and-boundaries.md +45 -0
  512. package/src/hidden-skills/groundwork-architect/references/data-architecture.md +33 -0
  513. package/src/hidden-skills/groundwork-architect/references/decision-records.md +34 -0
  514. package/src/hidden-skills/groundwork-architect/references/durable-execution.md +45 -0
  515. package/src/hidden-skills/groundwork-architect/references/evolutionary-architecture.md +37 -0
  516. package/src/hidden-skills/groundwork-architect/references/identity-and-access.md +41 -0
  517. package/src/hidden-skills/groundwork-architect/references/integration-patterns.md +39 -0
  518. package/src/hidden-skills/groundwork-architect/references/observability.md +36 -0
  519. package/src/hidden-skills/groundwork-architect/references/performance-and-scale.md +41 -0
  520. package/src/hidden-skills/groundwork-architect/references/platform-and-delivery.md +47 -0
  521. package/src/hidden-skills/groundwork-architect/references/realtime-and-async.md +28 -0
  522. package/src/hidden-skills/groundwork-architect/references/reliability.md +31 -0
  523. package/src/hidden-skills/groundwork-architect/references/security-and-trust.md +47 -0
  524. package/src/hidden-skills/groundwork-architect/references/surface-architecture.md +40 -0
  525. package/src/hidden-skills/groundwork-architect/sync-anchor.md +34 -0
  526. package/src/hidden-skills/groundwork-architecture/architecture-template.md +50 -0
  527. package/src/hidden-skills/groundwork-architecture/instructions.md +139 -0
  528. package/src/hidden-skills/groundwork-architecture/phases/01-context-ingestion.md +18 -0
  529. package/src/hidden-skills/groundwork-architecture/phases/02-technical-constraints.md +27 -0
  530. package/src/hidden-skills/groundwork-architecture/phases/03-service-design.md +19 -0
  531. package/src/hidden-skills/groundwork-architecture/phases/04-data-flow-communication.md +23 -0
  532. package/src/hidden-skills/groundwork-architecture/phases/05-component-boundaries-contracts.md +17 -0
  533. package/src/hidden-skills/groundwork-architecture/phases/06-draft-review-present.md +38 -0
  534. package/src/hidden-skills/groundwork-architecture/phases/07-commit.md +33 -0
  535. package/src/hidden-skills/groundwork-architecture/templates/architecture-cache.md +43 -0
  536. package/src/hidden-skills/groundwork-architecture-extract/instructions.md +163 -0
  537. package/src/hidden-skills/groundwork-architecture-extract/templates/architecture-extract-cache.md +21 -0
  538. package/src/hidden-skills/groundwork-bet/briefs/acceptance-auditor.md +68 -0
  539. package/src/hidden-skills/groundwork-bet/briefs/blind-reviewer.md +56 -0
  540. package/src/hidden-skills/groundwork-bet/briefs/coverage-auditor.md +95 -0
  541. package/src/hidden-skills/groundwork-bet/briefs/edge-case-tracer.md +64 -0
  542. package/src/hidden-skills/groundwork-bet/briefs/experience-auditor.md +83 -0
  543. package/src/hidden-skills/groundwork-bet/briefs/slice-worker.md +257 -0
  544. package/src/hidden-skills/groundwork-bet/instructions.md +88 -0
  545. package/src/hidden-skills/groundwork-bet/templates/bet-progress-test.md +115 -0
  546. package/src/hidden-skills/groundwork-bet/templates/change-proposal.md +38 -0
  547. package/src/hidden-skills/groundwork-bet/templates/decomposition/meta.json +4 -0
  548. package/src/hidden-skills/groundwork-bet/templates/decomposition/milestone-index.md +31 -0
  549. package/src/hidden-skills/groundwork-bet/templates/decomposition/slice.md +31 -0
  550. package/src/hidden-skills/groundwork-bet/templates/pitch.md +45 -0
  551. package/src/hidden-skills/groundwork-bet/templates/technical-design/01-ui-design.md +51 -0
  552. package/src/hidden-skills/groundwork-bet/templates/technical-design/02-data-flows.md +36 -0
  553. package/src/hidden-skills/groundwork-bet/templates/technical-design/03-api-design.md +90 -0
  554. package/src/hidden-skills/groundwork-bet/templates/technical-design/04-data-design.md +29 -0
  555. package/src/hidden-skills/groundwork-bet/workflows/01-discovery.md +200 -0
  556. package/src/hidden-skills/groundwork-bet/workflows/02-design.md +178 -0
  557. package/src/hidden-skills/groundwork-bet/workflows/03-decomposition.md +242 -0
  558. package/src/hidden-skills/groundwork-bet/workflows/04-delivery.md +226 -0
  559. package/src/hidden-skills/groundwork-bet/workflows/05-validation.md +210 -0
  560. package/src/hidden-skills/groundwork-design-system/instructions.md +125 -0
  561. package/src/hidden-skills/groundwork-design-system/templates/brand-tokens.md +182 -0
  562. package/src/hidden-skills/groundwork-design-system/templates/design-system-cache.md +64 -0
  563. package/src/hidden-skills/groundwork-design-system/tracks/_foundation.md +136 -0
  564. package/src/hidden-skills/groundwork-design-system/tracks/agentic-protocol.md +269 -0
  565. package/src/hidden-skills/groundwork-design-system/tracks/cli.md +355 -0
  566. package/src/hidden-skills/groundwork-design-system/tracks/graphical-ui.md +330 -0
  567. package/src/hidden-skills/groundwork-design-system-extract/instructions.md +124 -0
  568. package/src/hidden-skills/groundwork-design-system-extract/templates/design-system-extract-cache.md +19 -0
  569. package/src/hidden-skills/groundwork-designer/SKILL.md +108 -0
  570. package/src/hidden-skills/groundwork-designer/references/accessibility.md +33 -0
  571. package/src/hidden-skills/groundwork-designer/references/ai-native-design.md +37 -0
  572. package/src/hidden-skills/groundwork-designer/references/design-review.md +29 -0
  573. package/src/hidden-skills/groundwork-designer/references/design-systems-and-tokens.md +33 -0
  574. package/src/hidden-skills/groundwork-designer/references/interaction-and-motion.md +37 -0
  575. package/src/hidden-skills/groundwork-designer/references/layout-and-space.md +33 -0
  576. package/src/hidden-skills/groundwork-designer/references/usability-and-ux.md +33 -0
  577. package/src/hidden-skills/groundwork-designer/references/visual-craft.md +49 -0
  578. package/src/hidden-skills/groundwork-designer/sync-anchor.md +20 -0
  579. package/src/hidden-skills/groundwork-doc-sync/instructions.md +100 -0
  580. package/src/hidden-skills/groundwork-elicit/instructions.md +66 -0
  581. package/src/hidden-skills/groundwork-elicit/methods.md +65 -0
  582. package/src/hidden-skills/groundwork-infra-adopt/instructions.md +168 -0
  583. package/src/hidden-skills/groundwork-infra-adopt/templates/infra-adopt-cache.md +21 -0
  584. package/src/hidden-skills/groundwork-mvp/instructions.md +223 -0
  585. package/src/hidden-skills/groundwork-mvp/templates/mvp-cache.md +9 -0
  586. package/src/hidden-skills/groundwork-patch/instructions.md +40 -0
  587. package/src/hidden-skills/groundwork-persona/instructions.md +65 -0
  588. package/src/hidden-skills/groundwork-product/SKILL.md +102 -0
  589. package/src/hidden-skills/groundwork-product/references/ai-native-product.md +45 -0
  590. package/src/hidden-skills/groundwork-product/references/discovery-and-opportunity.md +38 -0
  591. package/src/hidden-skills/groundwork-product/references/product-risks.md +52 -0
  592. package/src/hidden-skills/groundwork-product/references/requirements-and-specs.md +39 -0
  593. package/src/hidden-skills/groundwork-product/references/scope-and-sequencing.md +35 -0
  594. package/src/hidden-skills/groundwork-product/references/shaping-and-appetite.md +48 -0
  595. package/src/hidden-skills/groundwork-product/references/success-metrics-and-signals.md +37 -0
  596. package/src/hidden-skills/groundwork-product/sync-anchor.md +19 -0
  597. package/src/hidden-skills/groundwork-product-brief/instructions.md +231 -0
  598. package/src/hidden-skills/groundwork-product-brief-extract/instructions.md +139 -0
  599. package/src/hidden-skills/groundwork-product-brief-extract/templates/product-brief-extract-cache.md +17 -0
  600. package/src/hidden-skills/groundwork-review/checklists/architecture.md +93 -0
  601. package/src/hidden-skills/groundwork-review/checklists/bet-pitch.md +94 -0
  602. package/src/hidden-skills/groundwork-review/checklists/decomposition.md +135 -0
  603. package/src/hidden-skills/groundwork-review/checklists/design-system.md +85 -0
  604. package/src/hidden-skills/groundwork-review/checklists/domain-entity.md +66 -0
  605. package/src/hidden-skills/groundwork-review/checklists/implementation-readiness.md +47 -0
  606. package/src/hidden-skills/groundwork-review/checklists/infrastructure.md +68 -0
  607. package/src/hidden-skills/groundwork-review/checklists/maturity.md +71 -0
  608. package/src/hidden-skills/groundwork-review/checklists/product-brief.md +69 -0
  609. package/src/hidden-skills/groundwork-review/checklists/technical-design.md +112 -0
  610. package/src/hidden-skills/groundwork-review/instructions.md +181 -0
  611. package/src/hidden-skills/groundwork-scaffold/instructions.md +254 -0
  612. package/src/hidden-skills/groundwork-scaffold/phases/01-ingestion-service-mapping.md +87 -0
  613. package/src/hidden-skills/groundwork-scaffold/phases/02-scaffolding-execution.md +15 -0
  614. package/src/hidden-skills/groundwork-scaffold/phases/03-service-documentation-api-stubs.md +100 -0
  615. package/src/hidden-skills/groundwork-scaffold/phases/04-infrastructure-verification.md +17 -0
  616. package/src/hidden-skills/groundwork-scaffold/phases/05-draft-review.md +19 -0
  617. package/src/hidden-skills/groundwork-scaffold/phases/06-commit.md +19 -0
  618. package/src/hidden-skills/groundwork-scaffold/templates/scaffold-cache.md +23 -0
  619. package/src/hidden-skills/groundwork-scan/instructions.md +164 -0
  620. package/src/hidden-skills/groundwork-scan/references/digest-schema.md +66 -0
  621. package/src/hidden-skills/groundwork-scan/references/exclusions.md +44 -0
  622. package/src/hidden-skills/groundwork-scan/templates/architecture-findings.md +42 -0
  623. package/src/hidden-skills/groundwork-scan/templates/design-findings.md +23 -0
  624. package/src/hidden-skills/groundwork-scan/templates/overview.md +26 -0
  625. package/src/hidden-skills/groundwork-scan/templates/product-findings.md +23 -0
  626. package/src/hidden-skills/groundwork-scan/templates/scan-state.json +19 -0
  627. package/src/hidden-skills/groundwork-stack-forge/instructions.md +150 -0
  628. package/src/hidden-skills/groundwork-stack-forge/references/authoring-engineer-skills.md +107 -0
  629. package/src/hidden-skills/groundwork-surface-activation/instructions.md +138 -0
  630. package/src/hidden-skills/groundwork-update/briefs/reconcile-worker.md +196 -0
  631. package/src/hidden-skills/groundwork-update/instructions.md +200 -0
  632. package/src/hidden-skills/groundwork-writer/SKILL.md +278 -0
  633. package/src/hidden-skills/maturity-model.md +125 -0
  634. package/src/hidden-skills/operating-contract.md +400 -0
  635. package/src/hidden-skills/repo-map-schema.md +90 -0
  636. package/src/hidden-skills/templates/adr.md +57 -0
  637. package/src/hidden-skills/templates/capability-ports.md +71 -0
  638. package/src/hidden-skills/templates/discovery-notes.md +33 -0
  639. package/src/hidden-skills/templates/domain-entity.md +80 -0
  640. package/src/hidden-skills/templates/gap-ledger.md +21 -0
  641. package/src/hidden-skills/templates/handoff.md +37 -0
  642. package/src/hidden-skills/templates/maturity.md +39 -0
  643. package/src/hidden-skills/templates/surfaces.md +207 -0
  644. package/src/skills/groundwork-check/SKILL.md +56 -0
  645. package/src/skills/groundwork-check/instructions.md +70 -0
  646. package/src/skills/groundwork-orchestrator/SKILL.md +176 -0
  647. package/src/skills/groundwork-orchestrator/workflow-index.md +50 -0
@@ -0,0 +1,126 @@
1
+ # Resilience
2
+
3
+ ## Timeouts
4
+
5
+ Set explicit timeouts on every outbound HTTP call:
6
+
7
+ ```python
8
+ import httpx
9
+
10
+ client = httpx.AsyncClient(
11
+ timeout=httpx.Timeout(
12
+ connect=5.0, # TCP connection
13
+ read=30.0, # Full response body
14
+ write=10.0, # Request body
15
+ pool=5.0, # Connection from pool
16
+ )
17
+ )
18
+ ```
19
+
20
+ Own the timeout at the provider level. The `read` timeout is critical for ML/API providers — a streaming response that hangs mid-way waits indefinitely without it.
21
+
22
+ ## Retries
23
+
24
+ Use `tenacity` for retry logic:
25
+
26
+ ```python
27
+ from tenacity import (
28
+ retry,
29
+ retry_if_exception_type,
30
+ stop_after_attempt,
31
+ wait_exponential_jitter,
32
+ )
33
+
34
+ @retry(
35
+ retry=retry_if_exception_type(TransientError),
36
+ wait=wait_exponential_jitter(initial=1, max=30),
37
+ stop=stop_after_attempt(3),
38
+ )
39
+ async def _call_with_retry(self, payload: dict) -> dict:
40
+ return await self._client.post(payload)
41
+ ```
42
+
43
+ **Jitter is not optional.** Backoff without jitter causes thundering herd.
44
+
45
+ **Only retry transient errors.** A `400` is permanent — retrying wastes budget. Map errors to domain types before retrying.
46
+
47
+ ## Circuit Breakers
48
+
49
+ Prevent cascading failure from a down dependency:
50
+
51
+ ```python
52
+ from circuitbreaker import circuit
53
+
54
+ @circuit(
55
+ failure_threshold=5,
56
+ recovery_timeout=30,
57
+ expected_exception=TransientError,
58
+ )
59
+ async def complete(self, prompt: str) -> str:
60
+ return await self._client.complete(prompt)
61
+ ```
62
+
63
+ **Set `expected_exception` explicitly.** A breaker that trips on all exceptions produces false opens.
64
+
65
+ ## Graceful Shutdown
66
+
67
+ FastAPI + Uvicorn handle `SIGTERM` correctly when `lifespan` is used:
68
+
69
+ 1. `SIGTERM` received
70
+ 2. Stop accepting new connections
71
+ 3. In-flight requests and `BackgroundTasks` complete
72
+ 4. `lifespan` cleanup runs
73
+ 5. Process exits
74
+
75
+ Keep the shutdown path fast:
76
+
77
+ ```python
78
+ @asynccontextmanager
79
+ async def lifespan(app: FastAPI):
80
+ resources = await initialise_resources()
81
+ yield
82
+ await asyncio.wait_for(resources.close(), timeout=4.0)
83
+ ```
84
+
85
+ ## Health Probes
86
+
87
+ **`/healthz` (liveness):** Returns `200` unconditionally. No external dependency checks.
88
+
89
+ **`/readyz` (readiness):** Returns `200` only after startup completes. Returns `503` during startup and shutdown.
90
+
91
+ ```python
92
+ @router.get("/healthz")
93
+ async def liveness() -> dict:
94
+ return {"status": "ok"}
95
+
96
+ @router.get("/readyz")
97
+ async def readiness(state: AppState = Depends(get_app_state)) -> dict:
98
+ if not state.ready:
99
+ raise HTTPException(status_code=503, detail="not ready")
100
+ return {"status": "ready"}
101
+ ```
102
+
103
+ ## Graceful Degradation
104
+
105
+ Return partial results rather than hard errors when non-critical steps fail:
106
+
107
+ ```python
108
+ async def process_with_enrichment(self, input_uri: str) -> Result:
109
+ base = await self.processor.process(input_uri)
110
+ try:
111
+ enrichment = await self.enricher.enrich(base)
112
+ return base.with_enrichment(enrichment)
113
+ except EnrichmentUnavailableError:
114
+ logger.warning("enrichment.unavailable", item_id=base.id)
115
+ return base
116
+ ```
117
+
118
+ Log every degraded response with structured context. Silent degradation is invisible in production.
119
+
120
+ ## Anti-Patterns
121
+
122
+ - **No timeout on provider calls.** Hung connections hold indefinitely.
123
+ - **Retrying non-transient errors.** A `400` never succeeds on retry.
124
+ - **Circuit breaker on all exceptions.** False opens from caller errors.
125
+ - **Long-running lifespan shutdown.** Force-killed by orchestrator.
126
+ - **Silent degradation.** Partial results without structured logs.
@@ -0,0 +1,148 @@
1
+ # Security
2
+
3
+ This service is a trust boundary. Everything outside it — clients, webhooks, queue events, upstream APIs, model output — is hostile until validated. This file is the Python idiom of the framework security canon (`docs/principles/quality/security.md`); when this file and the canon disagree, the canon wins and this file is the one to fix.
4
+
5
+ The controls below are enforced at the FastAPI entrypoint and the adapter edge, not scattered through the Domain. The boundary is validated once and explicitly; inside it, the core trusts its own types.
6
+
7
+ ## 1. Input is hostile; validate at the boundary
8
+
9
+ Every inbound payload is a Pydantic model parsed at the route, not a `dict` read field-by-field. Pydantic v2 validation *is* the boundary check — a request that fails parsing never reaches a service.
10
+
11
+ ```python
12
+ from pydantic import BaseModel, Field, EmailStr
13
+
14
+ class CreateOrderRequest(BaseModel):
15
+ model_config = {"extra": "forbid"} # reject unknown fields, never silently drop
16
+
17
+ customer_email: EmailStr
18
+ quantity: int = Field(gt=0, le=1000)
19
+ note: str = Field(default="", max_length=2000)
20
+
21
+ @router.post("/orders")
22
+ async def create_order(body: CreateOrderRequest) -> OrderResponse:
23
+ # body is validated; the service receives a typed domain request, not raw input
24
+ ...
25
+ ```
26
+
27
+ - `extra="forbid"` turns mass-assignment and typo'd fields into a `422`, not a silent accept.
28
+ - Constrain at the type (`gt`, `le`, `max_length`, `EmailStr`, `Literal`), so the constraint travels with the field and cannot be forgotten by a caller.
29
+ - Do not re-validate between internal callers — the core trusts its own dataclasses (`references/implementation-patterns.md` → Strict Typing). One boundary, scrutinised; no defensive re-checks inside.
30
+
31
+ ## 2. Parameterised queries — never string-built SQL
32
+
33
+ SQL injection is closed by construction: the query text is constant and every value is a bound parameter. SQLAlchemy and the driver do the binding; an f-string carrying user input into SQL is a defect.
34
+
35
+ ```python
36
+ from sqlalchemy import select, text
37
+
38
+ # ORM — values are bound, never interpolated
39
+ stmt = select(OrderRow).where(OrderRow.customer_id == customer_id)
40
+
41
+ # Raw SQL when unavoidable — named bind parameters, never an f-string
42
+ await session.execute(
43
+ text("SELECT * FROM orders WHERE customer_id = :cid"),
44
+ {"cid": customer_id},
45
+ )
46
+ ```
47
+
48
+ The session lifecycle and the repository port live in `references/database.md`; security adds one rule on top — no user value reaches a query except as a bound parameter, and table/column names are never taken from input.
49
+
50
+ ## 3. Authorization at the dependency boundary
51
+
52
+ Authentication establishes *who*; authorization decides *what they may do*. Both are FastAPI dependencies on the route, enforced through one path, not re-implemented per handler.
53
+
54
+ ```python
55
+ from fastapi import Depends, HTTPException, status
56
+
57
+ async def require_order_access(
58
+ order_id: str,
59
+ principal: Principal = Depends(get_principal), # from the verified token
60
+ ) -> str:
61
+ if not await policy.can_access_order(principal, order_id):
62
+ raise HTTPException(status.HTTP_403_FORBIDDEN)
63
+ return order_id
64
+
65
+ @router.get("/orders/{order_id}")
66
+ async def get_order(order_id: str = Depends(require_order_access)) -> OrderResponse:
67
+ ...
68
+ ```
69
+
70
+ - The token is verified by a proven provider (OIDC); the service does not hand-roll JWT or session logic. Auth is boring technology — see `docs/principles/system-design/identity-and-access.md`.
71
+ - In a multi-tenant service the tenant is bound to the authenticated principal and enforced at the data boundary, never trusted from a path or query parameter.
72
+ - Least privilege: the database role and any cloud identity the service runs as start minimal and widen only on evidence.
73
+
74
+ ## 4. Secrets are managed, never in code
75
+
76
+ No secret lives in source, in a committed `.env`, or baked into an image layer. Configuration is validated once at boot with `pydantic-settings` (`references/implementation-patterns.md` → Configuration Validation); secret *values* are injected from the platform's secret manager at runtime.
77
+
78
+ ```python
79
+ from pydantic import Field
80
+ from pydantic_settings import BaseSettings
81
+
82
+ class Secrets(BaseSettings):
83
+ # Sourced from the secret manager / injected env at runtime — never a default here
84
+ database_url: str = Field(..., min_length=1)
85
+ upstream_api_key: str = Field(..., min_length=16)
86
+
87
+ # .env.example carries names with empty values; real values never enter the repo
88
+ ```
89
+
90
+ The hierarchy is eliminate, then shorten, then rotate: prefer workload identity or OIDC federation (no static credential at all), then short-lived minted secrets, and reserve scheduled rotation for static credentials that genuinely cannot be made ephemeral.
91
+
92
+ ## 5. Supply chain is part of the attack surface
93
+
94
+ Every third-party package is a potential exploit vector. `uv` pins the full dependency graph in `uv.lock`; CI installs from the lockfile (`uv sync --frozen`), never an unpinned resolve.
95
+
96
+ - A new dependency is a reviewed decision, not an intuition — check maintenance, ownership, and transitive weight before adding it.
97
+ - Generate an SBOM and run a vulnerability scan (`uv pip audit` / `pip-audit` or equivalent) on every build; a known-vulnerable transitive dependency fails the build.
98
+ - Emit build provenance for anything published, so the artifact's origin is verifiable, not just its contents.
99
+
100
+ ## 6. SSRF on outbound calls
101
+
102
+ A service that fetches a URL derived from input is an SSRF vector — an attacker aims it at internal metadata endpoints or private hosts. Outbound targets are allowlisted, not reflected from the request.
103
+
104
+ ```python
105
+ from urllib.parse import urlparse
106
+
107
+ ALLOWED_HOSTS = {"api.partner.example", "cdn.partner.example"}
108
+
109
+ def assert_allowed(url: str) -> str:
110
+ host = urlparse(url).hostname
111
+ if host not in ALLOWED_HOSTS:
112
+ raise PermanentInferenceError(f"outbound host not allowed: {host}")
113
+ return url
114
+ ```
115
+
116
+ - Validate the resolved host against an allowlist before the call; reject `file:`, `gopher:`, and non-HTTPS schemes.
117
+ - Set explicit connect/read timeouts on every outbound client so a hostile or slow upstream cannot exhaust the service (`references/resilience.md`).
118
+
119
+ ## 7. Error envelopes that do not leak internals
120
+
121
+ A client receives a stable, structured error; stack traces, SQL fragments, and upstream provider messages stay in the logs. The Domain raises typed exceptions (`references/implementation-patterns.md` → Error Handling); one exception handler maps them to a safe envelope.
122
+
123
+ ```python
124
+ from fastapi import Request
125
+ from fastapi.responses import JSONResponse
126
+
127
+ @app.exception_handler(AppError)
128
+ async def handle_app_error(request: Request, exc: AppError) -> JSONResponse:
129
+ logger.exception("request failed", extra={"trace_id": current_trace_id()})
130
+ # client sees a code and a correlation id — never exc internals
131
+ return JSONResponse(
132
+ status_code=422,
133
+ content={"error": exc.code, "trace_id": current_trace_id()},
134
+ )
135
+ ```
136
+
137
+ The `422` unification and CORS rules live in `references/api-standards.md`; security's addition is that the body never carries an internal detail and the correlation id is how support traces it without exposing it.
138
+
139
+ ## Anti-Patterns
140
+
141
+ - **Reading the raw request body as a `dict`.** Bypasses validation; parse a Pydantic model with `extra="forbid"`.
142
+ - **f-string SQL.** `f"WHERE id = {user_id}"` is injection. Bind every value.
143
+ - **Per-handler permission checks that drift.** Authorize through one dependency; model the policy once.
144
+ - **Secrets in `.env`, an image layer, or a default value.** Inject from the secret manager at runtime.
145
+ - **Unpinned installs in CI.** `uv sync --frozen` against `uv.lock`; scan and SBOM every build.
146
+ - **Fetching an input-supplied URL unchecked.** Allowlist the host; block internal addresses and non-HTTPS schemes.
147
+ - **Returning the exception string to the client.** Log the detail, return a code and a trace id.
148
+ - **"It is an internal service, skip auth."** Internal services are an attacker's favourite foothold — zero trust between services.
@@ -0,0 +1,216 @@
1
+ # Testing
2
+
3
+ ## The Model: Honeycomb, Not Pyramid
4
+
5
+ Testcontainers spins up real Postgres/Pub/Sub in seconds. The confidence it provides is categorically different from any mock. Mock-heavy suites pass while production breaks.
6
+
7
+ **Service tests are the default.** Unit tests are reserved for genuinely complex logic. System tests are minimal.
8
+
9
+ This is the stack idiom of the framework testing canon (`docs/principles/foundations/testing.md`); when this file and the canon disagree, the canon wins and this file is the one to fix.
10
+
11
+ Above the honeycomb sits the front-door proof: drive the real running service through the front door a consumer actually calls — its HTTP API — end to end on the real pipeline. Service tests that each pass behind a `dependency_overrides` mock or a stubbed adapter can still assemble into a product that does nothing on the real path, so one proof exercises that path with nothing in the middle faked. This makes a rule on every fake: a stub or fixture standing in for a real stage — an LLM response, a downstream service, a producer's output — is a debt that some test of the real producer must pay. Seeding the input is fine; faking the work in the middle is the violation, and an unpaid debt is a green light wired to nothing.
12
+
13
+ ---
14
+
15
+ ## Tier 1 — Service Tests (Default)
16
+
17
+ Drive the FastAPI app through HTTP using `httpx.AsyncClient` with `ASGITransport`. Infrastructure runs in containers. Non-containerisable providers (LLM APIs) are replaced at the FastAPI `dependency_overrides` boundary.
18
+
19
+ ### Fixture Setup — App + Async Client
20
+
21
+ ```python
22
+ import pytest
23
+ import httpx
24
+
25
+ @pytest.fixture(scope="session")
26
+ def app():
27
+ return create_app()
28
+
29
+ @pytest.fixture
30
+ async def client(app):
31
+ async with httpx.AsyncClient(
32
+ transport=httpx.ASGITransport(app=app),
33
+ base_url="http://test",
34
+ ) as c:
35
+ yield c
36
+ ```
37
+
38
+ ### Fixture Setup — Containerised Infrastructure
39
+
40
+ ```python
41
+ from testcontainers.postgres import PostgresContainer
42
+
43
+ @pytest.fixture(scope="session")
44
+ def postgres():
45
+ with PostgresContainer("postgres:16-alpine") as container:
46
+ yield container
47
+ ```
48
+
49
+ Scope containers at `session`. Reset state via transactions or truncation between tests.
50
+
51
+ ### Replacing Non-Containerisable Providers
52
+
53
+ Replace at the FastAPI boundary, not by patching internals:
54
+
55
+ ```python
56
+ from unittest.mock import AsyncMock
57
+
58
+ @pytest.fixture
59
+ def fake_processor():
60
+ proc = AsyncMock()
61
+ proc.process.return_value = DomainResult(...)
62
+ return proc
63
+
64
+ async def test_endpoint_returns_result(client, app, fake_processor):
65
+ app.dependency_overrides[get_processor] = lambda: fake_processor
66
+ response = await client.post("/process", json={"input": "test"})
67
+ assert response.status_code == 200
68
+ ```
69
+
70
+ Route handler, service, and validation all run for real. Only the external API call is substituted.
71
+
72
+ ### Live Provider Tests
73
+
74
+ Marked `@pytest.mark.live` and selected explicitly with pytest's `-m` flag (excluded from normal runs with `-m "not live"`):
75
+
76
+ ```python
77
+ @pytest.mark.live
78
+ async def test_adapter_against_real_api(processor, fixture_data):
79
+ result = await processor.process(fixture_data)
80
+ assert result.confidence > 0
81
+ ```
82
+
83
+ ---
84
+
85
+ ## Tier 2 — Unit Tests (Reserved)
86
+
87
+ Appropriate when logic is genuinely complex, has many branches, operates on pure data, and is painful to exercise through HTTP.
88
+
89
+ **What earns a unit test:**
90
+ - Domain model immutability, field validation, business rules
91
+ - Complex transformations (resampling, merging, normalisation)
92
+ - Pure algorithms (confidence thresholding, chunking strategies)
93
+
94
+ **What does NOT earn a unit test:**
95
+ - Service methods that orchestrate adapter calls
96
+ - Endpoint handlers that validate and delegate
97
+ - Adapters that translate SDK responses
98
+
99
+ ```python
100
+ class TestDomainModel:
101
+ def test_rejects_invalid_confidence(self):
102
+ with pytest.raises(ValidationError):
103
+ Segment(text="hello", confidence=1.5, start=0.0, end=1.0)
104
+
105
+ def test_is_immutable(self):
106
+ segment = Segment(text="hello", confidence=0.9, start=0.0, end=1.0)
107
+ with pytest.raises(ValidationError):
108
+ segment.text = "goodbye"
109
+ ```
110
+
111
+ ---
112
+
113
+ ## Tier 3 — System Tests (Minimal)
114
+
115
+ **Bootstrap test** — verifies the DI container initialises:
116
+
117
+ ```python
118
+ def test_application_starts():
119
+ app = create_app()
120
+ assert app is not None
121
+ ```
122
+
123
+ **Golden path test** — one per critical journey, against the full live stack.
124
+
125
+ ---
126
+
127
+ ## Async Configuration
128
+
129
+ ```toml
130
+ [tool.pytest.ini_options]
131
+ asyncio_mode = "auto"
132
+ ```
133
+
134
+ Write `async def` tests directly. No `@pytest.mark.asyncio` needed.
135
+
136
+ ## Test Isolation
137
+
138
+ - **Transaction rollback** per test, or **truncation fixture**.
139
+ - Always reset `dependency_overrides` after each test:
140
+
141
+ ```python
142
+ @pytest.fixture(autouse=True)
143
+ def reset_overrides(app):
144
+ yield
145
+ app.dependency_overrides.clear()
146
+ ```
147
+
148
+ ## Naming
149
+
150
+ ```python
151
+ # Good
152
+ async def test_process_returns_422_when_input_missing(client): ...
153
+ # Bad
154
+ async def test_process_success(client): ...
155
+ ```
156
+
157
+ ## Running Tests
158
+
159
+ ```bash
160
+ uv run pytest tests/unit # No infrastructure
161
+ uv run pytest tests/integration -m "not live" # Requires Docker; skips live APIs
162
+ uv run pytest tests/integration -m live # Live API tests — requires real keys
163
+ uv run pytest tests/system # Bootstrap + golden path
164
+ ```
165
+
166
+ ## Trace Assertions
167
+
168
+ Observability is a test surface: a critical-path request must emit an unbroken trace, and a missing span is a test failure, not an instrumentation TODO. The mechanism is an **in-memory span exporter** from the OTel SDK — no external tooling, and the durable approach now that the dedicated trace-test tools have gone dormant.
169
+
170
+ ```python
171
+ from opentelemetry import trace
172
+ from opentelemetry.sdk.trace import TracerProvider
173
+ from opentelemetry.sdk.trace.export import SimpleSpanProcessor
174
+ from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter
175
+
176
+ @pytest.fixture
177
+ def spans():
178
+ exporter = InMemorySpanExporter()
179
+ provider = TracerProvider()
180
+ provider.add_span_processor(SimpleSpanProcessor(exporter))
181
+ trace.set_tracer_provider(provider)
182
+ return exporter
183
+
184
+ async def test_process_emits_trace(client, spans):
185
+ await client.post("/process", json={"input": "test"})
186
+ names = {s.name for s in spans.get_finished_spans()}
187
+ assert "POST /process" in names # the entry span exists
188
+ assert "db.insert" in names # the work span exists
189
+ # assert the work span is a descendant of the entry span — the trace is connected
190
+ ```
191
+
192
+ Assert what the contract promises — the spans that must exist on the journey, that the trace stays connected across hops, and the attributes a dashboard or SLO query depends on. Pinning the exact span tree and every attribute couples the test to implementation and trains the team to delete it.
193
+
194
+ ## Mutation Testing — the assertion-quality read-out
195
+
196
+ A fat service test drives many branches through one HTTP call and can *execute* them all while only asserting on the response body. Mutation testing is the one instrument that proves the suite checks what it runs: inject a fault, confirm a test fails, and a surviving mutant is a line you cover but do not check. Treat it as a **signal, never a gate** — run it on the high-risk modules the risk matrix flags and on changed code only.
197
+
198
+ Use `mutmut` or `cosmic-ray`. A gotcha: `mutmut` 3 no longer mutates module-level code (only function bodies), so a module whose risk lives in top-level constants or table definitions needs `cosmic-ray` or `mutmut` 2. Scope a run to the dense package under change (`mutmut run --paths-to-mutate src/<pkg>/pricing`), read it as a read-out, and turn each surviving mutant on changed high-risk code into the missing assertion — the same read-out catches AI-generated tests whose oracle was lifted from the implementation.
199
+
200
+ ## Anti-Patterns
201
+
202
+ - **Mocking the interior.** Test what comes out, not which methods were called.
203
+ - **Testing delegation.** `assert adapter.called_once_with(...)` tests the mock, not the code.
204
+ - **Fixture factories that mirror domain.** Construct only what the test needs.
205
+ - **`scope="session"` on mutable state.** Containers: safe. Application state: not.
206
+ - **Skipping the async client.** `TestClient` hides async behaviour. Use `httpx.AsyncClient`.
207
+
208
+ ## Bet Slice Rollout — the permanent tests a slice owes
209
+
210
+ When a bet slice's progress tests go green, the slice-worker rolls out permanent coverage as part of the same slice, before the driver reviews it (bet workflow, Delivery). The bet-progress tests prove the capability once and are archived; these stay.
211
+
212
+ - **Service perimeter test (always).** One test per capability the slice delivered, through `httpx.AsyncClient` against the real app with a real database — the coverage that survives refactors.
213
+ - **Unit tests (when logic earned them).** Pure-function tests for branching business logic the slice introduced — validation rules, transformations, state machines. Plumbing does not earn unit tests; the perimeter test already covers it.
214
+ - **Property-based tests (when invariants exist).** A slice that introduced an invariant — round-trip serialization, idempotent consumers, order-independent merges — pins it with Hypothesis, because example-based tests sample invariants instead of stating them.
215
+ - **Critical-path trace assertions (when the slice added an observable path).** A slice that introduced an endpoint or worker whose trace a dashboard or SLO depends on pins it with an in-memory-exporter test: the entry and work spans exist and the trace stays connected. A missing span is a test failure, not an instrumentation TODO.
216
+ - **Contract conformance (when the slice changed an API).** FastAPI's served `/openapi.json` must match the promoted spec in `docs/architecture/api/<service>/openapi.yaml`; the generated system suite checks this — the slice's job is to keep the spec promotion current.
@@ -0,0 +1,20 @@
1
+ # Sync Anchor
2
+
3
+ This file pins the principle files this skill embeds — both the per-stack Python
4
+ idiom docs and the cross-cutting central canon this skill distils. When any
5
+ listed file changes, this skill must be reviewed in the same commit (and the
6
+ matching per-stack idiom doc reconciled to the canon). CI verifies the hashes
7
+ match.
8
+
9
+ | Principle file | SHA-256 | Last reviewed |
10
+ |---|---|---|
11
+ | src/generators/python-microservice/docs/principles/stack/python/async.md | 6fdd399fb3052381020ff6e792a724d72bdabe674817794093853cbf24fa9f97 | 2026-05-26 |
12
+ | src/generators/python-microservice/docs/principles/stack/python/resilience.md | d5a7b8f089acdb71d64c1bd4fc9ce80e6947504b01b0ace695ac5ee66554a1b1 | 2026-06-19 |
13
+ | src/generators/python-microservice/docs/principles/stack/python/testing.md | f15e62c83b659788f8b3e39f560779e892080d6bce73768be093d919f3e6946c | 2026-06-26 |
14
+ | src/generators/python-microservice/docs/principles/stack/python/documentation.md | ac58228ba22435bf9bad2ea5bf924bdf9e3674e9967515d5c82aaf3b7825214d | 2026-05-26 |
15
+ | src/generators/python-microservice/docs/principles/stack/python/mcp.md | 1e6deab0b45c7271e0038e9b3d51bc30cb2917488f608e847d566739ac6caeba | 2026-06-19 |
16
+ | src/docs/principles/foundations/testing.md | 205ac40d4c643e7b61cf1e4295df8a7b8b46dcd7c81b857aa8c642ea353f62ef | 2026-06-27 |
17
+ | src/docs/principles/quality/observability.md | 8aa60e213ba03e989c93263153e3a1ac10b2336f6d0360c394f473660d565a0b | 2026-06-26 |
18
+ | src/docs/principles/quality/security.md | 61157d97677142737ec537954dc5aaad7a04012cc8a3dcc855e2d324287fdc64 | 2026-06-26 |
19
+ | src/docs/principles/quality/reliability.md | 9c9788504e0963458667d2727c3fc2359776108be593a2efc6603f6470002252 | 2026-06-26 |
20
+ | src/docs/principles/foundations/documentation.md | 8b576072eaf4970f1251b560781e3e755c864a7920faa599b2834c921cbb8734 | 2026-06-26 |
@@ -0,0 +1,70 @@
1
+ import { formatFiles, Tree } from '@nx/devkit';
2
+ import { recordGeneratorProvenance } from '../shared/provenance';
3
+ import { applyCapability, loadCapability } from '../shared/capabilities';
4
+
5
+ export interface AddCapabilityGeneratorSchema {
6
+ service: string;
7
+ capability: string;
8
+ provider?: string;
9
+ stack?: string;
10
+ }
11
+
12
+ /** Locate the service root in the tree. Accepts a bare name (resolved under
13
+ * services/) or an explicit path. */
14
+ function resolveServiceRoot(tree: Tree, service: string): string {
15
+ const candidates = service.includes('/') ? [service] : [`services/${service}`, service];
16
+ for (const c of candidates) {
17
+ if (tree.exists(`${c}/pyproject.toml`) || tree.exists(`${c}/go.mod`) || tree.exists(`${c}/package.json`)) {
18
+ return c;
19
+ }
20
+ }
21
+ throw new Error(
22
+ `Could not find service "${service}" (looked for ${candidates.join(', ')} with a pyproject.toml / go.mod / package.json).`,
23
+ );
24
+ }
25
+
26
+ /** Infer the stack from the marker file present in the service root. */
27
+ function detectStack(tree: Tree, serviceRoot: string): string {
28
+ if (tree.exists(`${serviceRoot}/pyproject.toml`)) return 'python';
29
+ if (tree.exists(`${serviceRoot}/go.mod`)) return 'go';
30
+ if (tree.exists(`${serviceRoot}/package.json`)) return 'typescript';
31
+ throw new Error(`Could not detect the stack for ${serviceRoot}.`);
32
+ }
33
+
34
+ export default async function (tree: Tree, options: AddCapabilityGeneratorSchema) {
35
+ const capability = options.capability || 'llm';
36
+ const cap = loadCapability(capability);
37
+ const provider = options.provider || cap.default;
38
+ const serviceRoot = resolveServiceRoot(tree, options.service);
39
+ const stack = options.stack || detectStack(tree, serviceRoot);
40
+
41
+ const result = applyCapability(tree, { capability, provider, stack, serviceRoot });
42
+
43
+ await formatFiles(tree);
44
+ recordGeneratorProvenance(tree, 'add-capability', options as unknown as Record<string, unknown>);
45
+
46
+ // Guidance — the injector writes the port, adapter, contract test, deps and
47
+ // env, but composition-root wiring is service-specific and a compose/runner
48
+ // footprint is workspace-level, so we surface what the engineer must finish.
49
+ console.log(`\nAdded capability "${capability}" (provider: ${provider}, footprint: ${result.footprint}) to ${serviceRoot}`);
50
+ console.log(` port: ${result.files.port}`);
51
+ console.log(` adapter: ${result.files.adapter}`);
52
+ console.log(` contract test: ${result.files.contractTest}`);
53
+ if (result.wiring) console.log(` wiring: ${result.wiring}`);
54
+ if (provider === 'none') {
55
+ console.log(` bet: the contract test is strict-xfail — implement the adapter to cash it.`);
56
+ }
57
+ if (result.footprint === 'compose-service') {
58
+ console.log(
59
+ result.materialized
60
+ ? ` footprint: injected its container into docker-compose.yml — run \`./dev start\` to boot it.`
61
+ : ` footprint: needs a docker-compose service, but no docker-compose.yml was found — run workspace-dev-cli first.`,
62
+ );
63
+ } else if (result.footprint === 'runner') {
64
+ console.log(
65
+ result.materialized
66
+ ? ` footprint: registered as a native runner in .dev/dev.config.json — \`./dev start\` will launch it.`
67
+ : ` footprint: runs as a process, but no .dev/dev.config.json was found — run workspace-dev-cli first.`,
68
+ );
69
+ }
70
+ }
@@ -0,0 +1,30 @@
1
+ {
2
+ "$schema": "http://json-schema.org/schema",
3
+ "id": "add-capability",
4
+ "title": "Add Capability",
5
+ "description": "Add a capability interface + a chosen provider implementation (or a bare `none` interface) to an existing service. The footprint — env / compose-service / runner / none — follows from the provider.",
6
+ "type": "object",
7
+ "properties": {
8
+ "service": {
9
+ "type": "string",
10
+ "description": "The service to add the capability to (directory name under services/, or a path to the service root).",
11
+ "$default": { "$source": "argv", "index": 0 },
12
+ "x-prompt": "Which service should the capability be added to?"
13
+ },
14
+ "capability": {
15
+ "type": "string",
16
+ "default": "llm",
17
+ "description": "The capability to add (must exist in the capability registry).",
18
+ "x-prompt": "Which capability do you want to add?"
19
+ },
20
+ "provider": {
21
+ "type": "string",
22
+ "description": "The provider that satisfies the capability. Defaults to the capability's default provider. Use `none` for a bare interface (interface + stub + red contract test, to be built as a bet)."
23
+ },
24
+ "stack": {
25
+ "type": "string",
26
+ "description": "Language stack of the target service. Auto-detected from the service when omitted (e.g. pyproject.toml -> python)."
27
+ }
28
+ },
29
+ "required": ["service"]
30
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "id": "llm",
3
+ "title": "LLM inference",
4
+ "description": "Text generation via a large language model. The interface is fixed; the provider (and therefore the operational footprint) is a scaffold-time choice.",
5
+ "default": "anthropic",
6
+ "providers": ["anthropic", "openai", "local", "ollama", "localai", "none"],
7
+ "stacks": {
8
+ "python": {
9
+ "port": "src/__packageName__/core/llm.py",
10
+ "portSymbol": "TextGenerator",
11
+ "adapter": "src/__packageName__/adapters/llm.py",
12
+ "adapterSymbol": "LLMClient",
13
+ "contractTest": "tests/contracts/test_llm.py",
14
+ "envFile": ".env.example",
15
+ "wiring": "Provide LLMClient() to your composition root (e.g. dependencies.py get_text_generator) typed as the TextGenerator protocol from core.llm, and call generate_text() from your service."
16
+ },
17
+ "go": {
18
+ "port": "internal/core/service/llm.go",
19
+ "portSymbol": "TextGenerator",
20
+ "adapter": "internal/llm/llm.go",
21
+ "adapterSymbol": "Client",
22
+ "contractTest": "internal/llm/llm_test.go",
23
+ "envFile": ".env",
24
+ "module": true,
25
+ "wiring": "Construct llm.NewClient() in cmd/api/main.go and pass it (typed as the service.TextGenerator interface) into your service. Run `go mod tidy` if a provider added a dependency."
26
+ }
27
+ }
28
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "kind": "env",
3
+ "summary": "Anthropic Claude over HTTPS. API key in env; no infrastructure.",
4
+ "env": [
5
+ { "name": "LLM_API_KEY", "required": true, "default": "" },
6
+ { "name": "LLM_BASE_URL", "required": false, "default": "" },
7
+ { "name": "LLM_MODEL", "required": false, "default": "claude-sonnet-4-6" }
8
+ ],
9
+ "stacks": {
10
+ "python": { "dependencies": ["anthropic>=0.40.0"] },
11
+ "go": { "dependencies": [] }
12
+ }
13
+ }