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.
- package/CHANGELOG.md +823 -0
- package/LICENSE +21 -0
- package/README.md +44 -29
- package/bin/groundwork.js +1723 -0
- package/dist/src/generators/add-capability/generator.d.ts +8 -0
- package/dist/src/generators/add-capability/generator.js +60 -0
- package/dist/src/generators/add-capability/generator.js.map +1 -0
- package/dist/src/generators/cli-app/generator.d.ts +9 -0
- package/dist/src/generators/cli-app/generator.js +140 -0
- package/dist/src/generators/cli-app/generator.js.map +1 -0
- package/dist/src/generators/docs-site/generator.d.ts +5 -0
- package/dist/src/generators/docs-site/generator.js +441 -0
- package/dist/src/generators/docs-site/generator.js.map +1 -0
- package/dist/src/generators/electron-app/generator.d.ts +6 -0
- package/dist/src/generators/electron-app/generator.js +261 -0
- package/dist/src/generators/electron-app/generator.js.map +1 -0
- package/dist/src/generators/flutter-app/generator.d.ts +6 -0
- package/dist/src/generators/flutter-app/generator.js +314 -0
- package/dist/src/generators/flutter-app/generator.js.map +1 -0
- package/dist/src/generators/go-microservice/generator.d.ts +8 -0
- package/dist/src/generators/go-microservice/generator.js +232 -0
- package/dist/src/generators/go-microservice/generator.js.map +1 -0
- package/dist/src/generators/nextjs-app/generator.d.ts +8 -0
- package/dist/src/generators/nextjs-app/generator.js +294 -0
- package/dist/src/generators/nextjs-app/generator.js.map +1 -0
- package/dist/src/generators/python-microservice/generator.d.ts +13 -0
- package/dist/src/generators/python-microservice/generator.js +265 -0
- package/dist/src/generators/python-microservice/generator.js.map +1 -0
- package/dist/src/generators/shared/brand-tokens.d.ts +89 -0
- package/dist/src/generators/shared/brand-tokens.js +308 -0
- package/dist/src/generators/shared/brand-tokens.js.map +1 -0
- package/dist/src/generators/shared/capabilities.d.ts +101 -0
- package/dist/src/generators/shared/capabilities.js +279 -0
- package/dist/src/generators/shared/capabilities.js.map +1 -0
- package/dist/src/generators/shared/provenance.d.ts +2 -0
- package/dist/src/generators/shared/provenance.js +85 -0
- package/dist/src/generators/shared/provenance.js.map +1 -0
- package/dist/src/generators/shared/scaffold-helpers.d.ts +72 -0
- package/dist/src/generators/shared/scaffold-helpers.js +309 -0
- package/dist/src/generators/shared/scaffold-helpers.js.map +1 -0
- package/dist/src/generators/system-test-runner/generator.d.ts +23 -0
- package/dist/src/generators/system-test-runner/generator.js +173 -0
- package/dist/src/generators/system-test-runner/generator.js.map +1 -0
- package/dist/src/generators/workspace-dev-cli/generator.d.ts +7 -0
- package/dist/src/generators/workspace-dev-cli/generator.js +138 -0
- package/dist/src/generators/workspace-dev-cli/generator.js.map +1 -0
- package/generators.json +57 -0
- package/lib/repo-map/grammars/tree-sitter-c.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-cpp.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-csharp.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-dart.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-go.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-java.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-javascript.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-kotlin.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-lua.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-php.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-python.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-ruby.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-rust.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-scala.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-swift.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-tsx.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-typescript.wasm +0 -0
- package/lib/repo-map/index.js +386 -0
- package/lib/repo-map/languages.js +514 -0
- package/lib/repo-map/pagerank.js +59 -0
- package/migrations/README.md +60 -0
- package/migrations/_template/cli-migration.js +27 -0
- package/migrations/gw-bet-prose-redesign.js +105 -0
- package/migrations/gw-drop-test-manifest.js +37 -0
- package/migrations/gw-register-serena-mcp.js +42 -0
- package/migrations/gw-relocate-hidden-skills.js +40 -0
- package/migrations/gw-seed-config-toml.js +24 -0
- package/migrations/index.json +40 -0
- package/package.json +70 -6
- package/src/AGENTS.md +36 -0
- package/src/config/config.toml +30 -0
- package/src/config/groundwork-state.json +5 -0
- package/src/docs/llms.txt +72 -0
- package/src/docs/principles/ai-native/agent-native-systems.md +90 -0
- package/src/docs/principles/ai-native/agentic-systems.md +78 -0
- package/src/docs/principles/ai-native/ai-engineering.md +100 -0
- package/src/docs/principles/ai-native/ai-native-product.md +76 -0
- package/src/docs/principles/delivery/cost-engineering.md +89 -0
- package/src/docs/principles/delivery/day-2-operational-baseline.md +57 -0
- package/src/docs/principles/delivery/devex.md +88 -0
- package/src/docs/principles/delivery/platform.md +101 -0
- package/src/docs/principles/delivery/progressive-delivery.md +92 -0
- package/src/docs/principles/design/ai-native-design.md +73 -0
- package/src/docs/principles/design/design-foundations.md +80 -0
- package/src/docs/principles/design/design-systems-and-tokens.md +72 -0
- package/src/docs/principles/design/interaction-and-motion.md +69 -0
- package/src/docs/principles/design/layout-and-space.md +72 -0
- package/src/docs/principles/design/usability-and-ux.md +79 -0
- package/src/docs/principles/design/visual-design.md +84 -0
- package/src/docs/principles/foundations/code-craft.md +86 -0
- package/src/docs/principles/foundations/continuous-discovery.md +75 -0
- package/src/docs/principles/foundations/documentation.md +102 -0
- package/src/docs/principles/foundations/prioritization-and-appetite.md +78 -0
- package/src/docs/principles/foundations/product-engineering.md +90 -0
- package/src/docs/principles/foundations/product-risks.md +89 -0
- package/src/docs/principles/foundations/requirements-and-specs.md +80 -0
- package/src/docs/principles/foundations/success-metrics.md +66 -0
- package/src/docs/principles/foundations/testing.md +108 -0
- package/src/docs/principles/index.md +24 -0
- package/src/docs/principles/quality/accessibility.md +88 -0
- package/src/docs/principles/quality/observability.md +84 -0
- package/src/docs/principles/quality/performance.md +84 -0
- package/src/docs/principles/quality/privacy.md +92 -0
- package/src/docs/principles/quality/reliability.md +89 -0
- package/src/docs/principles/quality/security.md +78 -0
- package/src/docs/principles/stack/postgres.md +100 -0
- package/src/docs/principles/system-design/api-design.md +86 -0
- package/src/docs/principles/system-design/architecture-decisions.md +81 -0
- package/src/docs/principles/system-design/code-structure.md +104 -0
- package/src/docs/principles/system-design/data-engineering.md +87 -0
- package/src/docs/principles/system-design/durable-execution.md +89 -0
- package/src/docs/principles/system-design/evolutionary-architecture.md +81 -0
- package/src/docs/principles/system-design/identity-and-access.md +76 -0
- package/src/docs/principles/system-design/integration-patterns.md +84 -0
- package/src/docs/principles/system-design/real-time.md +83 -0
- package/src/docs/principles/system-design/surface-architecture.md +74 -0
- package/src/docs/ways-of-working/documentation.md +69 -0
- package/src/docs/ways-of-working/how-we-work.md +76 -0
- package/src/docs/ways-of-working/units-of-work.md +40 -0
- package/src/engineer-skills/groundwork-electron-engineer/SKILL.md +123 -0
- package/src/engineer-skills/groundwork-electron-engineer/references/documentation.md +126 -0
- package/src/engineer-skills/groundwork-electron-engineer/references/ipc-contracts.md +138 -0
- package/src/engineer-skills/groundwork-electron-engineer/references/observability.md +37 -0
- package/src/engineer-skills/groundwork-electron-engineer/references/packaging-and-updates.md +82 -0
- package/src/engineer-skills/groundwork-electron-engineer/references/performance-and-reliability.md +80 -0
- package/src/engineer-skills/groundwork-electron-engineer/references/process-model.md +94 -0
- package/src/engineer-skills/groundwork-electron-engineer/references/security.md +107 -0
- package/src/engineer-skills/groundwork-electron-engineer/references/testing-and-smoke.md +129 -0
- package/src/engineer-skills/groundwork-electron-engineer/references/theming-and-tokens.md +74 -0
- package/src/engineer-skills/groundwork-electron-engineer/sync-anchor.md +22 -0
- package/src/engineer-skills/groundwork-flutter-engineer/SKILL.md +114 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/accessibility.md +92 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/architecture.md +189 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/data-and-contracts.md +136 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/documentation.md +122 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/navigation.md +122 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/observability.md +37 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/performance-and-reliability.md +100 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/platform-channels.md +93 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/releases-and-distribution.md +84 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/security.md +96 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/state-management.md +166 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/testing.md +160 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/theming-and-design-tokens.md +109 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/widgets-and-composition.md +123 -0
- package/src/engineer-skills/groundwork-flutter-engineer/sync-anchor.md +24 -0
- package/src/engineer-skills/groundwork-go-engineer/SKILL.md +174 -0
- package/src/engineer-skills/groundwork-go-engineer/references/api-design.md +82 -0
- package/src/engineer-skills/groundwork-go-engineer/references/architecture.md +42 -0
- package/src/engineer-skills/groundwork-go-engineer/references/capability-ports.md +50 -0
- package/src/engineer-skills/groundwork-go-engineer/references/code-craft-security.md +34 -0
- package/src/engineer-skills/groundwork-go-engineer/references/concurrency.md +108 -0
- package/src/engineer-skills/groundwork-go-engineer/references/documentation.md +130 -0
- package/src/engineer-skills/groundwork-go-engineer/references/go-services.md +77 -0
- package/src/engineer-skills/groundwork-go-engineer/references/http-handlers.md +172 -0
- package/src/engineer-skills/groundwork-go-engineer/references/implementation-patterns.md +156 -0
- package/src/engineer-skills/groundwork-go-engineer/references/integration-realtime-data.md +57 -0
- package/src/engineer-skills/groundwork-go-engineer/references/observability.md +49 -0
- package/src/engineer-skills/groundwork-go-engineer/references/postgres.md +41 -0
- package/src/engineer-skills/groundwork-go-engineer/references/reliability-performance.md +105 -0
- package/src/engineer-skills/groundwork-go-engineer/references/testing.md +201 -0
- package/src/engineer-skills/groundwork-go-engineer/sync-anchor.md +20 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/SKILL.md +112 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/accessibility.md +111 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/architecture.md +323 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/data-fetching.md +458 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/documentation.md +324 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/error-boundaries.md +383 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/mutations-and-forms.md +396 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/observability.md +48 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/performance-and-deployment.md +947 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/routing-and-navigation.md +405 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/security.md +131 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/server-components.md +394 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/tailwind-and-styling.md +134 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/testing.md +491 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/type-system.md +368 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/ux-principles.md +230 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/visual-language.md +69 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/sync-anchor.md +16 -0
- package/src/engineer-skills/groundwork-python-engineer/SKILL.md +199 -0
- package/src/engineer-skills/groundwork-python-engineer/references/api-standards.md +88 -0
- package/src/engineer-skills/groundwork-python-engineer/references/architecture.md +57 -0
- package/src/engineer-skills/groundwork-python-engineer/references/async-patterns.md +103 -0
- package/src/engineer-skills/groundwork-python-engineer/references/capability-ports.md +44 -0
- package/src/engineer-skills/groundwork-python-engineer/references/database.md +88 -0
- package/src/engineer-skills/groundwork-python-engineer/references/documentation-mcp.md +167 -0
- package/src/engineer-skills/groundwork-python-engineer/references/implementation-patterns.md +166 -0
- package/src/engineer-skills/groundwork-python-engineer/references/ml-pipelines.md +119 -0
- package/src/engineer-skills/groundwork-python-engineer/references/ml-systems-ai-engineering.md +74 -0
- package/src/engineer-skills/groundwork-python-engineer/references/observability.md +57 -0
- package/src/engineer-skills/groundwork-python-engineer/references/resilience.md +126 -0
- package/src/engineer-skills/groundwork-python-engineer/references/security.md +148 -0
- package/src/engineer-skills/groundwork-python-engineer/references/testing.md +216 -0
- package/src/engineer-skills/groundwork-python-engineer/sync-anchor.md +20 -0
- package/src/generators/add-capability/generator.ts +70 -0
- package/src/generators/add-capability/schema.json +30 -0
- package/src/generators/capabilities/llm/capability.json +28 -0
- package/src/generators/capabilities/llm/providers/anthropic/footprint.json +13 -0
- package/src/generators/capabilities/llm/providers/anthropic/stacks/go/internal/llm/llm.go.template +102 -0
- package/src/generators/capabilities/llm/providers/anthropic/stacks/python/src/__packageName__/adapters/llm.py.template +61 -0
- package/src/generators/capabilities/llm/providers/local/footprint.json +13 -0
- package/src/generators/capabilities/llm/providers/local/stacks/go/internal/llm/llm.go.template +102 -0
- package/src/generators/capabilities/llm/providers/local/stacks/python/src/__packageName__/adapters/llm.py.template +53 -0
- package/src/generators/capabilities/llm/providers/localai/footprint.json +29 -0
- package/src/generators/capabilities/llm/providers/localai/stacks/go/internal/llm/llm.go.template +102 -0
- package/src/generators/capabilities/llm/providers/localai/stacks/python/src/__packageName__/adapters/llm.py.template +53 -0
- package/src/generators/capabilities/llm/providers/none/footprint.json +9 -0
- package/src/generators/capabilities/llm/providers/none/stacks/go/internal/llm/llm.go.template +35 -0
- package/src/generators/capabilities/llm/providers/none/stacks/python/src/__packageName__/adapters/llm.py.template +25 -0
- package/src/generators/capabilities/llm/providers/ollama/footprint.json +20 -0
- package/src/generators/capabilities/llm/providers/ollama/stacks/go/internal/llm/llm.go.template +102 -0
- package/src/generators/capabilities/llm/providers/ollama/stacks/python/src/__packageName__/adapters/llm.py.template +53 -0
- package/src/generators/capabilities/llm/providers/openai/footprint.json +13 -0
- package/src/generators/capabilities/llm/providers/openai/stacks/go/internal/llm/llm.go.template +98 -0
- package/src/generators/capabilities/llm/providers/openai/stacks/python/src/__packageName__/adapters/llm.py.template +60 -0
- package/src/generators/capabilities/llm/stacks/go/internal/core/service/llm.go.template +12 -0
- package/src/generators/capabilities/llm/stacks/go/internal/llm/llm_test.go.template +33 -0
- package/src/generators/capabilities/llm/stacks/python/src/__packageName__/core/llm.py.template +15 -0
- package/src/generators/capabilities/llm/stacks/python/tests/contracts/test_llm.py.template +37 -0
- package/src/generators/cli-app/files/README.md.template +76 -0
- package/src/generators/cli-app/files/build.mjs.template +15 -0
- package/src/generators/cli-app/files/package.json.template +21 -0
- package/src/generators/cli-app/files/src/cli.ts.template +67 -0
- package/src/generators/cli-app/files/src/commands/hello.ts.template +17 -0
- package/src/generators/cli-app/files/src/commands/status.ts.template +23 -0
- package/src/generators/cli-app/files/src/core/client.test.ts.template +80 -0
- package/src/generators/cli-app/files/src/core/client.ts.template +64 -0
- package/src/generators/cli-app/files/src/registry.test.ts.template +35 -0
- package/src/generators/cli-app/files/src/registry.ts.template +31 -0
- package/src/generators/cli-app/files/tsconfig.json.template +16 -0
- package/src/generators/cli-app/files/tsconfig.test.json.template +11 -0
- package/src/generators/cli-app/generator.ts +138 -0
- package/src/generators/cli-app/schema.json +24 -0
- package/src/generators/docs-site/files/.gitignore.ejs +40 -0
- package/src/generators/docs-site/files/app/docs/__slug__/page.tsx +101 -0
- package/src/generators/docs-site/files/app/docs/layout.tsx +14 -0
- package/src/generators/docs-site/files/app/docs.css +43 -0
- package/src/generators/docs-site/files/app/layout.tsx +24 -0
- package/src/generators/docs-site/files/app/page.tsx +135 -0
- package/src/generators/docs-site/files/app/source.ts +8 -0
- package/src/generators/docs-site/files/components/mermaid.tsx +67 -0
- package/src/generators/docs-site/files/next.config.mjs +10 -0
- package/src/generators/docs-site/files/package.json +32 -0
- package/src/generators/docs-site/files/pnpm-workspace.yaml +7 -0
- package/src/generators/docs-site/files/postcss.config.mjs +6 -0
- package/src/generators/docs-site/files/source.config.ts +77 -0
- package/src/generators/docs-site/files/tailwind.config.js +10 -0
- package/src/generators/docs-site/files/tsconfig.json +27 -0
- package/src/generators/docs-site/generator.ts +476 -0
- package/src/generators/docs-site/schema.json +17 -0
- package/src/generators/electron-app/docs/principles/stack/electron/index.md +49 -0
- package/src/generators/electron-app/docs/principles/stack/electron/ipc-contracts.md +71 -0
- package/src/generators/electron-app/docs/principles/stack/electron/packaging-and-updates.md +59 -0
- package/src/generators/electron-app/docs/principles/stack/electron/process-model.md +53 -0
- package/src/generators/electron-app/docs/principles/stack/electron/security.md +70 -0
- package/src/generators/electron-app/docs/principles/stack/typescript/frontend.md +65 -0
- package/src/generators/electron-app/files/.gitignore.template +20 -0
- package/src/generators/electron-app/files/README.md.template +125 -0
- package/src/generators/electron-app/files/electron.vite.config.ts +31 -0
- package/src/generators/electron-app/files/eslint.config.mjs +92 -0
- package/src/generators/electron-app/files/forge.config.ts.template +44 -0
- package/src/generators/electron-app/files/package.json.template +54 -0
- package/src/generators/electron-app/files/playwright.config.ts +18 -0
- package/src/generators/electron-app/files/project.json.template +65 -0
- package/src/generators/electron-app/files/src/main/core-client.test.ts +81 -0
- package/src/generators/electron-app/files/src/main/core-client.ts +55 -0
- package/src/generators/electron-app/files/src/main/index.ts +157 -0
- package/src/generators/electron-app/files/src/main/ipc.ts +52 -0
- package/src/generators/electron-app/files/src/main/policy.test.ts +71 -0
- package/src/generators/electron-app/files/src/main/policy.ts +73 -0
- package/src/generators/electron-app/files/src/preload/index.ts +23 -0
- package/src/generators/electron-app/files/src/renderer/index.html.template +20 -0
- package/src/generators/electron-app/files/src/renderer/src/App.test.tsx +61 -0
- package/src/generators/electron-app/files/src/renderer/src/App.tsx.template +43 -0
- package/src/generators/electron-app/files/src/renderer/src/assets/main.css +40 -0
- package/src/generators/electron-app/files/src/renderer/src/env.d.ts +14 -0
- package/src/generators/electron-app/files/src/renderer/src/main.tsx +25 -0
- package/src/generators/electron-app/files/src/shared/ipc.ts +54 -0
- package/src/generators/electron-app/files/tests/smoke/app.spec.ts.template +133 -0
- package/src/generators/electron-app/files/tool/electron_exec.sh.template +83 -0
- package/src/generators/electron-app/files/tsconfig.json +7 -0
- package/src/generators/electron-app/files/tsconfig.node.json +27 -0
- package/src/generators/electron-app/files/tsconfig.web.json +22 -0
- package/src/generators/electron-app/files/vitest.config.ts +32 -0
- package/src/generators/electron-app/files/vitest.setup.ts +1 -0
- package/src/generators/electron-app/generator.ts +288 -0
- package/src/generators/electron-app/schema.json +23 -0
- package/src/generators/flutter-app/docs/principles/stack/flutter/architecture.md +78 -0
- package/src/generators/flutter-app/docs/principles/stack/flutter/index.md +38 -0
- package/src/generators/flutter-app/docs/principles/stack/flutter/platform-channels.md +51 -0
- package/src/generators/flutter-app/docs/principles/stack/flutter/releases-and-distribution.md +59 -0
- package/src/generators/flutter-app/docs/principles/stack/flutter/state-management.md +85 -0
- package/src/generators/flutter-app/docs/principles/stack/flutter/testing.md +86 -0
- package/src/generators/flutter-app/docs/principles/stack/flutter/widgets-and-composition.md +69 -0
- package/src/generators/flutter-app/files/.gitignore.template +30 -0
- package/src/generators/flutter-app/files/README.md.template +100 -0
- package/src/generators/flutter-app/files/analysis_options.yaml.template +18 -0
- package/src/generators/flutter-app/files/integration_test/app_test.dart.template +64 -0
- package/src/generators/flutter-app/files/lib/app.dart.template +24 -0
- package/src/generators/flutter-app/files/lib/config/app_config.dart +15 -0
- package/src/generators/flutter-app/files/lib/data/repositories/status_repository.dart +36 -0
- package/src/generators/flutter-app/files/lib/data/services/api_client.dart +71 -0
- package/src/generators/flutter-app/files/lib/domain/models/health_status.dart +23 -0
- package/src/generators/flutter-app/files/lib/main.dart +11 -0
- package/src/generators/flutter-app/files/lib/router.dart +23 -0
- package/src/generators/flutter-app/files/lib/ui/core/theme/app_theme.dart +110 -0
- package/src/generators/flutter-app/files/lib/ui/home/home_view.dart +89 -0
- package/src/generators/flutter-app/files/lib/ui/home/home_view_model.dart.template +38 -0
- package/src/generators/flutter-app/files/project.json.template +51 -0
- package/src/generators/flutter-app/files/pubspec.yaml.template +47 -0
- package/src/generators/flutter-app/files/test/api_client_test.dart.template +63 -0
- package/src/generators/flutter-app/files/test/fakes/fake_status_repository.dart.template +19 -0
- package/src/generators/flutter-app/files/test/home_view_test.dart.template +58 -0
- package/src/generators/flutter-app/files/tool/flutter_exec.sh.template +60 -0
- package/src/generators/flutter-app/generator.ts +362 -0
- package/src/generators/flutter-app/schema.json +23 -0
- package/src/generators/go-microservice/docs/principles/stack/go/concurrency.md +123 -0
- package/src/generators/go-microservice/docs/principles/stack/go/index.md +70 -0
- package/src/generators/go-microservice/docs/principles/stack/go/testing.md +168 -0
- package/src/generators/go-microservice/files/.air.toml.template +38 -0
- package/src/generators/go-microservice/files/.env.template +4 -0
- package/src/generators/go-microservice/files/.golangci.yml.template +82 -0
- package/src/generators/go-microservice/files/Dockerfile.dev.template +12 -0
- package/src/generators/go-microservice/files/asyncapi-pubsub.yaml.template +33 -0
- package/src/generators/go-microservice/files/asyncapi-ws.yaml.template +34 -0
- package/src/generators/go-microservice/files/cmd/api/main.go.template +149 -0
- package/src/generators/go-microservice/files/cmd/api/main_test.go.template +99 -0
- package/src/generators/go-microservice/files/cmd/worker/cleanup/main.go.template +39 -0
- package/src/generators/go-microservice/files/db/schema.sql.template +24 -0
- package/src/generators/go-microservice/files/go.mod.template +39 -0
- package/src/generators/go-microservice/files/internal/config/config.go.template +52 -0
- package/src/generators/go-microservice/files/internal/config/otel.go.template +93 -0
- package/src/generators/go-microservice/files/internal/core/domain/errors.go.template +16 -0
- package/src/generators/go-microservice/files/internal/core/domain/model.go.template +28 -0
- package/src/generators/go-microservice/files/internal/core/domain/user.go.template +13 -0
- package/src/generators/go-microservice/files/internal/core/pagination.go.template +16 -0
- package/src/generators/go-microservice/files/internal/core/service/app_service.go.template +79 -0
- package/src/generators/go-microservice/files/internal/core/service/event_hub.go.template +9 -0
- package/src/generators/go-microservice/files/internal/core/service/message_queue.go.template +10 -0
- package/src/generators/go-microservice/files/internal/core/service/outbox_repository.go.template +31 -0
- package/src/generators/go-microservice/files/internal/core/service/repository.go.template +23 -0
- package/src/generators/go-microservice/files/internal/core/service/user_repository.go.template +15 -0
- package/src/generators/go-microservice/files/internal/core/service/user_service.go.template +43 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/app_handler.go.template +108 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/auth_middleware_test.go.template +52 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/clerk_webhook.go.template +202 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/clerk_webhook_test.go.template +82 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/health_handler.go.template +80 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/idempotency/middleware.go.template +87 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/idempotency/middleware_test.go.template +76 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/idempotency/repository.go.template +37 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/middleware_auth.go.template +40 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/middleware_loadshed.go.template +38 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/middleware_logging.go.template +40 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/middleware_ratelimit.go.template +48 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/middleware_test.go.template +81 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/router.go.template +105 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/types.go.template +70 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/websocket_handler.go.template +39 -0
- package/src/generators/go-microservice/files/internal/httpclient/http_client.go.template +87 -0
- package/src/generators/go-microservice/files/internal/kafka/kafka.go.template +34 -0
- package/src/generators/go-microservice/files/internal/postgres/postgres.go.template +195 -0
- package/src/generators/go-microservice/files/internal/postgres/postgres_test.go.template +156 -0
- package/src/generators/go-microservice/files/internal/postgres/user_repository.go.template +56 -0
- package/src/generators/go-microservice/files/internal/pubsub/gcp_pubsub.go.template +35 -0
- package/src/generators/go-microservice/files/internal/websocket/client.go.template +151 -0
- package/src/generators/go-microservice/files/internal/websocket/hub.go.template +261 -0
- package/src/generators/go-microservice/files/scripts/apply-schema.sh.template +21 -0
- package/src/generators/go-microservice/files/tools/tools.go.template +10 -0
- package/src/generators/go-microservice/generator.ts +240 -0
- package/src/generators/go-microservice/schema.json +63 -0
- package/src/generators/nextjs-app/docs/principles/stack/typescript/frontend.md +65 -0
- package/src/generators/nextjs-app/files/.dockerignore.template +7 -0
- package/src/generators/nextjs-app/files/.env.example.template +24 -0
- package/src/generators/nextjs-app/files/.gitignore.template +5 -0
- package/src/generators/nextjs-app/files/Dockerfile +53 -0
- package/src/generators/nextjs-app/files/app/(auth)/sign-in/__sign-in__/page.tsx.template +9 -0
- package/src/generators/nextjs-app/files/app/(auth)/sign-up/__sign-up__/page.tsx.template +9 -0
- package/src/generators/nextjs-app/files/app/api/config/route.ts.template +39 -0
- package/src/generators/nextjs-app/files/app/api/healthz/route.test.ts +15 -0
- package/src/generators/nextjs-app/files/app/api/healthz/route.ts +5 -0
- package/src/generators/nextjs-app/files/app/api/proxy/__path__/route.test.ts.template +55 -0
- package/src/generators/nextjs-app/files/app/api/proxy/__path__/route.ts.template +126 -0
- package/src/generators/nextjs-app/files/app/error.tsx +39 -0
- package/src/generators/nextjs-app/files/app/global-error.tsx +68 -0
- package/src/generators/nextjs-app/files/app/globals.css +105 -0
- package/src/generators/nextjs-app/files/app/layout.tsx +59 -0
- package/src/generators/nextjs-app/files/app/loading.tsx +13 -0
- package/src/generators/nextjs-app/files/app/not-found.tsx +30 -0
- package/src/generators/nextjs-app/files/app/page.tsx +20 -0
- package/src/generators/nextjs-app/files/components/providers/default.tsx +19 -0
- package/src/generators/nextjs-app/files/components/providers/production.tsx +32 -0
- package/src/generators/nextjs-app/files/components/providers/telemetry.tsx +76 -0
- package/src/generators/nextjs-app/files/components/render-smoke.test.tsx +29 -0
- package/src/generators/nextjs-app/files/components/theme-provider.tsx +11 -0
- package/src/generators/nextjs-app/files/components.json +21 -0
- package/src/generators/nextjs-app/files/eslint.config.mjs +120 -0
- package/src/generators/nextjs-app/files/hooks/use-toast.ts +7 -0
- package/src/generators/nextjs-app/files/instrumentation.ts +90 -0
- package/src/generators/nextjs-app/files/lib/api/fetcher.ts.template +130 -0
- package/src/generators/nextjs-app/files/lib/config.ts +21 -0
- package/src/generators/nextjs-app/files/lib/logger.ts +29 -0
- package/src/generators/nextjs-app/files/lib/schemas/index.ts +19 -0
- package/src/generators/nextjs-app/files/lib/utils.ts +6 -0
- package/src/generators/nextjs-app/files/next.config.mjs +9 -0
- package/src/generators/nextjs-app/files/package.json +70 -0
- package/src/generators/nextjs-app/files/postcss.config.mjs +8 -0
- package/src/generators/nextjs-app/files/proxy.test.ts.template +30 -0
- package/src/generators/nextjs-app/files/proxy.ts +31 -0
- package/src/generators/nextjs-app/files/public/.gitkeep +1 -0
- package/src/generators/nextjs-app/files/tsconfig.json +42 -0
- package/src/generators/nextjs-app/files/vitest.config.mts +15 -0
- package/src/generators/nextjs-app/files/vitest.setup.ts +7 -0
- package/src/generators/nextjs-app/generator.ts +307 -0
- package/src/generators/nextjs-app/schema.json +44 -0
- package/src/generators/python-microservice/docs/principles/stack/python/async.md +168 -0
- package/src/generators/python-microservice/docs/principles/stack/python/documentation.md +240 -0
- package/src/generators/python-microservice/docs/principles/stack/python/mcp.md +147 -0
- package/src/generators/python-microservice/docs/principles/stack/python/resilience.md +193 -0
- package/src/generators/python-microservice/docs/principles/stack/python/testing.md +322 -0
- package/src/generators/python-microservice/files/.env.example.template +30 -0
- package/src/generators/python-microservice/files/Dockerfile.template +36 -0
- package/src/generators/python-microservice/files/db/schema.sql.template +19 -0
- package/src/generators/python-microservice/files/pyproject.toml.template +76 -0
- package/src/generators/python-microservice/files/scripts/apply-schema.sh.template +25 -0
- package/src/generators/python-microservice/files/src/__packageName__/adapters/comfyui.py.template +87 -0
- package/src/generators/python-microservice/files/src/__packageName__/adapters/config.py.template +48 -0
- package/src/generators/python-microservice/files/src/__packageName__/adapters/database.py.template +21 -0
- package/src/generators/python-microservice/files/src/__packageName__/adapters/message_queue.py.template +29 -0
- package/src/generators/python-microservice/files/src/__packageName__/adapters/repository.py.template +130 -0
- package/src/generators/python-microservice/files/src/__packageName__/adapters/telemetry.py.template +68 -0
- package/src/generators/python-microservice/files/src/__packageName__/adapters/websocket_hub.py.template +36 -0
- package/src/generators/python-microservice/files/src/__packageName__/core/domain/entities.py.template +22 -0
- package/src/generators/python-microservice/files/src/__packageName__/core/domain/exceptions.py.template +43 -0
- package/src/generators/python-microservice/files/src/__packageName__/core/ports.py.template +42 -0
- package/src/generators/python-microservice/files/src/__packageName__/core/service/example_service.py.template +68 -0
- package/src/generators/python-microservice/files/src/__packageName__/entrypoints/api/dependencies.py.template +50 -0
- package/src/generators/python-microservice/files/src/__packageName__/entrypoints/api/middleware.py.template +131 -0
- package/src/generators/python-microservice/files/src/__packageName__/entrypoints/api/router.py.template +37 -0
- package/src/generators/python-microservice/files/src/__packageName__/entrypoints/api/websocket_handler.py.template +20 -0
- package/src/generators/python-microservice/files/src/__packageName__/entrypoints/worker/cleanup.py.template +35 -0
- package/src/generators/python-microservice/files/src/__packageName__/entrypoints/worker/worker.py.template +28 -0
- package/src/generators/python-microservice/files/src/__packageName__/main.py.template +108 -0
- package/src/generators/python-microservice/files/tests/test_main.py.template +74 -0
- package/src/generators/python-microservice/files/tests/test_middleware.py.template +109 -0
- package/src/generators/python-microservice/files/tests/test_worker.py.template +16 -0
- package/src/generators/python-microservice/generator.ts +286 -0
- package/src/generators/python-microservice/schema.json +86 -0
- package/src/generators/shared/brand-tokens.ts +301 -0
- package/src/generators/shared/capabilities.ts +349 -0
- package/src/generators/shared/provenance.ts +61 -0
- package/src/generators/shared/scaffold-helpers.ts +309 -0
- package/src/generators/system-test-runner/NATIVE-CHECK-CONTRACT.md +20 -0
- package/src/generators/system-test-runner/files/tests/bets/.gitkeep +0 -0
- package/src/generators/system-test-runner/files/tests/bets/_archive/.gitkeep +0 -0
- package/src/generators/system-test-runner/files/tests/conftest.py.template +503 -0
- package/src/generators/system-test-runner/files/tests/pyproject.toml.template +20 -0
- package/src/generators/system-test-runner/files/tests/system/pages/__init__.py.template +9 -0
- package/src/generators/system-test-runner/files/tests/system/pages/base_page.py.template +36 -0
- package/src/generators/system-test-runner/files/tests/system/test_a11y_smoke.py.template +132 -0
- package/src/generators/system-test-runner/files/tests/system/test_contract_conformance.py.template +140 -0
- package/src/generators/system-test-runner/files/tests/system/test_layout_geometry.py.template +109 -0
- package/src/generators/system-test-runner/files/tests/system/test_render_smoke.py.template +257 -0
- package/src/generators/system-test-runner/files/tests/system/test_system.py.template +158 -0
- package/src/generators/system-test-runner/files/tests/system/test_token_conformance.py.template +206 -0
- package/src/generators/system-test-runner/files/tests/system/test_visual_regression.py.template +104 -0
- package/src/generators/system-test-runner/generator.ts +196 -0
- package/src/generators/system-test-runner/schema.json +24 -0
- package/src/generators/workspace-dev-cli/cli-src/build.mjs +42 -0
- package/src/generators/workspace-dev-cli/cli-src/dist/dev-bundle.js +2168 -0
- package/src/generators/workspace-dev-cli/cli-src/src/commands/bet.ts +442 -0
- package/src/generators/workspace-dev-cli/cli-src/src/commands/completion.ts +87 -0
- package/src/generators/workspace-dev-cli/cli-src/src/commands/doctor.ts +139 -0
- package/src/generators/workspace-dev-cli/cli-src/src/commands/lifecycle.ts +548 -0
- package/src/generators/workspace-dev-cli/cli-src/src/commands/quality.ts +127 -0
- package/src/generators/workspace-dev-cli/cli-src/src/commands/surface.ts +214 -0
- package/src/generators/workspace-dev-cli/cli-src/src/index.ts +127 -0
- package/src/generators/workspace-dev-cli/cli-src/src/registry.ts +194 -0
- package/src/generators/workspace-dev-cli/cli-src/src/theme/color.ts +130 -0
- package/src/generators/workspace-dev-cli/cli-src/src/theme/render.ts +158 -0
- package/src/generators/workspace-dev-cli/cli-src/src/theme/tokens.ts +122 -0
- package/src/generators/workspace-dev-cli/cli-src/src/util/context.ts +43 -0
- package/src/generators/workspace-dev-cli/cli-src/src/util/extensions.ts +99 -0
- package/src/generators/workspace-dev-cli/cli-src/src/util/paths.ts +46 -0
- package/src/generators/workspace-dev-cli/cli-src/src/util/proc.ts +106 -0
- package/src/generators/workspace-dev-cli/cli-src/src/util/prompt.ts +108 -0
- package/src/generators/workspace-dev-cli/cli-src/src/util/runners.ts +70 -0
- package/src/generators/workspace-dev-cli/cli-src/src/util/services.ts +221 -0
- package/src/generators/workspace-dev-cli/cli-src/src/util/version.ts +21 -0
- package/src/generators/workspace-dev-cli/cli-src/tsconfig.json +16 -0
- package/src/generators/workspace-dev-cli/files/.agents/skills/workspace-cli/SKILL.md.template +74 -0
- package/src/generators/workspace-dev-cli/files/dev.template +16 -0
- package/src/generators/workspace-dev-cli/files/docker-compose.yml.template +20 -0
- package/src/generators/workspace-dev-cli/files/scripts/cli/templates/milestone-test.pytmpl.template +46 -0
- package/src/generators/workspace-dev-cli/files/scripts/cli/templates/slice-test.pytmpl.template +38 -0
- package/src/generators/workspace-dev-cli/generator.ts +136 -0
- package/src/generators/workspace-dev-cli/schema.json +22 -0
- package/src/hidden-skills/code-intelligence.md +135 -0
- package/src/hidden-skills/groundwork-architect/SKILL.md +114 -0
- package/src/hidden-skills/groundwork-architect/references/agentic-systems.md +44 -0
- package/src/hidden-skills/groundwork-architect/references/ai-native-architecture.md +37 -0
- package/src/hidden-skills/groundwork-architect/references/api-and-contracts.md +45 -0
- package/src/hidden-skills/groundwork-architect/references/core-and-boundaries.md +45 -0
- package/src/hidden-skills/groundwork-architect/references/data-architecture.md +33 -0
- package/src/hidden-skills/groundwork-architect/references/decision-records.md +34 -0
- package/src/hidden-skills/groundwork-architect/references/durable-execution.md +45 -0
- package/src/hidden-skills/groundwork-architect/references/evolutionary-architecture.md +37 -0
- package/src/hidden-skills/groundwork-architect/references/identity-and-access.md +41 -0
- package/src/hidden-skills/groundwork-architect/references/integration-patterns.md +39 -0
- package/src/hidden-skills/groundwork-architect/references/observability.md +36 -0
- package/src/hidden-skills/groundwork-architect/references/performance-and-scale.md +41 -0
- package/src/hidden-skills/groundwork-architect/references/platform-and-delivery.md +47 -0
- package/src/hidden-skills/groundwork-architect/references/realtime-and-async.md +28 -0
- package/src/hidden-skills/groundwork-architect/references/reliability.md +31 -0
- package/src/hidden-skills/groundwork-architect/references/security-and-trust.md +47 -0
- package/src/hidden-skills/groundwork-architect/references/surface-architecture.md +40 -0
- package/src/hidden-skills/groundwork-architect/sync-anchor.md +34 -0
- package/src/hidden-skills/groundwork-architecture/architecture-template.md +50 -0
- package/src/hidden-skills/groundwork-architecture/instructions.md +139 -0
- package/src/hidden-skills/groundwork-architecture/phases/01-context-ingestion.md +18 -0
- package/src/hidden-skills/groundwork-architecture/phases/02-technical-constraints.md +27 -0
- package/src/hidden-skills/groundwork-architecture/phases/03-service-design.md +19 -0
- package/src/hidden-skills/groundwork-architecture/phases/04-data-flow-communication.md +23 -0
- package/src/hidden-skills/groundwork-architecture/phases/05-component-boundaries-contracts.md +17 -0
- package/src/hidden-skills/groundwork-architecture/phases/06-draft-review-present.md +38 -0
- package/src/hidden-skills/groundwork-architecture/phases/07-commit.md +33 -0
- package/src/hidden-skills/groundwork-architecture/templates/architecture-cache.md +43 -0
- package/src/hidden-skills/groundwork-architecture-extract/instructions.md +163 -0
- package/src/hidden-skills/groundwork-architecture-extract/templates/architecture-extract-cache.md +21 -0
- package/src/hidden-skills/groundwork-bet/briefs/acceptance-auditor.md +68 -0
- package/src/hidden-skills/groundwork-bet/briefs/blind-reviewer.md +56 -0
- package/src/hidden-skills/groundwork-bet/briefs/coverage-auditor.md +95 -0
- package/src/hidden-skills/groundwork-bet/briefs/edge-case-tracer.md +64 -0
- package/src/hidden-skills/groundwork-bet/briefs/experience-auditor.md +83 -0
- package/src/hidden-skills/groundwork-bet/briefs/slice-worker.md +257 -0
- package/src/hidden-skills/groundwork-bet/instructions.md +88 -0
- package/src/hidden-skills/groundwork-bet/templates/bet-progress-test.md +115 -0
- package/src/hidden-skills/groundwork-bet/templates/change-proposal.md +38 -0
- package/src/hidden-skills/groundwork-bet/templates/decomposition/meta.json +4 -0
- package/src/hidden-skills/groundwork-bet/templates/decomposition/milestone-index.md +31 -0
- package/src/hidden-skills/groundwork-bet/templates/decomposition/slice.md +31 -0
- package/src/hidden-skills/groundwork-bet/templates/pitch.md +45 -0
- package/src/hidden-skills/groundwork-bet/templates/technical-design/01-ui-design.md +51 -0
- package/src/hidden-skills/groundwork-bet/templates/technical-design/02-data-flows.md +36 -0
- package/src/hidden-skills/groundwork-bet/templates/technical-design/03-api-design.md +90 -0
- package/src/hidden-skills/groundwork-bet/templates/technical-design/04-data-design.md +29 -0
- package/src/hidden-skills/groundwork-bet/workflows/01-discovery.md +200 -0
- package/src/hidden-skills/groundwork-bet/workflows/02-design.md +178 -0
- package/src/hidden-skills/groundwork-bet/workflows/03-decomposition.md +242 -0
- package/src/hidden-skills/groundwork-bet/workflows/04-delivery.md +226 -0
- package/src/hidden-skills/groundwork-bet/workflows/05-validation.md +210 -0
- package/src/hidden-skills/groundwork-design-system/instructions.md +125 -0
- package/src/hidden-skills/groundwork-design-system/templates/brand-tokens.md +182 -0
- package/src/hidden-skills/groundwork-design-system/templates/design-system-cache.md +64 -0
- package/src/hidden-skills/groundwork-design-system/tracks/_foundation.md +136 -0
- package/src/hidden-skills/groundwork-design-system/tracks/agentic-protocol.md +269 -0
- package/src/hidden-skills/groundwork-design-system/tracks/cli.md +355 -0
- package/src/hidden-skills/groundwork-design-system/tracks/graphical-ui.md +330 -0
- package/src/hidden-skills/groundwork-design-system-extract/instructions.md +124 -0
- package/src/hidden-skills/groundwork-design-system-extract/templates/design-system-extract-cache.md +19 -0
- package/src/hidden-skills/groundwork-designer/SKILL.md +108 -0
- package/src/hidden-skills/groundwork-designer/references/accessibility.md +33 -0
- package/src/hidden-skills/groundwork-designer/references/ai-native-design.md +37 -0
- package/src/hidden-skills/groundwork-designer/references/design-review.md +29 -0
- package/src/hidden-skills/groundwork-designer/references/design-systems-and-tokens.md +33 -0
- package/src/hidden-skills/groundwork-designer/references/interaction-and-motion.md +37 -0
- package/src/hidden-skills/groundwork-designer/references/layout-and-space.md +33 -0
- package/src/hidden-skills/groundwork-designer/references/usability-and-ux.md +33 -0
- package/src/hidden-skills/groundwork-designer/references/visual-craft.md +49 -0
- package/src/hidden-skills/groundwork-designer/sync-anchor.md +20 -0
- package/src/hidden-skills/groundwork-doc-sync/instructions.md +100 -0
- package/src/hidden-skills/groundwork-elicit/instructions.md +66 -0
- package/src/hidden-skills/groundwork-elicit/methods.md +65 -0
- package/src/hidden-skills/groundwork-infra-adopt/instructions.md +168 -0
- package/src/hidden-skills/groundwork-infra-adopt/templates/infra-adopt-cache.md +21 -0
- package/src/hidden-skills/groundwork-mvp/instructions.md +223 -0
- package/src/hidden-skills/groundwork-mvp/templates/mvp-cache.md +9 -0
- package/src/hidden-skills/groundwork-patch/instructions.md +40 -0
- package/src/hidden-skills/groundwork-persona/instructions.md +65 -0
- package/src/hidden-skills/groundwork-product/SKILL.md +102 -0
- package/src/hidden-skills/groundwork-product/references/ai-native-product.md +45 -0
- package/src/hidden-skills/groundwork-product/references/discovery-and-opportunity.md +38 -0
- package/src/hidden-skills/groundwork-product/references/product-risks.md +52 -0
- package/src/hidden-skills/groundwork-product/references/requirements-and-specs.md +39 -0
- package/src/hidden-skills/groundwork-product/references/scope-and-sequencing.md +35 -0
- package/src/hidden-skills/groundwork-product/references/shaping-and-appetite.md +48 -0
- package/src/hidden-skills/groundwork-product/references/success-metrics-and-signals.md +37 -0
- package/src/hidden-skills/groundwork-product/sync-anchor.md +19 -0
- package/src/hidden-skills/groundwork-product-brief/instructions.md +231 -0
- package/src/hidden-skills/groundwork-product-brief-extract/instructions.md +139 -0
- package/src/hidden-skills/groundwork-product-brief-extract/templates/product-brief-extract-cache.md +17 -0
- package/src/hidden-skills/groundwork-review/checklists/architecture.md +93 -0
- package/src/hidden-skills/groundwork-review/checklists/bet-pitch.md +94 -0
- package/src/hidden-skills/groundwork-review/checklists/decomposition.md +135 -0
- package/src/hidden-skills/groundwork-review/checklists/design-system.md +85 -0
- package/src/hidden-skills/groundwork-review/checklists/domain-entity.md +66 -0
- package/src/hidden-skills/groundwork-review/checklists/implementation-readiness.md +47 -0
- package/src/hidden-skills/groundwork-review/checklists/infrastructure.md +68 -0
- package/src/hidden-skills/groundwork-review/checklists/maturity.md +71 -0
- package/src/hidden-skills/groundwork-review/checklists/product-brief.md +69 -0
- package/src/hidden-skills/groundwork-review/checklists/technical-design.md +112 -0
- package/src/hidden-skills/groundwork-review/instructions.md +181 -0
- package/src/hidden-skills/groundwork-scaffold/instructions.md +254 -0
- package/src/hidden-skills/groundwork-scaffold/phases/01-ingestion-service-mapping.md +87 -0
- package/src/hidden-skills/groundwork-scaffold/phases/02-scaffolding-execution.md +15 -0
- package/src/hidden-skills/groundwork-scaffold/phases/03-service-documentation-api-stubs.md +100 -0
- package/src/hidden-skills/groundwork-scaffold/phases/04-infrastructure-verification.md +17 -0
- package/src/hidden-skills/groundwork-scaffold/phases/05-draft-review.md +19 -0
- package/src/hidden-skills/groundwork-scaffold/phases/06-commit.md +19 -0
- package/src/hidden-skills/groundwork-scaffold/templates/scaffold-cache.md +23 -0
- package/src/hidden-skills/groundwork-scan/instructions.md +164 -0
- package/src/hidden-skills/groundwork-scan/references/digest-schema.md +66 -0
- package/src/hidden-skills/groundwork-scan/references/exclusions.md +44 -0
- package/src/hidden-skills/groundwork-scan/templates/architecture-findings.md +42 -0
- package/src/hidden-skills/groundwork-scan/templates/design-findings.md +23 -0
- package/src/hidden-skills/groundwork-scan/templates/overview.md +26 -0
- package/src/hidden-skills/groundwork-scan/templates/product-findings.md +23 -0
- package/src/hidden-skills/groundwork-scan/templates/scan-state.json +19 -0
- package/src/hidden-skills/groundwork-stack-forge/instructions.md +150 -0
- package/src/hidden-skills/groundwork-stack-forge/references/authoring-engineer-skills.md +107 -0
- package/src/hidden-skills/groundwork-surface-activation/instructions.md +138 -0
- package/src/hidden-skills/groundwork-update/briefs/reconcile-worker.md +196 -0
- package/src/hidden-skills/groundwork-update/instructions.md +200 -0
- package/src/hidden-skills/groundwork-writer/SKILL.md +278 -0
- package/src/hidden-skills/maturity-model.md +125 -0
- package/src/hidden-skills/operating-contract.md +400 -0
- package/src/hidden-skills/repo-map-schema.md +90 -0
- package/src/hidden-skills/templates/adr.md +57 -0
- package/src/hidden-skills/templates/capability-ports.md +71 -0
- package/src/hidden-skills/templates/discovery-notes.md +33 -0
- package/src/hidden-skills/templates/domain-entity.md +80 -0
- package/src/hidden-skills/templates/gap-ledger.md +21 -0
- package/src/hidden-skills/templates/handoff.md +37 -0
- package/src/hidden-skills/templates/maturity.md +39 -0
- package/src/hidden-skills/templates/surfaces.md +207 -0
- package/src/skills/groundwork-check/SKILL.md +56 -0
- package/src/skills/groundwork-check/instructions.md +70 -0
- package/src/skills/groundwork-orchestrator/SKILL.md +176 -0
- package/src/skills/groundwork-orchestrator/workflow-index.md +50 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Go Service Standards
|
|
2
|
+
|
|
3
|
+
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.
|
|
4
|
+
|
|
5
|
+
## Principles
|
|
6
|
+
|
|
7
|
+
### 1. Standard Library First
|
|
8
|
+
|
|
9
|
+
`net/http`, `context`, `database/sql` — the standard library is the default. Reach for third-party packages 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.
|
|
10
|
+
|
|
11
|
+
### 2. A Pure Core, Swappable Edges
|
|
12
|
+
|
|
13
|
+
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 (e.g. `Repository`) declared in the core package that consumes them, with technology-named implementations at the edge. Packages are nested 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` (HTTP edge) — with composition roots in `cmd/`. Exported interfaces declared at the point of use, unexported or concrete edge types returned. `depguard` (in `.golangci.yml.template`) fails the build if `internal/core/...` imports an edge package.
|
|
14
|
+
|
|
15
|
+
### 3. Errors Are Values with Context
|
|
16
|
+
|
|
17
|
+
Wrap errors with `fmt.Errorf("doing X: %w", err)` when adding context. Inspect with `errors.Is` and `errors.As` at the boundary. Never `panic` in service code; `panic` is reserved for truly unrecoverable conditions and is recovered only at the HTTP boundary.
|
|
18
|
+
|
|
19
|
+
Sentinel errors are defined where the caller must branch on them. Structured error types are defined where the caller needs detail.
|
|
20
|
+
|
|
21
|
+
### 4. Context Is Threaded Everywhere
|
|
22
|
+
|
|
23
|
+
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.
|
|
24
|
+
|
|
25
|
+
### 5. Concurrency Is Simple or Explicit
|
|
26
|
+
|
|
27
|
+
`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. Shared state is accessed through channels by default, through mutexes when a channel would be awkward, and never through silence.
|
|
28
|
+
|
|
29
|
+
### 6. Interfaces Are Defined by Consumers
|
|
30
|
+
|
|
31
|
+
Define interfaces in the package that consumes them — "accept interfaces, return structs." A package that defines an interface for its own use is leaking internals. Small interfaces (one to three methods) compose well; wide interfaces are a smell.
|
|
32
|
+
|
|
33
|
+
### 7. Dependency Injection Is Manual and Explicit
|
|
34
|
+
|
|
35
|
+
No runtime DI frameworks. Dependencies are passed into constructors. Composition happens in a `cmd/` entry point — the "composition root" pattern. Every dependency is visible at build time; cycles are impossible by construction.
|
|
36
|
+
|
|
37
|
+
### 8. Configuration Validation at Startup
|
|
38
|
+
|
|
39
|
+
Validate all environment variables immediately at startup using declarative struct tags (e.g., using `kelseyhightower/envconfig`). Do not scatter `os.Getenv` throughout the codebase. If configuration is missing or invalid, the service must crash immediately before accepting traffic.
|
|
40
|
+
|
|
41
|
+
```go
|
|
42
|
+
type Config struct {
|
|
43
|
+
DatabaseURL string `envconfig:"DATABASE_URL" required:"true"`
|
|
44
|
+
Port int `envconfig:"PORT" default:"8080"`
|
|
45
|
+
Environment string `envconfig:"ENVIRONMENT" default:"production"`
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
func main() {
|
|
49
|
+
var cfg Config
|
|
50
|
+
if err := envconfig.Process("myapp", &cfg); err != nil {
|
|
51
|
+
log.Fatalf("failed to load configuration: %v", err)
|
|
52
|
+
}
|
|
53
|
+
// ...
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### 9. Tests Use the Real Thing Where Possible
|
|
58
|
+
|
|
59
|
+
Service tests spin up a real Postgres container via Testcontainers and exercise the handler through HTTP. Mock only the expensive external edges (model clients, third-party APIs).
|
|
60
|
+
|
|
61
|
+
## Anti-Patterns
|
|
62
|
+
|
|
63
|
+
- **Framework-flavoured Go.** Heavy router libraries, ORMs that rewrite queries.
|
|
64
|
+
- **`interface{}` or `any` as a type.** Except at reflection boundaries. Name the type.
|
|
65
|
+
- **Package-level mutable state.** Config, loggers, metrics registries in package variables. Inject them.
|
|
66
|
+
- **Goroutines without supervision.** If you launch it, you own its lifetime.
|
|
67
|
+
- **`init()` functions that do work.** `init` is for registering, not for running.
|
|
68
|
+
- **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.
|
|
69
|
+
|
|
70
|
+
## Canonical References
|
|
71
|
+
|
|
72
|
+
- *The Go Programming Language*, Donovan & Kernighan
|
|
73
|
+
- *100 Go Mistakes and How to Avoid Them*, Teiva Harsanyi
|
|
74
|
+
- *Dave Cheney's blog* (dave.cheney.net)
|
|
75
|
+
- *Effective Go* (go.dev/doc/effective_go)
|
|
76
|
+
- *Uber Go Style Guide* (github.com/uber-go/guide)
|
|
77
|
+
- *The Go Memory Model* (golang.org/ref/mem)
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# HTTP Handlers
|
|
2
|
+
|
|
3
|
+
## Handler Framework
|
|
4
|
+
|
|
5
|
+
Handlers use typed function registration (e.g., Huma v2, Chi, or standard library). The Go types are the spec — no separate YAML to drift from production. Request types are validated before the handler runs. Error responses are serialised to RFC 9457 `application/problem+json`.
|
|
6
|
+
|
|
7
|
+
## Handler Structure
|
|
8
|
+
|
|
9
|
+
### Registration
|
|
10
|
+
|
|
11
|
+
Register every handler via a typed registration function. Pass an operation for metadata and a typed function for implementation:
|
|
12
|
+
|
|
13
|
+
```go
|
|
14
|
+
func RegisterEntity(api huma.API, svc service.EntityService) {
|
|
15
|
+
huma.Register(api, huma.Operation{
|
|
16
|
+
OperationID: "createEntity",
|
|
17
|
+
Method: http.MethodPost,
|
|
18
|
+
Path: "/entities",
|
|
19
|
+
Summary: "Create an Entity",
|
|
20
|
+
Tags: []string{"Entities"},
|
|
21
|
+
DefaultStatus: http.StatusCreated,
|
|
22
|
+
Security: []map[string][]string{{"bearerAuth": {}}},
|
|
23
|
+
}, func(ctx context.Context, req *CreateEntityRequest) (*CreateEntityResponse, error) {
|
|
24
|
+
// ...
|
|
25
|
+
})
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Each `RegisterXxx` function takes the API and the service interfaces it needs. Called once from the composition root in `internal/entrypoints/api/router.go`.
|
|
30
|
+
|
|
31
|
+
### Handler Signature
|
|
32
|
+
|
|
33
|
+
```go
|
|
34
|
+
func(ctx context.Context, req *InputType) (*OutputType, error)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
- `ctx` carries request context, auth principal, and cancellation signal.
|
|
38
|
+
- `req` is fully validated before the function is called.
|
|
39
|
+
- Return `(nil, huma.NewError(...))` to abort with a specific HTTP status.
|
|
40
|
+
- Return `(nil, err)` for unexpected errors — framework converts to a 500.
|
|
41
|
+
|
|
42
|
+
### Request Types
|
|
43
|
+
|
|
44
|
+
Request structs compose path, query, header, and body fields with struct tags:
|
|
45
|
+
|
|
46
|
+
```go
|
|
47
|
+
type CreateEntityRequest struct {
|
|
48
|
+
IdempotencyKey string `header:"Idempotency-Key" required:"false" format:"uuid"`
|
|
49
|
+
Body createEntityBody
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
type createEntityBody struct {
|
|
53
|
+
Name string `json:"name" min:"1" max:"100" example:"example"`
|
|
54
|
+
Email string `json:"email" format:"email"`
|
|
55
|
+
RefID *string `json:"ref_id,omitempty"`
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Use a nested body type (unexported) to separate the JSON body from path/query/header fields.
|
|
60
|
+
|
|
61
|
+
### Response Types
|
|
62
|
+
|
|
63
|
+
```go
|
|
64
|
+
type CreateEntityResponse struct {
|
|
65
|
+
Body EntityItem
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
type EntityItem struct {
|
|
69
|
+
ID string `json:"id" format:"uuid" readOnly:"true"`
|
|
70
|
+
Name string `json:"name"`
|
|
71
|
+
CreatedAt string `json:"created_at" format:"date-time" readOnly:"true"`
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Use `readOnly:"true"` on fields never accepted on input. Keep response types separate from request body types.
|
|
76
|
+
|
|
77
|
+
## Authentication
|
|
78
|
+
|
|
79
|
+
Extract the principal at the top of the handler:
|
|
80
|
+
|
|
81
|
+
```go
|
|
82
|
+
func(ctx context.Context, req *GetEntityRequest) (*GetEntityResponse, error) {
|
|
83
|
+
principal, err := auth.PrincipalFromContext(ctx)
|
|
84
|
+
if err != nil {
|
|
85
|
+
return nil, huma.NewError(http.StatusUnauthorized, "unauthorized")
|
|
86
|
+
}
|
|
87
|
+
// use principal.ID(), principal.IsSystem(), etc.
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Pass the principal into service calls — never access auth state from globals.
|
|
92
|
+
|
|
93
|
+
## Error Handling
|
|
94
|
+
|
|
95
|
+
Use framework helpers for expected domain errors; return unwrapped errors for unexpected failures:
|
|
96
|
+
|
|
97
|
+
```go
|
|
98
|
+
// Domain validation error
|
|
99
|
+
if err := entity.Validate(); err != nil {
|
|
100
|
+
return nil, huma.NewError(http.StatusUnprocessableEntity, err.Error())
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Auth failure
|
|
104
|
+
return nil, huma.NewError(http.StatusForbidden, "insufficient permissions")
|
|
105
|
+
|
|
106
|
+
// Unexpected error — framework returns 500
|
|
107
|
+
saved, err := svc.Save(ctx, principal, entity)
|
|
108
|
+
if err != nil {
|
|
109
|
+
return nil, err // log at the service layer
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Do not log errors in the handler and also return them. Log at the layer with enough context; wrap elsewhere.
|
|
114
|
+
|
|
115
|
+
## Inbound Defenses
|
|
116
|
+
|
|
117
|
+
### CORS Configuration
|
|
118
|
+
|
|
119
|
+
Configure CORS explicitly at the router level. Never use wildcard `"*"` origins in production.
|
|
120
|
+
|
|
121
|
+
```go
|
|
122
|
+
import "github.com/go-chi/cors"
|
|
123
|
+
|
|
124
|
+
router.Use(cors.Handler(cors.Options{
|
|
125
|
+
AllowedOrigins: []string{"https://app.example.com"}, // Loaded from config
|
|
126
|
+
AllowedMethods: []string{"GET", "POST", "PATCH", "DELETE", "OPTIONS"},
|
|
127
|
+
AllowedHeaders: []string{"Accept", "Authorization", "Content-Type", "Idempotency-Key"},
|
|
128
|
+
AllowCredentials: true,
|
|
129
|
+
}))
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Idempotency Middleware
|
|
133
|
+
|
|
134
|
+
Mutating endpoints (`POST`, `PATCH`) must be idempotent. Extract the `Idempotency-Key` header and verify its state before allowing the handler to execute.
|
|
135
|
+
|
|
136
|
+
```go
|
|
137
|
+
func IdempotencyMiddleware(store IdempotencyStore) func(http.Handler) http.Handler {
|
|
138
|
+
return func(next http.Handler) http.Handler {
|
|
139
|
+
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
140
|
+
key := r.Header.Get("Idempotency-Key")
|
|
141
|
+
if key == "" && (r.Method == "POST" || r.Method == "PATCH") {
|
|
142
|
+
http.Error(w, "Idempotency-Key required", http.StatusBadRequest)
|
|
143
|
+
return
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Check store and return cached response if COMPLETED,
|
|
147
|
+
// or 409 Conflict if IN_PROGRESS.
|
|
148
|
+
// Otherwise, proceed.
|
|
149
|
+
next.ServeHTTP(w, r)
|
|
150
|
+
})
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Handler Placement
|
|
156
|
+
|
|
157
|
+
- One `RegisterXxx` function per domain resource in `internal/entrypoints/api/routes/<resource>.go`
|
|
158
|
+
- Request/response types in the same file as the handler
|
|
159
|
+
- Domain conversion helpers (`toXxx`) at the bottom of the file, unexported
|
|
160
|
+
- Inline closures for simple handlers; named methods on a struct for handlers that share helpers
|
|
161
|
+
- When a handler needs more than two service calls or substantial conditional logic, move logic to the application service layer
|
|
162
|
+
|
|
163
|
+
## Operation Metadata
|
|
164
|
+
|
|
165
|
+
Every operation needs:
|
|
166
|
+
|
|
167
|
+
- `OperationID` — unique, camelCase, used as the generated client method name
|
|
168
|
+
- `Method` + `Path` — HTTP verb and URI template; use `{id}` placeholders
|
|
169
|
+
- `Summary` — one sentence, title-cased, no period
|
|
170
|
+
- `Tags` — group the endpoint in the OpenAPI UI
|
|
171
|
+
- `Security` — authentication scheme for the endpoint
|
|
172
|
+
- `DefaultStatus` — only for non-200 success codes (201 for creation, 204 for deletions)
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# Implementation Patterns
|
|
2
|
+
|
|
3
|
+
Concrete Go patterns for trace-first logging, a pure core with swappable edges, error handling, and dependency injection.
|
|
4
|
+
|
|
5
|
+
## 1. Trace-First Development
|
|
6
|
+
|
|
7
|
+
Every inbound request starts a trace. Every outbound request cascades it.
|
|
8
|
+
|
|
9
|
+
### Initializing a Span
|
|
10
|
+
|
|
11
|
+
```go
|
|
12
|
+
import "go.opentelemetry.io/otel/trace"
|
|
13
|
+
|
|
14
|
+
func (s *OrderService) Process(ctx context.Context, orderID string) error {
|
|
15
|
+
ctx, span := s.tracer.Start(ctx, "OrderService.Process")
|
|
16
|
+
defer span.End()
|
|
17
|
+
|
|
18
|
+
span.SetAttributes(attribute.String("order.id", orderID))
|
|
19
|
+
// ... logic
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Passing Context
|
|
24
|
+
|
|
25
|
+
Context is King. Do not store context in structs. Pass it as the first parameter to every domain, service, and edge-implementation function. Dropping the context severs the distributed trace.
|
|
26
|
+
|
|
27
|
+
## 2. Error Handling
|
|
28
|
+
|
|
29
|
+
Use Go's `errors.Is` with sentinel errors to prevent database or HTTP leakage into domain logic.
|
|
30
|
+
|
|
31
|
+
### Defining Sentinels
|
|
32
|
+
|
|
33
|
+
Define business rule errors in `internal/core/domain/errors.go`:
|
|
34
|
+
|
|
35
|
+
```go
|
|
36
|
+
package domain
|
|
37
|
+
|
|
38
|
+
import "errors"
|
|
39
|
+
|
|
40
|
+
var ErrNotFound = errors.New("not found")
|
|
41
|
+
var ErrUnauthorized = errors.New("unauthorized access")
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Wrapping & Mapping Errors at the Edge
|
|
45
|
+
|
|
46
|
+
An edge implementation catching an infrastructure error wraps it into a Domain error before returning:
|
|
47
|
+
|
|
48
|
+
```go
|
|
49
|
+
// internal/postgres
|
|
50
|
+
func (r *Repository) Get(ctx context.Context, id string) (*domain.Entity, error) {
|
|
51
|
+
var entity domain.Entity
|
|
52
|
+
err := r.db.QueryRowContext(ctx, "SELECT ...").Scan(...)
|
|
53
|
+
|
|
54
|
+
if err != nil {
|
|
55
|
+
if errors.Is(err, sql.ErrNoRows) {
|
|
56
|
+
return nil, fmt.Errorf("lookup failed: %w", domain.ErrNotFound)
|
|
57
|
+
}
|
|
58
|
+
// %v, not %w: unexpected driver errors stay opaque at the storage
|
|
59
|
+
// boundary so callers cannot couple to infrastructure internals.
|
|
60
|
+
return nil, fmt.Errorf("unexpected db error: %v", err)
|
|
61
|
+
}
|
|
62
|
+
return &entity, nil
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## 3. Dependency Injection
|
|
67
|
+
|
|
68
|
+
### The Interface (Declared by the Core)
|
|
69
|
+
|
|
70
|
+
The interface belongs in `internal/core/service` (package `service`), declared at the point of use and speaking Domain language:
|
|
71
|
+
|
|
72
|
+
```go
|
|
73
|
+
package service
|
|
74
|
+
|
|
75
|
+
import "myservice/internal/core/domain"
|
|
76
|
+
|
|
77
|
+
type EntityStore interface {
|
|
78
|
+
Get(ctx context.Context, id string) (*domain.Entity, error)
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### The Wiring (Composition Root)
|
|
83
|
+
|
|
84
|
+
Constructor injection assembles pieces at startup without globals:
|
|
85
|
+
|
|
86
|
+
```go
|
|
87
|
+
// 1. Initialize the concrete edge implementation
|
|
88
|
+
store := postgres.NewRepository(sqlDB)
|
|
89
|
+
|
|
90
|
+
// 2. Inject into the Service (which only knows the service.EntityStore interface)
|
|
91
|
+
entityService := service.NewEntityService(store)
|
|
92
|
+
|
|
93
|
+
// 3. Inject the Service into the inbound HTTP route
|
|
94
|
+
entrypoints.RegisterEntityRoutes(router, entityService)
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## 4. Accept Interfaces, Return Structs
|
|
98
|
+
|
|
99
|
+
This idiom is how the inward-dependency rule is written in Go. The core service declares the interface; it accepts that interface; the edge implementation returns a concrete struct that satisfies it.
|
|
100
|
+
|
|
101
|
+
```go
|
|
102
|
+
// 1. The interface lives in the core, with the code that calls it
|
|
103
|
+
package service
|
|
104
|
+
|
|
105
|
+
type Store interface {
|
|
106
|
+
Get(ctx context.Context, id string) (*domain.Entity, error)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// 2. The Service accepts the interface
|
|
110
|
+
func NewService(store Store) *Service {
|
|
111
|
+
return &Service{store: store}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// 3. The edge implementation returns the concrete struct
|
|
115
|
+
package postgres
|
|
116
|
+
|
|
117
|
+
type Repository struct { /* ... */ }
|
|
118
|
+
|
|
119
|
+
func NewRepository(db *sql.DB) *Repository {
|
|
120
|
+
return &Repository{db: db}
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## 5. Goroutines and Context Loss
|
|
125
|
+
|
|
126
|
+
When spawning background tasks, use `context.WithoutCancel` (Go 1.21+) or extract/inject the trace so the background span remains a child of the request trace — even if the HTTP client disconnects early.
|
|
127
|
+
|
|
128
|
+
```go
|
|
129
|
+
func (s *Service) ProcessAsync(ctx context.Context) {
|
|
130
|
+
bgCtx := context.WithoutCancel(ctx)
|
|
131
|
+
|
|
132
|
+
go func() {
|
|
133
|
+
_, span := s.tracer.Start(bgCtx, "ProcessAsync.Background")
|
|
134
|
+
defer span.End()
|
|
135
|
+
// Execute asynchronous domain work...
|
|
136
|
+
}()
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## 6. Immutability in the Domain
|
|
141
|
+
|
|
142
|
+
When creating methods on Domain entities that calculate or evaluate state rather than modifying it, enforce immutability by exclusively using value receivers:
|
|
143
|
+
|
|
144
|
+
```go
|
|
145
|
+
package domain
|
|
146
|
+
|
|
147
|
+
type Order struct {
|
|
148
|
+
DurationSeconds int
|
|
149
|
+
Status string
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// CalculateCost uses a value receiver — cannot mutate the Order.
|
|
153
|
+
func (o Order) CalculateCost(rate float64) float64 {
|
|
154
|
+
return float64(o.DurationSeconds) * rate
|
|
155
|
+
}
|
|
156
|
+
```
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Integration Patterns
|
|
2
|
+
|
|
3
|
+
## Principles
|
|
4
|
+
|
|
5
|
+
1. **Default to async; upgrade to sync when required.** Sync only for inline response values or strict writes.
|
|
6
|
+
2. **Outbox pattern for DB write + event agreement.** Write event to `outbox` table in same transaction; worker relays to broker.
|
|
7
|
+
3. **Every consumer is idempotent.** De-duplication key or idempotent operations (UPSERT, conditional update).
|
|
8
|
+
4. **Retries have policies.** Explicit maximum, backoff curve, dead-letter destination.
|
|
9
|
+
5. **Webhooks verify, sign, and replay.** HMAC signature over payload. Both sides support replay.
|
|
10
|
+
6. **Timeouts are end-to-end budgets.** Allocated from the outermost caller's budget.
|
|
11
|
+
7. **Circuit breakers protect the system.** Open after threshold, fast-fail, probe periodically.
|
|
12
|
+
8. **Every integration has a contract test.** Real signature verification, retry curve, idempotency in CI.
|
|
13
|
+
|
|
14
|
+
## Anti-Patterns
|
|
15
|
+
|
|
16
|
+
- Sync chains three deep. Fire-and-forget webhooks. Commit-and-then-publish.
|
|
17
|
+
- Global retry policies. Dead-letter queues as logs.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
# Real-Time Architecture
|
|
22
|
+
|
|
23
|
+
## Principles
|
|
24
|
+
|
|
25
|
+
1. **WebSocket is the default transport.** SSE for one-way server-to-client only. No long-polling.
|
|
26
|
+
2. **Every message carries a sequence number.** Monotonic, per-session. Detect gaps, duplicates, resync.
|
|
27
|
+
3. **Reconnection is the normal case.** Exponential backoff, jitter, resumption token.
|
|
28
|
+
4. **Backpressure is explicit.** Shed, coalesce, or block. Never buffer unbounded.
|
|
29
|
+
5. **Echo suppression is a design concern.** Specified before the first line of code.
|
|
30
|
+
6. **Idempotent handlers.** Same sequence number processed twice has no additional effect.
|
|
31
|
+
7. **Observability is unbroken across the socket.** OTel trace context propagates into the socket.
|
|
32
|
+
8. **Client state is recoverable, not sacred.** Server is the source of truth.
|
|
33
|
+
|
|
34
|
+
## Anti-Patterns
|
|
35
|
+
|
|
36
|
+
- Socket as fire-and-forget bus. Per-connection unbounded buffers. Reconnect-then-refetch-everything.
|
|
37
|
+
- Ad-hoc event schemas. Client-side echo reconciliation.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
# Data Engineering
|
|
42
|
+
|
|
43
|
+
## Principles
|
|
44
|
+
|
|
45
|
+
1. **Events are append-only and immutable.** Correction via compensating events.
|
|
46
|
+
2. **Schemas are versioned and evolvable.** Additive new fields; deprecated fields have a deadline.
|
|
47
|
+
3. **Partition keys are chosen deliberately.** Ordering guarantee per partition.
|
|
48
|
+
4. **CQRS where it pays.** Separate read model for complex projections.
|
|
49
|
+
5. **Event sourcing is a tool, not a religion.** Only where change history is the product.
|
|
50
|
+
6. **Data contracts are documented, versioned, and owned.**
|
|
51
|
+
7. **Retention is a design decision.** Decided at creation, enforced by automation.
|
|
52
|
+
8. **Backfills are planned operations.** Rehearsed in staging, measured in production.
|
|
53
|
+
|
|
54
|
+
## Anti-Patterns
|
|
55
|
+
|
|
56
|
+
- Silent schema changes. Mutable event logs. Kitchen-sink events table.
|
|
57
|
+
- Backfills without rehearsal. Retention by accident.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Observability
|
|
2
|
+
|
|
3
|
+
## Core Principles
|
|
4
|
+
|
|
5
|
+
### 1. OpenTelemetry Is the Common Language
|
|
6
|
+
|
|
7
|
+
Every service emits traces, metrics, and logs through OpenTelemetry SDKs to a single collector. Vendor lock-in at the collector boundary, not inside application code.
|
|
8
|
+
|
|
9
|
+
### 2. Traces Are the Primary Signal
|
|
10
|
+
|
|
11
|
+
Given a choice between adding a metric or enriching a trace, enrich the trace. Traces preserve causality; metrics aggregate it away.
|
|
12
|
+
|
|
13
|
+
### 3. The Three Pillars Are One Pillar
|
|
14
|
+
|
|
15
|
+
Logs, metrics, and traces are different projections of the same events. A log line includes its trace ID; a metric includes dimensions to pivot back to traces; an exemplar on a metric points directly at the trace that produced it.
|
|
16
|
+
|
|
17
|
+
### 4. Dashboards Derive from SLOs
|
|
18
|
+
|
|
19
|
+
Every dashboard starts with the user-journey SLO it supports. Then latency percentiles, error rates, saturation, and traffic. Dashboards derived from SLOs stay useful; dashboards assembled by adding "interesting-looking" graphs drift.
|
|
20
|
+
|
|
21
|
+
### 5. Trace-Driven Development
|
|
22
|
+
|
|
23
|
+
Sketch the trace a new feature should produce *before* writing the handler. What spans must exist? What attributes? What parent-child relationships? The instrumentation design shapes the code.
|
|
24
|
+
|
|
25
|
+
### 6. Assert on Telemetry in Tests
|
|
26
|
+
|
|
27
|
+
System tests assert that traces are unbroken end-to-end — a missing span is a test failure. Instrumentation is part of the contract, not an optional decoration.
|
|
28
|
+
|
|
29
|
+
### 7. Logs Are Structured, Sampled, and Contextual
|
|
30
|
+
|
|
31
|
+
Every log line is structured (JSON), carries its trace ID, and is emitted at an agreed severity. Sample aggressively at debug and info; do not sample errors.
|
|
32
|
+
|
|
33
|
+
### 8. Cardinality Is a Design Choice
|
|
34
|
+
|
|
35
|
+
High-cardinality attributes (per-user, per-tenant) are valuable for debugging but expensive in storage. Tag deliberately — high cardinality on traces, lower cardinality on metrics.
|
|
36
|
+
|
|
37
|
+
## Implementation
|
|
38
|
+
|
|
39
|
+
- Use `slog` exclusively for structured logging. Always inject `trace_id` and `span_id` from the current context.
|
|
40
|
+
- Every HTTP endpoint and background job must initialize a Root Span.
|
|
41
|
+
- Adapter calls (SQL queries, Pub/Sub publishing) must extract and cascade the span.
|
|
42
|
+
|
|
43
|
+
## Anti-Patterns
|
|
44
|
+
|
|
45
|
+
- **Pillar-at-a-time adoption.** "We'll add metrics now, traces later." You will not.
|
|
46
|
+
- **Vendor SDKs in application code.** Application code imports OpenTelemetry; the collector talks to the vendor.
|
|
47
|
+
- **Dashboards without SLOs.** Pretty charts without a question they answer.
|
|
48
|
+
- **Logs-as-debugger.** Using `printf` style logging to trace a single bug. Write a test; add a span.
|
|
49
|
+
- **Cardinality explosions.** Putting a UUID in a Prometheus label.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Postgres
|
|
2
|
+
|
|
3
|
+
## Principles
|
|
4
|
+
|
|
5
|
+
1. **Schema design is a design document.** What it represents, identifies, invariants, queries, retention.
|
|
6
|
+
2. **Columns over JSONB for stable shape.** JSONB for varying shape or rarely queried metadata.
|
|
7
|
+
3. **Migrations are additive, reversible, online.** Nullable columns or cheap defaults. Never block on large rewrites.
|
|
8
|
+
4. **Indexes are evidence-based.** Justified by `pg_stat_user_indexes` and `pg_stat_statements`.
|
|
9
|
+
5. **`pgvector` is the vector store.** Operational simplicity over marginal dedicated-DB performance.
|
|
10
|
+
6. **Connection management is explicit.** Deliberate pool sizing, idle timeouts, statement timeouts.
|
|
11
|
+
7. **Query patterns are reviewed.** `EXPLAIN ANALYZE` in PRs for non-trivial queries.
|
|
12
|
+
8. **Backups and retention are not afterthoughts.** Test restores. Retention decided at table creation.
|
|
13
|
+
|
|
14
|
+
## Target-State Schema Workflow
|
|
15
|
+
|
|
16
|
+
1. `db/schema.sql` describes the desired final state.
|
|
17
|
+
2. Migrator compares live DB to target using `pg-schema-diff` or equivalent.
|
|
18
|
+
3. `dry-run` prints planned DDL and hazards.
|
|
19
|
+
4. `migrate` applies the plan.
|
|
20
|
+
|
|
21
|
+
### Safe Schema Changes
|
|
22
|
+
|
|
23
|
+
- Add nullable columns first, cheap defaults only when safe for table size.
|
|
24
|
+
- Add new tables empty. Add indexes for known access patterns.
|
|
25
|
+
- Avoid renames, drops, type rewrites in same release as consuming code.
|
|
26
|
+
- Multi-release: expand-contract sequencing.
|
|
27
|
+
|
|
28
|
+
## The persistence boundary
|
|
29
|
+
|
|
30
|
+
Take the clean break between the core and the store from a narrow, domain-named port plus real-DB tests — never from a generic repository. Idiomatically in Go:
|
|
31
|
+
|
|
32
|
+
- **Declare the interface where it is consumed, and keep it small.** The service that needs persistence declares an interface naming only the operations it calls (`type OrderStore interface { ByID(ctx, id) (*Order, error); Save(ctx, *Order) error }`), in the domain's language. The Postgres implementation (over `sqlc`/`pgx`) lives in its own package, returns concrete domain structs, and is wired in at the composition root. *"The bigger the interface, the weaker the abstraction"* — never expose the store's full CRUD surface.
|
|
33
|
+
- **No generic `Repository[T]`.** Per-entity queries, SQL, and row mapping differ, so persistence belongs to an interface, not a type parameter — Go's own guidance uses a type parameter only to *relate* multiple values, not when the implementation differs per type. A generic base used only by tests is speculative generality; delete it.
|
|
34
|
+
- **Right-size it.** A thin CRUD endpoint does not need a hand-written port over the query layer — reach for one when a rich aggregate with invariants must stay storage-ignorant, and then it is one port per aggregate root. When query variety grows, add a query/specification type, not more methods.
|
|
35
|
+
- Integration-test the adapter against a real Postgres (see `testing.md`); do not mock it.
|
|
36
|
+
|
|
37
|
+
## Anti-Patterns
|
|
38
|
+
|
|
39
|
+
- JSONB-everything. Indexes "just in case." Migrations that lock hot tables.
|
|
40
|
+
- Raw string interpolation. A second database without documented need.
|
|
41
|
+
- A generic `Repository[T]` over the query layer, or an exposed store-shaped CRUD surface — premature generality that leaks the schema into the core.
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Reliability
|
|
2
|
+
|
|
3
|
+
## Core Principles
|
|
4
|
+
|
|
5
|
+
### 1. SLOs, Not Uptime Percentages
|
|
6
|
+
|
|
7
|
+
Every significant service defines a Service Level Objective — a per-endpoint or per-user-journey target with latency and success-rate components, measured over a rolling window. "99.9% uptime" is not an SLO; "p95 `POST /entities` < 300ms over 30 days, 99.5% success" is.
|
|
8
|
+
|
|
9
|
+
### 2. Error Budgets Govern Velocity
|
|
10
|
+
|
|
11
|
+
The budget implied by the SLO is a spendable resource. Teams spending below budget ship riskier changes. Teams above budget pause feature work and pay down reliability debt.
|
|
12
|
+
|
|
13
|
+
### 3. Graceful Degradation Is a Design, Not a Hope
|
|
14
|
+
|
|
15
|
+
Every user-facing feature has a defined behaviour when its downstream fails. Degradation is decided at design time and implemented alongside the happy path.
|
|
16
|
+
|
|
17
|
+
### 4. Timeouts, Retries, and Circuit Breakers Are Defaults
|
|
18
|
+
|
|
19
|
+
Every outbound call has a timeout. Every retry has a bounded policy with jitter. Every client has a circuit breaker against its most important downstreams. Defaults are set in a shared library; opting out requires a written reason.
|
|
20
|
+
|
|
21
|
+
### 5. Isolate Blast Radius
|
|
22
|
+
|
|
23
|
+
A single tenant, user, or noisy consumer must not degrade the experience for everyone else. Isolate by quota (per-tenant rate limits), by resource (dedicated queues), and by bulkhead (separate worker pools).
|
|
24
|
+
|
|
25
|
+
### 6. Rehearse Failure
|
|
26
|
+
|
|
27
|
+
Inject failures routinely — killed pods, degraded networks, slow databases. Every chaos experiment that finds something surprising is worth a year of CI.
|
|
28
|
+
|
|
29
|
+
### 7. Alerts Fire on User Impact, Not Mechanism
|
|
30
|
+
|
|
31
|
+
Alert when users are affected — SLO burn rate, error-rate spikes on user journeys — not when a server has 80% CPU.
|
|
32
|
+
|
|
33
|
+
### 8. Every Incident Teaches a Specific Lesson
|
|
34
|
+
|
|
35
|
+
Post-incident: blameless postmortem, specific reliability assumption invalidated, specific change proposed. No "be more careful" action items.
|
|
36
|
+
|
|
37
|
+
## Anti-Patterns
|
|
38
|
+
|
|
39
|
+
- **"99.999% uptime" as a target.** Five-nines for a non-core service is reckless.
|
|
40
|
+
- **Retries without policies.** Retry-forever is a self-inflicted DDoS.
|
|
41
|
+
- **Mechanism alerts.** Paging on CPU without user-impact signal.
|
|
42
|
+
- **Postmortems that blame humans.** The action item is the system fix.
|
|
43
|
+
- **SLOs nobody tracks.** An SLO without a dashboard and burn-rate alert is theatre.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
# Performance
|
|
48
|
+
|
|
49
|
+
## Core Principles
|
|
50
|
+
|
|
51
|
+
### 1. Latency Is a Budget, Allocated Top-Down
|
|
52
|
+
|
|
53
|
+
Every user-facing operation starts with a latency budget at the edge. The budget is allocated to downstream hops. Budgeting makes trade-offs explicit.
|
|
54
|
+
|
|
55
|
+
### 2. Measure Tail Latency, Not Average
|
|
56
|
+
|
|
57
|
+
p50 is a marketing number. p95 and p99 are what users experience. Design for the tail.
|
|
58
|
+
|
|
59
|
+
### 3. Pre-Compute, Cache, and Denormalise Deliberately
|
|
60
|
+
|
|
61
|
+
Each trades complexity for latency. Each earns its keep with data, not intuition.
|
|
62
|
+
|
|
63
|
+
### 4. Backpressure Is Designed In
|
|
64
|
+
|
|
65
|
+
Every producer has a bounded queue and a defined behaviour when the queue fills: shed, coalesce, block.
|
|
66
|
+
|
|
67
|
+
### 5. Load Shedding Protects the System
|
|
68
|
+
|
|
69
|
+
When saturated, serve fewer requests well. Shed on clearly-defined criteria using inbound concurrency limits.
|
|
70
|
+
|
|
71
|
+
```go
|
|
72
|
+
import "golang.org/x/sync/semaphore"
|
|
73
|
+
|
|
74
|
+
var maxInflight = semaphore.NewWeighted(1000)
|
|
75
|
+
|
|
76
|
+
func LoadSheddingMiddleware(next http.Handler) http.Handler {
|
|
77
|
+
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
78
|
+
if !maxInflight.TryAcquire(1) {
|
|
79
|
+
http.Error(w, "Service Unavailable", http.StatusServiceUnavailable)
|
|
80
|
+
return
|
|
81
|
+
}
|
|
82
|
+
defer maxInflight.Release(1)
|
|
83
|
+
next.ServeHTTP(w, r)
|
|
84
|
+
})
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 6. Hot Paths Have No Allocations to Spare
|
|
89
|
+
|
|
90
|
+
For the hottest inner loops, write allocation-aware code. Every allocation is a GC pause in waiting.
|
|
91
|
+
|
|
92
|
+
### 7. Profile Before You Optimise
|
|
93
|
+
|
|
94
|
+
Every non-trivial optimisation starts with a profile. The "obvious" bottleneck is almost always wrong.
|
|
95
|
+
|
|
96
|
+
### 8. Budgets Are Enforced in CI
|
|
97
|
+
|
|
98
|
+
Bundle sizes, handler latencies — measured in CI against committed thresholds. Regressions require a reviewed waiver.
|
|
99
|
+
|
|
100
|
+
## Anti-Patterns
|
|
101
|
+
|
|
102
|
+
- **Optimising on hunch.** No profile, no optimisation.
|
|
103
|
+
- **Average-as-metric.** p50 is a lie. Use percentiles.
|
|
104
|
+
- **Unbounded queues.** A queue without a max is a latency bomb.
|
|
105
|
+
- **"We will fix performance later."** If you ship slow, users remember slow.
|