aw-spec-cli 0.1.7 → 0.1.9

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 (261) hide show
  1. package/assets/.appweaver/DESIGN-FORMAT.md +200 -0
  2. package/assets/.appweaver/ORCH-DIALECT.md +156 -0
  3. package/assets/.appweaver/RULE-PARTITION.md +175 -0
  4. package/assets/.appweaver/STACK-PROFILES.md +461 -0
  5. package/assets/.appweaver/ai-rules.md +180 -0
  6. package/assets/.appweaver/domain.json +1 -0
  7. package/assets/.appweaver/extensions/.registry +19 -0
  8. package/assets/.appweaver/extensions/agent-context/README.md +57 -0
  9. package/assets/.appweaver/extensions/agent-context/agent-context-config.yml +4 -0
  10. package/assets/.appweaver/extensions/agent-context/commands/aw-spec.agent-context.update.md +26 -0
  11. package/assets/.appweaver/extensions/agent-context/extension.yml +37 -0
  12. package/assets/.appweaver/extensions/agent-context/scripts/bash/update-agent-context.sh +201 -0
  13. package/assets/.appweaver/extensions/agent-context/scripts/powershell/update-agent-context.ps1 +237 -0
  14. package/assets/.appweaver/extensions.yml +16 -0
  15. package/assets/.appweaver/feature.json +3 -0
  16. package/assets/.appweaver/init-options.json +9 -0
  17. package/assets/.appweaver/integration.json +15 -0
  18. package/assets/.appweaver/integrations/aw-spec.manifest.json +9 -0
  19. package/assets/.appweaver/interpreter/run-skill.py +1176 -0
  20. package/assets/.appweaver/memory/constitution.md +50 -0
  21. package/assets/.appweaver/orchestrator/.smoke-out/smoke.md +6 -0
  22. package/assets/.appweaver/orchestrator/AGENT-PROFILE.md +94 -0
  23. package/assets/.appweaver/orchestrator/README.md +300 -0
  24. package/assets/.appweaver/orchestrator/adapters/claude_agent_sdk.py +74 -0
  25. package/assets/.appweaver/orchestrator/adapters/google_antigravity.py +74 -0
  26. package/assets/.appweaver/orchestrator/modules/delta-design.orch.yaml +105 -0
  27. package/assets/.appweaver/orchestrator/modules/delta-spec.orch.yaml +101 -0
  28. package/assets/.appweaver/orchestrator/modules/domain-select.orch.yaml +90 -0
  29. package/assets/.appweaver/orchestrator/modules/lane-gate.orch.yaml +126 -0
  30. package/assets/.appweaver/orchestrator/modules/tech-select.orch.yaml +123 -0
  31. package/assets/.appweaver/orchestrator/orchestrator.py +1721 -0
  32. package/assets/.appweaver/orchestrator/rev-templates/ai-rules.reference.md +40 -0
  33. package/assets/.appweaver/orchestrator/rev-templates/delta-design-template.skeleton.md +101 -0
  34. package/assets/.appweaver/orchestrator/rev-templates/design-template.skeleton.md +245 -0
  35. package/assets/.appweaver/orchestrator/rev-templates/domain-constitution.skeleton.md +63 -0
  36. package/assets/.appweaver/orchestrator/rev-templates/domain-requirements.skeleton.md +48 -0
  37. package/assets/.appweaver/orchestrator/rev-templates/domain-rule-bindings.skeleton.md +59 -0
  38. package/assets/.appweaver/orchestrator/rev-templates/domain-rule-file.skeleton.md +39 -0
  39. package/assets/.appweaver/orchestrator/rev-templates/frontend-rule-file.skeleton.md +63 -0
  40. package/assets/.appweaver/orchestrator/rev-templates/tech-rule-bindings.skeleton.md +116 -0
  41. package/assets/.appweaver/orchestrator/rev-templates/technical-constitution.skeleton.md +106 -0
  42. package/assets/.appweaver/orchestrator/rev-templates/technical-rule-file.skeleton.md +54 -0
  43. package/assets/.appweaver/orchestrator/rev-templates/ui-constitution.skeleton.md +125 -0
  44. package/assets/.appweaver/orchestrator/rev-templates/ui-delta-design-template.skeleton.md +123 -0
  45. package/assets/.appweaver/orchestrator/rev-templates/ui-design-template.skeleton.md +294 -0
  46. package/assets/.appweaver/orchestrator/workflows/_smoke.orch.yaml +160 -0
  47. package/assets/.appweaver/orchestrator/workflows/aw-spec-add-component.orch.yaml +270 -0
  48. package/assets/.appweaver/orchestrator/workflows/aw-spec-adopt.orch.yaml +934 -0
  49. package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-delta-design.orch.yaml +251 -0
  50. package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-design.orch.yaml +265 -0
  51. package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-slice.orch.yaml +437 -0
  52. package/assets/.appweaver/orchestrator/workflows/aw-spec-build.orch.yaml +197 -0
  53. package/assets/.appweaver/orchestrator/workflows/aw-spec-characterize.orch.yaml +475 -0
  54. package/assets/.appweaver/orchestrator/workflows/aw-spec-close-delta.orch.yaml +181 -0
  55. package/assets/.appweaver/orchestrator/workflows/aw-spec-constitution.orch.yaml +727 -0
  56. package/assets/.appweaver/orchestrator/workflows/aw-spec-demo.orch.yaml +100 -0
  57. package/assets/.appweaver/orchestrator/workflows/aw-spec-dependency-tree.orch.yaml +69 -0
  58. package/assets/.appweaver/orchestrator/workflows/aw-spec-deploy.orch.yaml +85 -0
  59. package/assets/.appweaver/orchestrator/workflows/aw-spec-design-ui.orch.yaml +386 -0
  60. package/assets/.appweaver/orchestrator/workflows/aw-spec-design.orch.yaml +382 -0
  61. package/assets/.appweaver/orchestrator/workflows/aw-spec-finalize-delta.orch.yaml +462 -0
  62. package/assets/.appweaver/orchestrator/workflows/aw-spec-foundation.orch.yaml +265 -0
  63. package/assets/.appweaver/orchestrator/workflows/aw-spec-implement-delta.orch.yaml +253 -0
  64. package/assets/.appweaver/orchestrator/workflows/aw-spec-implement-ui.orch.yaml +267 -0
  65. package/assets/.appweaver/orchestrator/workflows/aw-spec-implement.orch.yaml +287 -0
  66. package/assets/.appweaver/orchestrator/workflows/aw-spec-inventory.orch.yaml +238 -0
  67. package/assets/.appweaver/orchestrator/workflows/aw-spec-onboard.orch.yaml +1822 -0
  68. package/assets/.appweaver/orchestrator/workflows/aw-spec-parity.orch.yaml +293 -0
  69. package/assets/.appweaver/orchestrator/workflows/aw-spec-run.orch.yaml +194 -0
  70. package/assets/.appweaver/orchestrator/workflows/aw-spec-select-domain.orch.yaml +83 -0
  71. package/assets/.appweaver/orchestrator/workflows/aw-spec-select-feature.orch.yaml +128 -0
  72. package/assets/.appweaver/orchestrator/workflows/aw-spec-select-stack.orch.yaml +296 -0
  73. package/assets/.appweaver/orchestrator/workflows/aw-spec-specify.orch.yaml +439 -0
  74. package/assets/.appweaver/scripts/bash/aw-inventory.sh +17 -0
  75. package/assets/.appweaver/scripts/bash/aw-parity.sh +13 -0
  76. package/assets/.appweaver/scripts/bash/aw-rev-constitution.sh +13 -0
  77. package/assets/.appweaver/scripts/bash/aw-spec-actions.sh +2626 -0
  78. package/assets/.appweaver/scripts/bash/aw-xref.sh +15 -0
  79. package/assets/.appweaver/scripts/bash/common.sh +533 -0
  80. package/assets/.appweaver/scripts/powershell/aw-inventory.ps1 +17 -0
  81. package/assets/.appweaver/scripts/powershell/aw-parity.ps1 +13 -0
  82. package/assets/.appweaver/scripts/powershell/aw-rev-constitution.ps1 +13 -0
  83. package/assets/.appweaver/scripts/powershell/aw-spec-actions.ps1 +2232 -0
  84. package/assets/.appweaver/scripts/powershell/aw-xref.ps1 +15 -0
  85. package/assets/.appweaver/scripts/python/aw-component-catalog.py +121 -0
  86. package/assets/.appweaver/scripts/python/aw-inventory.py +1180 -0
  87. package/assets/.appweaver/scripts/python/aw-parity.py +380 -0
  88. package/assets/.appweaver/scripts/python/aw-rev-constitution.py +329 -0
  89. package/assets/.appweaver/scripts/python/aw-stack.py +1251 -0
  90. package/assets/.appweaver/scripts/python/aw-xref.py +1330 -0
  91. package/assets/.appweaver/scripts/python/validate_okf.py +352 -0
  92. package/assets/.appweaver/stack-profiles/angular.json +16 -0
  93. package/assets/.appweaver/stack-profiles/blazor-wasm.json +17 -0
  94. package/assets/.appweaver/stack-profiles/dotnet-webapi.json +15 -0
  95. package/assets/.appweaver/stack-profiles/go-chi.json +14 -0
  96. package/assets/.appweaver/stack-profiles/java-spring.json +16 -0
  97. package/assets/.appweaver/stack-profiles/nextjs.json +16 -0
  98. package/assets/.appweaver/stack-profiles/node-express.json +15 -0
  99. package/assets/.appweaver/stack-profiles/python-fastapi.json +16 -0
  100. package/assets/.appweaver/stack-profiles/react-vite.json +17 -0
  101. package/assets/.appweaver/stack-profiles/sveltekit.json +16 -0
  102. package/assets/.appweaver/stack-profiles/vue-vite.json +17 -0
  103. package/assets/.appweaver/stacks.json +3 -0
  104. package/assets/.appweaver/templates/constitution-domain-template.md +116 -0
  105. package/assets/.appweaver/templates/constitution-technical-template.md +108 -0
  106. package/assets/.appweaver/templates/constitution-ui-template.md +116 -0
  107. package/assets/.appweaver/templates/delta-design-template.md +69 -0
  108. package/assets/.appweaver/templates/delta-spec-template.md +63 -0
  109. package/assets/.appweaver/templates/design-template.md +383 -0
  110. package/assets/.appweaver/templates/okf-concept-template.md +114 -0
  111. package/assets/.appweaver/templates/parity-manifest-template.json +49 -0
  112. package/assets/.appweaver/templates/source-map-template.md +85 -0
  113. package/assets/.appweaver/templates/spec-template.md +309 -0
  114. package/assets/.appweaver/templates/ui-design-template.md +273 -0
  115. package/assets/foundations/dotnet/ModularMonolith/ModularMonolith.Reference.pack.txt +25248 -0
  116. package/assets/foundations/dotnet/ModularMonolith/ModularMonolith.pack.txt +5726 -0
  117. package/assets/foundations/dotnet/ModularMonolith/pack-foundation.ps1 +145 -0
  118. package/assets/foundations/dotnet/ModularMonolith/pack-foundation.sh +196 -0
  119. package/assets/foundations/dotnet/ModularMonolith/pack-reference-foundation.ps1 +157 -0
  120. package/assets/foundations/dotnet/ModularMonolith/pack-reference-foundation.sh +209 -0
  121. package/assets/foundations/dotnet/ModularMonolith/unpack-foundation.ps1 +126 -0
  122. package/assets/foundations/dotnet/ModularMonolith/unpack-foundation.sh +217 -0
  123. package/assets/foundations/dotnet/ModularMonolith/unpack-reference-foundation.ps1 +129 -0
  124. package/assets/foundations/dotnet/ModularMonolith/unpack-reference-foundation.sh +218 -0
  125. package/assets/foundations/dotnet/VerticalSlice/VerticalSlice.Reference.pack.txt +19318 -0
  126. package/assets/foundations/dotnet/VerticalSlice/VerticalSlice.pack.txt +2833 -0
  127. package/assets/foundations/dotnet/VerticalSlice/pack-foundation.ps1 +145 -0
  128. package/assets/foundations/dotnet/VerticalSlice/pack-foundation.sh +196 -0
  129. package/assets/foundations/dotnet/VerticalSlice/pack-reference-foundation.ps1 +157 -0
  130. package/assets/foundations/dotnet/VerticalSlice/pack-reference-foundation.sh +209 -0
  131. package/assets/foundations/dotnet/VerticalSlice/unpack-foundation.ps1 +126 -0
  132. package/assets/foundations/dotnet/VerticalSlice/unpack-foundation.sh +217 -0
  133. package/assets/foundations/dotnet/VerticalSlice/unpack-reference-foundation.ps1 +129 -0
  134. package/assets/foundations/dotnet/VerticalSlice/unpack-reference-foundation.sh +218 -0
  135. package/assets/foundations/dotnet/components/Email/README.md +119 -0
  136. package/assets/foundations/dotnet/components/Email/ReferenceEndpoints/SendEmailEndpoint.cs +84 -0
  137. package/assets/foundations/dotnet/components/Email/integration.md +300 -0
  138. package/assets/foundations/dotnet/components/Jobs/README.md +113 -0
  139. package/assets/foundations/dotnet/components/Jobs/integration.md +259 -0
  140. package/assets/foundations/dotnet/components/QrGenerator/README.md +85 -0
  141. package/assets/foundations/dotnet/components/QrGenerator/ReferenceEndpoints/GenerateQrEndpoint.cs +57 -0
  142. package/assets/foundations/dotnet/components/QrGenerator/integration.md +230 -0
  143. package/assets/foundations/dotnet/components/README.md +74 -0
  144. package/assets/guardrails/README.md +222 -0
  145. package/assets/guardrails/domain/healthcare/ai-rules.domain.md +34 -0
  146. package/assets/guardrails/domain/healthcare/api-versioning.domain.md +17 -0
  147. package/assets/guardrails/domain/healthcare/auditing.domain.md +97 -0
  148. package/assets/guardrails/domain/healthcare/authorization.domain.md +26 -0
  149. package/assets/guardrails/domain/healthcare/clinical-terms.md +20 -0
  150. package/assets/guardrails/domain/healthcare/coding-standards.domain.md +26 -0
  151. package/assets/guardrails/domain/healthcare/consent.md +19 -0
  152. package/assets/guardrails/domain/healthcare/cqrs.domain.md +12 -0
  153. package/assets/guardrails/domain/healthcare/data-classification.domain.md +28 -0
  154. package/assets/guardrails/domain/healthcare/dependency-policy.domain.md +11 -0
  155. package/assets/guardrails/domain/healthcare/dicom.md +15 -0
  156. package/assets/guardrails/domain/healthcare/domain-constitution.md +119 -0
  157. package/assets/guardrails/domain/healthcare/domain-driven-design.domain.md +28 -0
  158. package/assets/guardrails/domain/healthcare/eventing.domain.md +18 -0
  159. package/assets/guardrails/domain/healthcare/fhir.md +36 -0
  160. package/assets/guardrails/domain/healthcare/folder-structure.domain.md +25 -0
  161. package/assets/guardrails/domain/healthcare/hipaa.md +34 -0
  162. package/assets/guardrails/domain/healthcare/hl7.md +15 -0
  163. package/assets/guardrails/domain/healthcare/ihe-conformance.md +31 -0
  164. package/assets/guardrails/domain/healthcare/integration-terms.md +21 -0
  165. package/assets/guardrails/domain/healthcare/persistence.domain.md +20 -0
  166. package/assets/guardrails/domain/healthcare/terminology.md +30 -0
  167. package/assets/guardrails/domain/healthcare/testing.domain.md +15 -0
  168. package/assets/guardrails/domain/healthcare/ux/accessibility-standards.md +36 -0
  169. package/assets/guardrails/domain/healthcare/ux/content-design.md +32 -0
  170. package/assets/guardrails/domain/healthcare/ux/interaction-states.md +44 -0
  171. package/assets/guardrails/domain/healthcare/ux/journey-mapping.md +40 -0
  172. package/assets/guardrails/domain/healthcare/vertical-slices.domain.md +18 -0
  173. package/assets/guardrails/domain/healthcare/zero-trust.domain.md +12 -0
  174. package/assets/guardrails/domain/pharma/ai-rules.domain.md +32 -0
  175. package/assets/guardrails/domain/pharma/api-versioning.domain.md +20 -0
  176. package/assets/guardrails/domain/pharma/atc.md +22 -0
  177. package/assets/guardrails/domain/pharma/auditing.domain.md +90 -0
  178. package/assets/guardrails/domain/pharma/authorization.domain.md +25 -0
  179. package/assets/guardrails/domain/pharma/coding-standards.domain.md +28 -0
  180. package/assets/guardrails/domain/pharma/cqrs.domain.md +16 -0
  181. package/assets/guardrails/domain/pharma/data-classification.domain.md +24 -0
  182. package/assets/guardrails/domain/pharma/data-provenance.md +21 -0
  183. package/assets/guardrails/domain/pharma/dependency-policy.domain.md +11 -0
  184. package/assets/guardrails/domain/pharma/domain-constitution.md +113 -0
  185. package/assets/guardrails/domain/pharma/domain-driven-design.domain.md +36 -0
  186. package/assets/guardrails/domain/pharma/domain-requirements.sample.md +103 -0
  187. package/assets/guardrails/domain/pharma/eventing.domain.md +18 -0
  188. package/assets/guardrails/domain/pharma/fhir.md +31 -0
  189. package/assets/guardrails/domain/pharma/folder-structure.domain.md +26 -0
  190. package/assets/guardrails/domain/pharma/hl7.md +17 -0
  191. package/assets/guardrails/domain/pharma/idmp.md +26 -0
  192. package/assets/guardrails/domain/pharma/integration-terms.md +21 -0
  193. package/assets/guardrails/domain/pharma/ndc.md +28 -0
  194. package/assets/guardrails/domain/pharma/persistence.domain.md +23 -0
  195. package/assets/guardrails/domain/pharma/pharma-terms.md +27 -0
  196. package/assets/guardrails/domain/pharma/product-lifecycle.domain.md +30 -0
  197. package/assets/guardrails/domain/pharma/regulatory-compliance.md +19 -0
  198. package/assets/guardrails/domain/pharma/terminology.md +32 -0
  199. package/assets/guardrails/domain/pharma/testing.domain.md +19 -0
  200. package/assets/guardrails/domain/pharma/vertical-slices.domain.md +17 -0
  201. package/assets/guardrails/domain/pharma/zero-trust.domain.md +12 -0
  202. package/assets/guardrails/projects/dotnet-default-project/domain/domain-requirements.md +58 -0
  203. package/assets/guardrails/projects/dotnet-default-project/domain-rule-bindings.md +113 -0
  204. package/assets/guardrails/projects/dotnet-default-project/frontend/ui-requirements.md +43 -0
  205. package/assets/guardrails/projects/dotnet-default-project/service/technical-requirements.md +40 -0
  206. package/assets/guardrails/projects/dotnet-default-project/tech-rule-bindings.md +263 -0
  207. package/assets/guardrails/requirement-spec.txt +27 -0
  208. package/assets/guardrails/technology/dotnet-webapi/PACKAGING.md +184 -0
  209. package/assets/guardrails/technology/dotnet-webapi/api-versioning.md +44 -0
  210. package/assets/guardrails/technology/dotnet-webapi/auditing.md +96 -0
  211. package/assets/guardrails/technology/dotnet-webapi/authorization-matrix.md +14 -0
  212. package/assets/guardrails/technology/dotnet-webapi/authorization.md +39 -0
  213. package/assets/guardrails/technology/dotnet-webapi/clean-architecture.md +54 -0
  214. package/assets/guardrails/technology/dotnet-webapi/coding-standards.md +87 -0
  215. package/assets/guardrails/technology/dotnet-webapi/cqrs.md +63 -0
  216. package/assets/guardrails/technology/dotnet-webapi/data-classification.md +38 -0
  217. package/assets/guardrails/technology/dotnet-webapi/dependency-policy.md +40 -0
  218. package/assets/guardrails/technology/dotnet-webapi/domain-driven-design.md +91 -0
  219. package/assets/guardrails/technology/dotnet-webapi/eventing.md +57 -0
  220. package/assets/guardrails/technology/dotnet-webapi/examples/api-versioning.md +75 -0
  221. package/assets/guardrails/technology/dotnet-webapi/examples/auditing.md +84 -0
  222. package/assets/guardrails/technology/dotnet-webapi/examples/authorization.md +68 -0
  223. package/assets/guardrails/technology/dotnet-webapi/examples/clean-architecture.md +37 -0
  224. package/assets/guardrails/technology/dotnet-webapi/examples/cqrs.md +97 -0
  225. package/assets/guardrails/technology/dotnet-webapi/examples/domain-driven-design.md +141 -0
  226. package/assets/guardrails/technology/dotnet-webapi/examples/eventing.md +46 -0
  227. package/assets/guardrails/technology/dotnet-webapi/examples/persistence.md +207 -0
  228. package/assets/guardrails/technology/dotnet-webapi/examples/vertical-slices.md +151 -0
  229. package/assets/guardrails/technology/dotnet-webapi/examples/zero-trust.md +48 -0
  230. package/assets/guardrails/technology/dotnet-webapi/folder-structure.md +61 -0
  231. package/assets/guardrails/technology/dotnet-webapi/modular-monolith.md +47 -0
  232. package/assets/guardrails/technology/dotnet-webapi/persistence.md +82 -0
  233. package/assets/guardrails/technology/dotnet-webapi/technology-constitution.md +162 -0
  234. package/assets/guardrails/technology/dotnet-webapi/testing.md +55 -0
  235. package/assets/guardrails/technology/dotnet-webapi/vertical-slices.md +70 -0
  236. package/assets/guardrails/technology/dotnet-webapi/zero-trust.md +48 -0
  237. package/assets/guardrails/technology/java-spring/README.md +62 -0
  238. package/assets/guardrails/technology/nextjs/accessibility-implementation.md +56 -0
  239. package/assets/guardrails/technology/nextjs/api-client.md +56 -0
  240. package/assets/guardrails/technology/nextjs/api-integration.dotnet-webapi.md +174 -0
  241. package/assets/guardrails/technology/nextjs/api-integration.java-spring.md +203 -0
  242. package/assets/guardrails/technology/nextjs/auth-session.md +68 -0
  243. package/assets/guardrails/technology/nextjs/client-security.md +69 -0
  244. package/assets/guardrails/technology/nextjs/component-architecture.md +60 -0
  245. package/assets/guardrails/technology/nextjs/component-conventions.md +58 -0
  246. package/assets/guardrails/technology/nextjs/design-system.md +60 -0
  247. package/assets/guardrails/technology/nextjs/error-handling.md +72 -0
  248. package/assets/guardrails/technology/nextjs/forms-and-validation.md +75 -0
  249. package/assets/guardrails/technology/nextjs/frontend-testing.md +94 -0
  250. package/assets/guardrails/technology/nextjs/i18n.md +57 -0
  251. package/assets/guardrails/technology/nextjs/observability.md +67 -0
  252. package/assets/guardrails/technology/nextjs/performance-budgets.md +66 -0
  253. package/assets/guardrails/technology/nextjs/routing-navigation.md +52 -0
  254. package/assets/guardrails/technology/nextjs/state-management.md +70 -0
  255. package/assets/guardrails/technology/nextjs/ui-constitution.md +166 -0
  256. package/dist/commands/init.js +2 -2
  257. package/dist/commands/init.js.map +1 -1
  258. package/dist/utils/copy-assets.js +8 -8
  259. package/dist/utils/copy-assets.js.map +1 -1
  260. package/package.json +1 -1
  261. package/assets/docs/pharma-constitution.my-ref.md +0 -86
@@ -0,0 +1,151 @@
1
+ # Vertical Slice Standards — canonical example
2
+
3
+ > The worked `<SampleProjectName>` example for
4
+ > `guardrails/technology/dotnet-webapi/vertical-slices.md`. It is reference material for the
5
+ > phases that generate code — mapped for `design` — and carries no rule of its own: where this
6
+ > example and the rule file disagree, the rule file wins.
7
+ >
8
+ > It is deliberately absent from the `## /aw-spec-constitution` set. The constitution is a
9
+ > thin authority document — one declarative line and a `→` pointer per principle — and has no
10
+ > use for sample code.
11
+
12
+ ## Canonical example (agent reference — `<SampleProjectName>` sample)
13
+
14
+ A complete slice: Endpoint (+ request class in the same file), Validator, DTO, and mapping.
15
+
16
+ ```csharp
17
+ // <SampleProjectName>.Service/Projects/Features/CreateProject/CreateProjectEndpoint.cs
18
+ public class CreateProjectEndpoint(IMediator _mediator)
19
+ : SecureFastEndpoint<CreateProjectRequest, ProjectDto>
20
+ {
21
+ public override void Configure()
22
+ {
23
+ Post("/projects"); // kebab-case, plural noun
24
+ Summary(s => s.Summary = "Create a new project");
25
+ Options(o => o.WithTags("02 - Project - (FastEndpoints)"));
26
+ }
27
+
28
+ protected override SecurityCachePolicy GetSecurityCachePolicy() => new()
29
+ {
30
+ SecurityLevel = SecurityLevel.Internal,
31
+ CachePolicy = CachePolicy.NoStore // mutating endpoint
32
+ };
33
+
34
+ protected override async Task<Result<ProjectDto>> ExecuteAsync(
35
+ CreateProjectRequest req, CancellationToken ct)
36
+ {
37
+ var result = await _mediator.Send(new CreateProjectCommand( // IMediator only
38
+ req.Code, req.Name, req.Description, req.StartDate, req.EndDate, req.OwnerId), ct);
39
+
40
+ if (result.IsSuccess && !string.IsNullOrWhiteSpace(result.Value?.RowVersionBase64))
41
+ HttpContext.Response.SetETagFromBase64(result.Value!.RowVersionBase64);
42
+ return result;
43
+ }
44
+ }
45
+
46
+ // Request lives in the SAME file — primitive types only
47
+ public class CreateProjectRequest
48
+ {
49
+ public string Code { get; set; } = string.Empty;
50
+ public string Name { get; set; } = string.Empty;
51
+ public string? Description { get; set; }
52
+ public DateOnly StartDate { get; set; }
53
+ public DateOnly? EndDate { get; set; }
54
+ public Guid? OwnerId { get; set; }
55
+ }
56
+ ```
57
+
58
+ ```csharp
59
+ // .../CreateProject/CreateProjectValidator.cs — request shape only
60
+ public class CreateProjectValidator : AbstractValidator<CreateProjectCommand>
61
+ {
62
+ public CreateProjectValidator()
63
+ {
64
+ RuleFor(x => x.Code).NotEmpty().MaximumLength(20).Matches(@"^[A-Z0-9\-]+$");
65
+ RuleFor(x => x.Name).NotEmpty().MaximumLength(200);
66
+ RuleFor(x => x.EndDate)
67
+ .GreaterThanOrEqualTo(x => x.StartDate).When(x => x.EndDate.HasValue);
68
+ }
69
+ }
70
+ ```
71
+
72
+ ```csharp
73
+ // {Module}/Shared/ProjectDto.cs — includes RowVersionBase64 (IConcurrencyTracked)
74
+ public record ProjectDto
75
+ {
76
+ public Guid Id { get; set; }
77
+ public string Code { get; set; } = string.Empty;
78
+ public string Name { get; set; } = string.Empty;
79
+ public string Status { get; set; } = string.Empty;
80
+ public Guid? OwnerId { get; set; }
81
+ public List<ProjectTaskDto> Tasks { get; set; } = new();
82
+ public string RowVersionBase64 { get; set; } = string.Empty;
83
+ }
84
+
85
+ // {Module}/Shared/ProjectMappingExtensions.cs — hand-written, zero reflection
86
+ public static class ProjectMappingExtensions
87
+ {
88
+ public static ProjectDto ToDto(this Project e) => new()
89
+ {
90
+ Id = e.Id.Value, Code = e.Code.Value, Name = e.Name,
91
+ Status = e.Status.ToString(), OwnerId = e.OwnerId?.Value,
92
+ Tasks = e.Tasks.Select(t => t.ToDto()).ToList(),
93
+ RowVersionBase64 = e.RowVersion is { Length: > 0 } rv
94
+ ? Convert.ToBase64String(rv) : string.Empty
95
+ };
96
+
97
+ public static List<ProjectDto> ToDtoList(this IEnumerable<Project> es)
98
+ => es.Select(e => e.ToDto()).ToList();
99
+ }
100
+ ```
101
+
102
+ Sub-resource endpoint for a distinct operation on a child — nested route, multiple route
103
+ params, `EmptyResponse` when there is no body to return:
104
+
105
+ ```csharp
106
+ // .../Features/AssignTask/AssignTaskEndpoint.cs
107
+ public class AssignTaskEndpoint(IMediator _mediator)
108
+ : SecureFastEndpoint<AssignTaskRequest, EmptyResponse>
109
+ {
110
+ public override void Configure()
111
+ {
112
+ Put("/projects/{projectId:guid}/tasks/{taskId:guid}/assignee"); // sub-resource
113
+ Summary(s => s.Summary = "Assign a task to a TaskUser");
114
+ Options(o => o.WithTags("02 - Project - (FastEndpoints)"));
115
+ }
116
+
117
+ protected override SecurityCachePolicy GetSecurityCachePolicy() => new()
118
+ { SecurityLevel = SecurityLevel.Internal, CachePolicy = CachePolicy.NoStore };
119
+
120
+ protected override async Task<Result<EmptyResponse>> ExecuteAsync(
121
+ AssignTaskRequest req, CancellationToken ct)
122
+ {
123
+ var projectId = Route<Guid>("projectId");
124
+ var taskId = Route<Guid>("taskId");
125
+ var result = await _mediator.Send(new AssignTaskCommand(projectId, taskId, req.AssigneeId), ct);
126
+ return result.IsSuccess
127
+ ? Result<EmptyResponse>.Ok(new EmptyResponse())
128
+ : Result<EmptyResponse>.Failure([.. result.Errors]);
129
+ }
130
+ }
131
+
132
+ public class AssignTaskRequest { public Guid AssigneeId { get; set; } }
133
+ ```
134
+
135
+ Standard `PagedResult<T>` contract (required init props, computed `TotalPages`):
136
+
137
+ ```csharp
138
+ // {Module}/Common/PagedResult.cs
139
+ public sealed class PagedResult<T>
140
+ {
141
+ public required IReadOnlyList<T> Items { get; init; }
142
+ public required int TotalCount { get; init; }
143
+ public required int PageNumber { get; init; }
144
+ public required int PageSize { get; init; }
145
+ public int TotalPages => (int)Math.Ceiling((double)TotalCount / PageSize);
146
+ }
147
+ ```
148
+
149
+ ## Related
150
+
151
+ - Rule file: `guardrails/technology/dotnet-webapi/vertical-slices.md`
@@ -0,0 +1,48 @@
1
+ # Zero-Trust Standards — canonical example
2
+
3
+ > The worked `<SampleProjectName>` example for
4
+ > `guardrails/technology/dotnet-webapi/zero-trust.md`. It is reference material for the phases
5
+ > that generate code — mapped for `design` — and carries no rule of its own: where this
6
+ > example and the rule file disagree, the rule file wins.
7
+ >
8
+ > It is deliberately absent from the `## /aw-spec-constitution` set. The constitution is a
9
+ > thin authority document — one declarative line and a `→` pointer per principle — and has no
10
+ > use for sample code.
11
+
12
+ ## Canonical example (agent reference — `<SampleProjectName>` sample)
13
+
14
+ Secrets/IdP config read from configuration (Aspire parameters / secrets manager) — never
15
+ hard-coded; explicit CORS allow-list; HTTPS enforced outside development:
16
+
17
+ ```csharp
18
+ // <SampleProjectName>.Service/Program.cs
19
+ var cfg = builder.Configuration;
20
+
21
+ // IdP settings come from config — no client secrets or issuer URLs in source (see [[authorization]])
22
+ builder.Services.AddAppWeaverSecurity(security => security
23
+ .AddAuthentication(auth => auth.UseAzureAdB2C(o =>
24
+ {
25
+ o.Instance = cfg["AzureAdB2C:Instance"]!;
26
+ o.Domain = cfg["AzureAdB2C:Domain"]!;
27
+ o.ClientId = cfg["AzureAdB2C:ClientId"]!;
28
+ }, cfg))
29
+ .AddAuthorization(authz => authz.UseRoleBased(o => o.AdminRole = "Admin")),
30
+ options => { }, configuration: cfg);
31
+
32
+ // Explicit CORS allow-list — no wildcards
33
+ builder.Services.AddCors(o => o.AddPolicy("DevelopmentPolicy", p => p
34
+ .WithOrigins("http://localhost:7000", "http://localhost:3000")
35
+ .AllowAnyMethod().AllowAnyHeader().AllowCredentials()));
36
+
37
+ var app = builder.Build();
38
+ app.UseCors("DevelopmentPolicy");
39
+ app.UseAuthentication();
40
+ app.UseAuthorization();
41
+
42
+ if (!app.Environment.IsEnvironment("Development"))
43
+ app.UseHttpsRedirection(); // enforce HTTPS outside dev
44
+ ```
45
+
46
+ ## Related
47
+
48
+ - Rule file: `guardrails/technology/dotnet-webapi/zero-trust.md`
@@ -0,0 +1,61 @@
1
+ # Mandatory Folder Structure
2
+
3
+ > Pure technology (domain-agnostic) — domain additions (Interop adapters, conformance tests, fixtures) in [[folder-structure.domain]]. NON-NEGOTIABLE. Commands: `/aw-spec-design`, `/aw-spec-implement`, `/aw-spec-implement-delta`.
4
+ >
5
+ > Replace `<SampleProjectName>` with the project name (e.g. `Acme.Billing`).
6
+
7
+ ## Layout
8
+
9
+ ```
10
+ src/
11
+ <SampleProjectName>.AppHost/ Aspire composition root (Program.cs)
12
+ <SampleProjectName>.ServiceDefaults/ OTel + Serilog + resilience + service discovery
13
+ <SampleProjectName>.Service/ headless API runtime (a.k.a. <SampleProjectName>.Api)
14
+ Program.cs composition only
15
+ GlobalUsings.cs
16
+ appsettings.json / appsettings.{Env}.json
17
+ Common/ PagedResult<T> + shared value objects
18
+ Extensions/ ApplicationServiceRegistration (mediator/eventbus),
19
+ InfrastructureServiceRegistration (DbContext/repos),
20
+ Aspire/Host extensions, SpecificationExtensions
21
+ Infrastructure/
22
+ ApplicationDbContext.cs ContextAwareDbContext<T>
23
+ *DbContextFactory.cs design-time factories
24
+ Migrations/
25
+ Utilities/ ETag/HTTP helpers (HttpRequest/Response ETag ext)
26
+ <Module>/ one folder per bounded context
27
+ Domain/
28
+ <Aggregate>.cs
29
+ <ChildEntity>.cs
30
+ <ValueObject>.cs
31
+ <Aggregate>Id.cs [ValueObject<Guid>] partial struct
32
+ Enums/ (optional) status/priority enums
33
+ Events/ DomainEventBase descendants
34
+ Specifications/ Specification<TAggregate>
35
+ Persistence/
36
+ <Aggregate>Configuration.cs (+ <ChildEntity>Configuration.cs)
37
+ Features/<FeatureName>/ Command/Query + Handler + Endpoint + Validator
38
+ Shared/ module-public DTOs + ToDto mapping extensions
39
+ tests/
40
+ <SampleProjectName>.UnitTests/
41
+ <SampleProjectName>.IntegrationTests/ Testcontainers-driven
42
+ <SampleProjectName>.TestFixtures/ shared test fixtures
43
+ helm/
44
+ <SampleProjectName>.Api/
45
+ guardrails/ engineering standards (see [[README]] + context map)
46
+ ```
47
+
48
+ ## Rules
49
+
50
+ - Each **module** is a top-level folder with `Domain / Features / Persistence / Shared`
51
+ (see [[modular-monolith]], [[vertical-slices]]).
52
+ - Each **feature** is a self-contained vertical slice (Command/Query + Handler + Endpoint +
53
+ Validator co-located).
54
+ - Cross-cutting files (`Program.cs`, `GlobalUsings.cs`, `Directory.Build.props`,
55
+ `Directory.Packages.props`, `global.json`) MUST stay at the level they occupy in the
56
+ AppWeaver template.
57
+ - New folders outside this structure require a constitution amendment.
58
+
59
+ ## Related
60
+
61
+ - [[modular-monolith]] · [[vertical-slices]] · [[clean-architecture]] · [[folder-structure.domain]]
@@ -0,0 +1,47 @@
1
+ # Modular Monolith Standards
2
+
3
+ > Pure technology (domain-agnostic). NON-NEGOTIABLE where marked. Commands: `/aw-spec-design`.
4
+
5
+ ## Module boundaries
6
+
7
+ - The runtime is a **single deployable service** partitioned into bounded contexts (modules).
8
+ - Each module is a **top-level folder** containing four mandatory child folders:
9
+ `Domain`, `Features`, `Persistence`, `Shared` (plus `Interop` where applicable).
10
+ - A module **owns** its aggregates, persistence configurations, DTOs, integration
11
+ adapters/projectors, and public events. Nothing outside the module may reach past these.
12
+
13
+ ## Cross-module communication
14
+
15
+ - Modules **MUST NOT** reference another module's `Domain` types except through
16
+ **strongly-typed IDs** or the other module's **`Shared` DTOs**.
17
+ - Modules **MUST NOT** take EF Core `DbSet` dependencies on entities they do not own.
18
+ - **Cross-module reads** go through the other module's `Shared` DTOs or its `IMediator`
19
+ queries — never through its `DbContext` entities.
20
+ - **Cross-module writes** go through commands published to `IMediator` (in-process today,
21
+ on the event bus tomorrow). A module **MUST NOT** acquire a write lock on another
22
+ module's aggregate.
23
+ - No horizontal "Services/Managers" layers across slices.
24
+
25
+ ## Schema-per-module guidance
26
+
27
+ - Per-module schemas in PostgreSQL (**schema-per-module**) are RECOMMENDED so a future
28
+ service extraction is a clean cutover.
29
+
30
+ ## Module isolation / testability
31
+
32
+ - Every module **MUST be testable in isolation**: its unit tests and handler tests
33
+ **MUST NOT** require any other module to be loaded.
34
+
35
+ ## Future microservice extraction strategy
36
+
37
+ - Today's modules are tomorrow's services. Splitting a module into its own service
38
+ **MUST require zero changes to the domain code of other modules**.
39
+ - Migration to microservices is **approved by amendment** when a module's deployment
40
+ cadence, scaling profile, team ownership, or regulatory boundary materially diverges
41
+ from the rest of the monolith.
42
+
43
+ ## Related
44
+
45
+ - [[vertical-slices]] — feature organization within a module
46
+ - [[clean-architecture]] — dependency rule across layers
47
+ - [[eventing]] — async cross-module/event-bus propagation
@@ -0,0 +1,82 @@
1
+ # Persistence Standards
2
+
3
+ > Pure technology (domain-agnostic) — domain additions in [[persistence.domain]]. NON-NEGOTIABLE where marked. Commands: `/aw-spec-design`, `/aw-spec-run`.
4
+
5
+ ## EF Core conventions
6
+
7
+ - The `DbContext` is a `ContextAwareDbContext<TContext>` and is **provider-aware**.
8
+ - EF Core mapping lives **only** in `{Module}/Persistence/<Aggregate>Configuration.cs`,
9
+ applied via `ApplyConfigurationsFromAssembly`.
10
+ - `DateTimeOffset` columns **MUST** be re-mapped to `timestamptz` when the provider is Npgsql.
11
+ - Cross-cutting behaviors are applied via `modelBuilder.ApplyCrossCuttingBehaviors(this)`:
12
+ soft-delete global filters, tenant filters, base concurrency-token configuration.
13
+
14
+ ## Repository rules
15
+
16
+ - **Read handlers** inject `IReadRepository<TAggregate>`; **write handlers** inject
17
+ `IRepository<TAggregate>` + `IUnitOfWork`.
18
+ - No "repository as data-access god object" — **no custom methods** beyond
19
+ `IRepository<T>` / `IReadRepository<T>` + `Specification<T>`.
20
+ - Direct `DbContext.Set<T>()` LINQ inside Application Features is FORBIDDEN — use
21
+ `IReadRepository<T>` + a `Specification<T>` only.
22
+
23
+ ## Specification pattern
24
+
25
+ - Every non-trivial query is encapsulated in a `Specification<TAggregate>` under
26
+ `{Module}/Domain/Specifications/`.
27
+ - Specifications **MUST be composable**; paging via `WithPaging(pageNumber, pageSize)`.
28
+ - Ordering uses shared generic helpers (`OrderByIdAsc`, `OrderByIdDesc`, `OrderByNameAsc`);
29
+ ad-hoc `OrderBy` in handlers is forbidden when a typed helper exists.
30
+ - **Cross-aggregate joins via EF navigation properties are FORBIDDEN** — reference parent
31
+ aggregates by strongly-typed ID and project client-side.
32
+
33
+ ## Concurrency handling
34
+
35
+ - Every mutable aggregate **MUST** implement `IConcurrencyTracked`.
36
+ - Concurrency tokens are **client-managed**: `byte[] RowVersion`,
37
+ `IsConcurrencyToken().ValueGeneratedNever()`, refreshed by a `SaveChanges` interceptor.
38
+ - SQL Server `IsRowVersion()` semantics **MUST NOT** leak into entity configurations.
39
+ - ETag / `If-Match` at the edge: see [[api-versioning]].
40
+ - Server sets the ETag header on every create/read/update via `SetETagFromBase64(...)`.
41
+ - Update/Delete endpoints extract `If-Match` via `GetIfMatchBase64Token()` and pass it
42
+ to the command; mismatch returns `409 concurrency.conflict`.
43
+ - `DbUpdateConcurrencyException` is translated to the same `409 concurrency.conflict`.
44
+
45
+ ## Soft-delete rules
46
+
47
+ - Soft delete is enabled via `EnableSoftDelete()`.
48
+ - **Hard deletes are FORBIDDEN** for any aggregate flagged as retention-protected / regulated;
49
+ deletion is logical via `MarkAsDeleted(...)`. (See [[persistence.domain]] for which data
50
+ classes are retention-protected.)
51
+ - Append-only aggregates have no delete path at all.
52
+
53
+ ## Tenancy patterns
54
+
55
+ - Tenancy is enabled via `EnableTenancy()` and `RegisterDefaultContexts(...)`.
56
+ - Tenant resolution **MUST be transparent** to handlers.
57
+ - Default model: **tenant-per-row** with tenant-aware global filters; deployments MAY opt
58
+ into tenant-per-database via configuration.
59
+
60
+ ## Migrations policy
61
+
62
+ - Migrations are authored against **PostgreSQL** (production provider). Development MAY run
63
+ on SQLite (non-sensitive development data only).
64
+ - Multi-provider warnings (`PendingModelChangesWarning`) **MUST** be suppressed only at the
65
+ runtime registration site, **never** in migration code.
66
+ - Migrations **MUST** apply cleanly to a fresh PostgreSQL instance (CI gate).
67
+
68
+ ## Provider profile
69
+
70
+ - Production: PostgreSQL 16+ (encryption-at-rest profile in [[persistence.domain]]);
71
+ per-module schemas where reasonable.
72
+ - Development: PostgreSQL via Aspire containers; SQLite only for in-memory unit-test fixtures.
73
+
74
+ ## Canonical example
75
+
76
+ The worked `<SampleProjectName>` example for these rules lives in
77
+ `guardrails/technology/dotnet-webapi/examples/persistence.md`, mapped for `design` and `run`.
78
+ The constitution set maps the rules without it.
79
+
80
+ ## Related
81
+
82
+ - [[clean-architecture]] · [[cqrs]] · [[domain-driven-design]] · [[api-versioning]] · [[persistence.domain]]
@@ -0,0 +1,162 @@
1
+ # Technology Constitution — dotnet-webapi (domain-agnostic base)
2
+
3
+ > The technology-only governance base for this stack corpus. It heads the set mapped under
4
+ > `## /aw-spec-constitution` in a project's `tech-rule-bindings.md` — this file, then the
5
+ > standard technical rules beside it, then the project team's `technical-requirements.md` —
6
+ > which `/appweaver constitution` ratifies into `.appweaver/memory/constitution.technical.md`.
7
+
8
+ This file is domain-agnostic on purpose: the constitution command loads it *before* the domain
9
+ is selected, and that ordering is what keeps the technical half free of domain material. The
10
+ project's three constitutional SETS are siblings, never merged here — each is headed by
11
+ its own base file:
12
+
13
+ | Source | Ratified into | Principle series |
14
+ |---|---|---|
15
+ | `technology-constitution.md` (this file) | `constitution.technical.md` | I–XV |
16
+ | `domain-constitution.md` | `constitution.domain.md` | XVI+ |
17
+ | the lane corpus's `ui-constitution.md` | `constitution.ui.md` | UX-* |
18
+
19
+ - Core Principles **I–XV** below are domain-agnostic and reused across every project that maps this corpus.
20
+ - **PROJECT IDENTITY**, **REGULATORY REGIME**, domain principles (**XVI+**), domain folder
21
+ additions and governance-override values are **not** filled here — they come from
22
+ `domain-constitution.md`.
23
+ - **Experience principles (UX-\*)** are not filled here — they come from the lane corpus's
24
+ `ui-constitution.md`.
25
+
26
+ This content is the supreme engineering authority for the service lane: where any other
27
+ engineering guidance in the repository disagrees, this document wins. It stays slim and
28
+ authoritative — the detailed rules live in the technical rule files each principle cites.
29
+
30
+ ## Runtime Style
31
+
32
+ A Modular Monolith built to evolve into independent services. It combines Clean Architecture,
33
+ Domain-Driven Design, CQRS + Mediator, Vertical Slice feature organization, and
34
+ Specification-Driven Development. Cross-cutting concerns are delegated to the AppWeaver
35
+ framework family; business logic lives inside aggregates inside their owning module.
36
+
37
+ ## Core Principles (domain-agnostic)
38
+
39
+ > Essence only — the full rules live in the cited rule file.
40
+
41
+ ### I — Modular Monolith with Vertical Slices (NON-NEGOTIABLE)
42
+ Single deployable service partitioned into modules; each module = Domain/Features/Persistence/Shared; each feature is a self-contained vertical slice; no cross-module Domain coupling; no horizontal service layers.
43
+ → `guardrails/technology/dotnet-webapi/modular-monolith.md`, `vertical-slices.md`
44
+
45
+ ### II — Clean Architecture Dependency Rule (NON-NEGOTIABLE)
46
+ Dependencies flow inward: API → Application → Domain ← Infrastructure. Domain is framework-agnostic; endpoints call `IMediator`, never repositories/DbContext.
47
+ → `guardrails/technology/dotnet-webapi/clean-architecture.md`
48
+
49
+ ### III — Domain-Driven Design with Rich Aggregates (NON-NEGOTIABLE)
50
+ Access entities through aggregate roots; strongly-typed Vogen IDs; sealed validating value objects; immutable domain events; invariants enforced in the aggregate; transaction boundary = aggregate boundary.
51
+ → `guardrails/technology/dotnet-webapi/domain-driven-design.md`
52
+
53
+ ### IV — CQRS via Mediator with Result Pattern (NON-NEGOTIABLE)
54
+ All logic dispatched via AppWeaver.Mediator; commands/queries return `Result<T>`; errors are `Result.Failure` (not exceptions); writes run in a transaction and publish domain events.
55
+ → `guardrails/technology/dotnet-webapi/cqrs.md`
56
+
57
+ ### V — Specification-Driven Persistence (NON-NEGOTIABLE)
58
+ Query composition lives in Domain Specifications; no ad-hoc LINQ in handlers; no cross-aggregate EF navigation joins; reference parents by strongly-typed ID.
59
+ → `guardrails/technology/dotnet-webapi/persistence.md`
60
+
61
+ ### VI — Immutable Contracts at the Edge
62
+ Shared DTOs mapped with hand-written `ToDto()`; no reflection mappers; `RowVersionBase64` on concurrency-tracked DTOs; standard `PagedResult<T>`; external projections stay parallel.
63
+ → `guardrails/technology/dotnet-webapi/vertical-slices.md`
64
+
65
+ ### VII — Optimistic Concurrency via ETag / If-Match (NON-NEGOTIABLE)
66
+ Mutable aggregates implement `IConcurrencyTracked`; ETag set on every create/read/update; `If-Match` required on update/delete; mismatch → 409 `concurrency.conflict`.
67
+ → `guardrails/technology/dotnet-webapi/persistence.md`, `guardrails/technology/dotnet-webapi/api-versioning.md`
68
+
69
+ ### VIII — Multi-Provider, Multi-Tenant Persistence
70
+ Provider-aware `ContextAwareDbContext`; PostgreSQL production / SQLite dev (non-sensitive); client-managed concurrency tokens; cross-cutting soft-delete/tenant/audit behaviors; hard delete forbidden for retention-protected data.
71
+ → `guardrails/technology/dotnet-webapi/persistence.md`
72
+
73
+ ### IX — Security by Default (NON-NEGOTIABLE)
74
+ `SecureFastEndpoint` + declared cache policy; external IdP only (no local identity); role-based **and** scope-based auth; secrets from a manager not appsettings; TLS 1.2+; explicit CORS; sensitive data encrypted in transit and at rest (CMK).
75
+ → `guardrails/technology/dotnet-webapi/zero-trust.md`, `authorization.md`, `data-classification.md`
76
+
77
+ ### X — Observability is a First-Class Citizen (NON-NEGOTIABLE)
78
+ AppWeaver.ServiceDefaults (OTel + Serilog + health + resilience + discovery); `ILogger` message templates only; never log secrets/regulated data; every sensitive read/mutation emits an audit record; trace context propagates everywhere.
79
+ → `guardrails/technology/dotnet-webapi/auditing.md`, `data-classification.md`
80
+
81
+ ### XI — Cloud-Native Orchestration via .NET Aspire
82
+ AppHost is the composition root; backing services are Aspire resources referenced via `.WithReference(...)`; no hard-coded connection strings/ports; Helm stays in sync with the AppHost projection.
83
+ → `guardrails/technology/dotnet-webapi/zero-trust.md`, `eventing.md`
84
+
85
+ ### XII — REST API Standards
86
+ Internal REST (FastEndpoints, one endpoint/file, kebab routes); standard paging; versioned breaking changes; machine-readable contracts (OpenAPI). Domain interoperability surfaces (e.g. FHIR) are added by the domain half.
87
+ → `guardrails/technology/dotnet-webapi/api-versioning.md`, `vertical-slices.md`
88
+
89
+ ### XIII — Test-First Engineering
90
+ Tests for every aggregate behavior/value object/specification/handler/endpoint; deterministic (`IClock`/`IGuidGenerator`); contract changes ship with test updates in the same commit.
91
+ → `guardrails/technology/dotnet-webapi/testing.md`
92
+
93
+ ### XIV — Data Integration Layer / Single Source of Truth (NON-NEGOTIABLE)
94
+ Authoritative system of record; consumers use the REST API / published projections / CloudEvents only; no direct DB access; inbound feeds flow through Interop adapters; versioned machine-readable schemas.
95
+ → `guardrails/technology/dotnet-webapi/eventing.md`, `guardrails/technology/dotnet-webapi/api-versioning.md`
96
+
97
+ ### XV — Evolutionary Path to Microservices
98
+ Modules own their aggregates/persistence/DTOs/projectors/events; cross-module access via Shared DTOs or `IMediator`; per-module schemas recommended; extraction approved by amendment.
99
+ → `guardrails/technology/dotnet-webapi/modular-monolith.md`
100
+
101
+ > **Domain principles (XVI and beyond) are supplied by `domain-constitution.md`.**
102
+ > **Experience principles (UX-\*) are supplied by the lane corpus's `ui-constitution.md`.**
103
+
104
+ ## Mandatory Folder Structure
105
+
106
+ Governed by the technical rule files; this file does not duplicate the tree.
107
+
108
+ - Technology layout (src/tests/helm/docs, module = Domain/Features/Persistence/Shared):
109
+ `guardrails/technology/dotnet-webapi/folder-structure.md`
110
+ - Domain-specific additions (Interop adapters, domain test fixtures, regulatory controls):
111
+ supplied by `domain-constitution.md` + the active domain corpus's `folder-structure.domain.md`
112
+ - The frontend lane's layout lives entirely under its own root and is supplied by that lane's
113
+ own corpus, `guardrails/technology/nextjs/ui-constitution.md`. Nothing here applies to it.
114
+
115
+ Project names use the `<SampleProjectName>` placeholder. Cross-cutting files (`Program.cs`,
116
+ `GlobalUsings.cs`, `Directory.Build.props`, `Directory.Packages.props`, `global.json`) MUST stay
117
+ at the same level they occupy in the AppWeaver template.
118
+
119
+ ## Conventions, Forbidden Patterns, AI Rules, Quality Gates
120
+
121
+ Governed in full by the technical rule files; this file does not duplicate them.
122
+
123
+ - Naming & coding conventions, the Forbidden Patterns, and the CI Quality Gates:
124
+ `guardrails/technology/dotnet-webapi/coding-standards.md`
125
+ - Package governance (approved/banned packages, supply-chain, licensing):
126
+ `guardrails/technology/dotnet-webapi/dependency-policy.md`
127
+ - AI operational rules (generation, context loading, refusal conditions):
128
+ `.appweaver/ai-rules.md` — the domain half extends this with domain-specific masking,
129
+ code-set and refusal rules
130
+
131
+ ## Governance
132
+
133
+ - This constitution supersedes all other engineering documentation in the repository. Where they
134
+ disagree, this document wins; a rule file that contradicts a principle here is the file that
135
+ gets corrected.
136
+ - Amendments are proposed via pull request that modifies this file (and the affected rule
137
+ files), includes a migration plan for non-compliant code, bumps the version per the policy
138
+ below, and is approved per the roles named in `domain-constitution.md`'s Governance Overrides
139
+ (at minimum one Principal Engineer + the domain's mandatory approver).
140
+ - Versioning follows SemVer applied to governance:
141
+ - **MAJOR** — removal or weakening of a NON-NEGOTIABLE principle, or a backward-incompatible
142
+ change to the Mandatory Folder Structure.
143
+ - **MINOR** — addition of a new principle, new mandatory section, or new bounded context.
144
+ - **PATCH** — clarifications, wording fixes, non-semantic edits.
145
+ - This file versions independently of `domain-constitution.md` and `ui-constitution.md`.
146
+ - Compliance review happens on every PR. Reviewers MUST cite the principle number when
147
+ requesting changes.
148
+ - A quarterly architecture and security review MUST audit a random sample of modules against
149
+ this constitution and file remediation tickets for any deviation.
150
+ - Runtime guidance files MUST carry a single pointer to the ratified constitution and MUST NOT
151
+ duplicate or paraphrase its rules.
152
+ - Domain-specific governance overrides (approver roles, regulatory review triggers, control
153
+ mappings) are supplied by `domain-constitution.md`.
154
+
155
+ ## Ratification Metadata
156
+
157
+ > Carried into `constitution.technical.md` at ratification; the constitution command owns the
158
+ > version bump from there.
159
+
160
+ - **Version:** 1.0.0
161
+ - **Ratified:** `<YYYY-MM-DD>`
162
+ - **Last Amended:** `<YYYY-MM-DD>`
@@ -0,0 +1,55 @@
1
+ # Testing Standards
2
+
3
+ > Pure technology (domain-agnostic) — domain additions in [[testing.domain]]. Commands: `/aw-spec-design`, `/aw-spec-implement`, `/aw-spec-implement-delta`, `/aw-spec-analyze-slice`.
4
+
5
+ ## Test-first engineering
6
+
7
+ - Generated tests follow Test-First Engineering and **MUST fail before** the production
8
+ change is in place.
9
+ - Any change to an aggregate invariant, endpoint contract, or error code **MUST** include
10
+ the corresponding test update **in the same commit**.
11
+
12
+ ## Unit test conventions
13
+
14
+ - Unit tests are required for **every** aggregate behavior, value object, and specification.
15
+ - Tests are **deterministic** — time, randomness, and IDs are injected
16
+ (use the framework-provided `IClock` / `IGuidGenerator`). Never `DateTime.UtcNow` /
17
+ `Guid.NewGuid()` in the system under test.
18
+ - Tests **MUST NOT** reach into module internals; they exercise the public endpoint or
19
+ `IMediator` surface.
20
+
21
+ ## Handler tests
22
+
23
+ Required for **every** Command/Query handler and MUST cover:
24
+
25
+ - happy path
26
+ - validation failure
27
+ - not-found
28
+ - (for writes) concurrency conflict
29
+
30
+ ## Integration testing
31
+
32
+ - Required for **every** endpoint; run against **PostgreSQL via Testcontainers** or Aspire.
33
+ - Test database engine: Testcontainers PostgreSQL for integration; in-memory fixtures for
34
+ unit tests.
35
+
36
+ ## Testcontainers usage
37
+
38
+ - Integration and contract tests spin up real PostgreSQL (and other backing services)
39
+ via Testcontainers / Aspire — no faked persistence in integration tests.
40
+
41
+ ## Test data hygiene
42
+
43
+ - Tests use a **shared fixture library** rather than inlining fabricated data.
44
+ - Production data MUST NOT be used in development, test, demo, or shared CI.
45
+ (Domain specifics — synthetic fixtures + terminology sentinels — in [[testing.domain]].)
46
+
47
+ ## Coverage rules
48
+
49
+ - Minimum **85% line coverage** on Application + Domain.
50
+ - **100%** on aggregate behaviors and value objects.
51
+ - Code coverage on changed files must meet the threshold (CI gate).
52
+
53
+ ## Related
54
+
55
+ - [[domain-driven-design]] · [[persistence]] · [[testing.domain]]