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,75 @@
1
+ # Forms & Validation Standards — nextjs (frontend lane)
2
+
3
+ > Pure technology (domain-agnostic). NON-NEGOTIABLE where marked.
4
+ > Commands: `/aw-spec-design-ui`, `/aw-spec-implement-ui`.
5
+ > Detail layer under `constitution.ui.md` UX-V (every interaction state is specified) and
6
+ > UX-VII (mutations flow through one path).
7
+
8
+ A form is where the three failure modes meet — a user making mistakes, a network that may
9
+ not answer, and a service that is the real authority. All three are designed, not
10
+ discovered.
11
+
12
+ ## The authority rule (NON-NEGOTIABLE)
13
+
14
+ - **A client-side check restates a service rule for feedback. It NEVER replaces it.** The
15
+ service's validators check request shape and its domain enforces the invariants
16
+ ([[api-integration.<service-stack>]]).
17
+ - Every client-side rule **cites the spec id it echoes** (`BR-`/`FR-`) in the design's §4 and
18
+ in a code comment. An uncited client rule is a second, drifting copy of a business rule.
19
+ - A rule the service enforces and the client cannot know — uniqueness, cross-record limits,
20
+ state transitions — is **not** guessed at client-side. The form submits and renders the
21
+ service's field errors.
22
+
23
+ ## What the design owns
24
+
25
+ `design.ui.md §4` states, per form:
26
+
27
+ - **When validation runs** per field group — on change, on blur, on submit. Validating a
28
+ required field on first keystroke tells the user they are wrong before they have finished
29
+ being right.
30
+ - **How failures are surfaced** — inline per field, summarised at the top, or both — and
31
+ where focus goes on failure.
32
+ - **What is disabled while in flight**, and what a second submit does.
33
+ - **What happens on cancel and on navigate-away** with unsaved changes.
34
+ - **What survives a failed submit** — the user's input always does; a form that clears
35
+ itself on a server error is data loss.
36
+
37
+ ## Field errors from the service
38
+
39
+ - A `400` carries field-level errors. They are mapped onto the matching fields, not shown as
40
+ one opaque banner.
41
+ - A field error the client cannot attribute to a field is surfaced at form level, never
42
+ dropped.
43
+ - Focus moves to the first offending field, and the error is programmatically associated
44
+ with it so it is announced ([[accessibility-implementation]]).
45
+
46
+ ## Submission
47
+
48
+ - The submit path is the one mutation path (UX-VII): a Server Action or a generated-client
49
+ wrapper, never an ad-hoc handler.
50
+ - **Double submit is prevented in the UI and safe at the service.** The control disables on
51
+ submit, and the operation is idempotent or carries a client-generated key — because the
52
+ disable can be bypassed.
53
+ - On success the form's invalidation runs ([[state-management]]) and the design's success
54
+ state renders. "The call returned 2xx" is not, by itself, a state the user sees.
55
+ - On a `409` version conflict the stale-record state renders — never an automatic retry
56
+ ([[api-integration.<service-stack>]]).
57
+
58
+ ## Input handling
59
+
60
+ - Input is trimmed, normalised and typed at the client boundary, once — not in each
61
+ consumer.
62
+ - Numeric, date and currency input is parsed against the active locale ([[i18n]]) and sent
63
+ in the contract's canonical form. A date sent in the browser's local interpretation is a
64
+ timezone bug waiting for a user in another country.
65
+ - Classified fields are not autocompleted, not autofilled into unrelated fields and not
66
+ echoed into the URL ([[client-security]]).
67
+ - Destructive actions are confirmed as the design specifies, and the confirmation names what
68
+ will happen — including that a delete is a **logical** delete where the service does one.
69
+
70
+ ## Related
71
+
72
+ - [[error-handling]] — the five states every submission passes through
73
+ - [[api-integration.<service-stack>]] — the service's validation and conflict contract
74
+ - [[accessibility-implementation]] — label association, announcement, focus
75
+ - [[i18n]] — locale-aware parsing and formatting
@@ -0,0 +1,94 @@
1
+ # Frontend Testing Standards — nextjs (frontend lane)
2
+
3
+ > Pure technology (domain-agnostic). NON-NEGOTIABLE.
4
+ > Commands: `/aw-spec-implement-ui`.
5
+ > Detail layer under `constitution.ui.md` UX-XI (frontend test-first).
6
+
7
+ Every file `implement-ui` generates ships with its test. The design says what to test: each
8
+ test **cites the spec id** from `design.ui.md §7 Traceability` that it covers, so a coverage
9
+ gap reads as a `UX-`/`US-`/`FR-` with no test rather than as a percentage.
10
+
11
+ ## What ships with what
12
+
13
+ | Generated | Test that ships with it |
14
+ |---|---|
15
+ | Screen | renders for each of its `§1` access conditions; the not-found and denied paths |
16
+ | Feature component | its stated responsibility, its inputs at their boundaries, the events it raises |
17
+ | Form | validation timing, the field-error mapping, the double-submit guard, what survives a failed submit |
18
+ | Client-layer wrapper | contract integration against the **generated types**, including the failure mapping |
19
+ | Every interactive surface | an accessibility assertion |
20
+
21
+ ## The interaction states ARE the coverage
22
+
23
+ Per UX-V and `§4`, loading, empty, error, permission-denied and in-flight each get a test.
24
+ These are the assertions that catch real regressions; a suite covering only the happy path
25
+ passes while the surface is broken. Specifically:
26
+
27
+ - **Empty is distinct from loading**, and both are asserted — a spinner that never resolves
28
+ and a genuinely empty list look identical to a test that only checks "no rows".
29
+ - **`403` renders denied, not error.** A test that accepts any failure state cannot tell
30
+ them apart, and neither will the user.
31
+ - **A `409` version conflict renders the stale-record state and does NOT retry.** Assert
32
+ the absence of the retry ([[api-integration.<service-stack>]]).
33
+ - **Out-of-range paging** — an empty item list with a non-zero total — renders the
34
+ past-the-last-page state, distinct from "no results".
35
+ - A retryable failure retries a bounded number of times; a non-idempotent mutation does not
36
+ retry at all.
37
+
38
+ ## Testing through the user's surface
39
+
40
+ - Query by **role, accessible name and visible text**. A test coupled to an internal
41
+ structure fails on a refactor that changed nothing a user can see, and passes when the
42
+ accessible name is wrong.
43
+ - **A snapshot is not coverage.** It records what the code does, including what it does
44
+ wrong, and it is approved by whoever is least likely to read it.
45
+ - Assert on outcomes, not on implementation calls. "The mutation wrapper was called" is
46
+ weaker than "the row disappears and the toast names the record".
47
+
48
+ ## Contract integration
49
+
50
+ - The service is stubbed **at the client layer**, against the generated contract types. A
51
+ stub that does not typecheck against the contract is a test asserting a contract that does
52
+ not exist ([[api-client]]).
53
+ - Stubs mirror the **real** shapes the pairing file states — the paged envelope with its
54
+ actual field names, the version token on tracked reads, the real error codes. A
55
+ hand-written happy shape hides exactly the integration defects this suite exists to catch
56
+ ([[api-integration.<service-stack>]]).
57
+ - **The paging index base is asserted, not assumed**: request page one and assert the value
58
+ that goes on the wire. A 0-based service read by a 1-based client does not fail — it skips
59
+ a page — so this assertion is the only thing that catches it.
60
+ - **Redaction is tested**: the same endpoint returning a reduced field set for a lesser role
61
+ renders the design's "not available to you" affordance, not an error and not a blank.
62
+ - Client regeneration drift fails the build — a suite passing against a stale client is a
63
+ green build shipping a broken screen.
64
+
65
+ ## Accessibility assertions
66
+
67
+ Per UX-I every interactive surface asserts: reachable by keyboard, correct accessible name,
68
+ focus placed where the design says on open and on error, and the announced state change
69
+ where the design names one ([[accessibility-implementation]]). An automated scan is a floor,
70
+ not a pass — it cannot see focus order or a meaningless accessible name.
71
+
72
+ ## Discipline
73
+
74
+ - Tests are **deterministic**: no real network, no wall-clock dependence, no ordering
75
+ between files, no shared mutable fixture.
76
+ - Time and randomness are injected so a date-dependent screen is testable at any date.
77
+ - Each test names its spec id. A test with no id tests something the design did not ask for
78
+ — either the design is missing a row, or the test is.
79
+ - No test asserts on a classified value it should not have; fixtures use synthetic data
80
+ ([[client-security]]).
81
+
82
+ ## Gates
83
+
84
+ Type-check, lint, accessibility scan, unit and integration tests, and the performance budget
85
+ are all blocking. **A lane that fails any of them fails the build** — there is no
86
+ frontend-only exemption, and a lane that was never compiled reporting green is the exact
87
+ failure the lane model exists to prevent.
88
+
89
+ ## Related
90
+
91
+ - [[api-client]] — the layer stubs attach to
92
+ - [[api-integration.<service-stack>]] — the real shapes stubs must mirror
93
+ - [[error-handling]] — the states under test
94
+ - [[accessibility-implementation]] — what the accessibility assertion checks
@@ -0,0 +1,57 @@
1
+ # Internationalization Standards — nextjs (frontend lane)
2
+
3
+ > Pure technology (domain-agnostic). Commands: `/aw-spec-design-ui`, `/aw-spec-implement-ui`.
4
+ > Detail layer under `constitution.ui.md` UX-X (internationalization is structural).
5
+
6
+ Internationalization is structural: it is cheap while the surface is being designed and
7
+ expensive once strings are scattered through components. It is applied whether or not a
8
+ second locale ships today.
9
+
10
+ ## Strings
11
+
12
+ - **Every user-visible string comes from the locale catalogue.** A literal in a component is
13
+ a string no translator will ever see and no reviewer will ever read as copy.
14
+ - Keys are semantic and scoped to the feature: `order.cancel.confirmTitle`, not `title2`.
15
+ - **Sentences are never concatenated from fragments.** Word order differs by language, so a
16
+ sentence assembled from parts is untranslatable. Use one message with named placeholders.
17
+ - Plurals and gendered forms use the catalogue's plural rules, not an `if count === 1`.
18
+ - The catalogue carries the CONTEXT a translator needs — where the string appears, what the
19
+ placeholders are. A bare key with no context produces a confident mistranslation.
20
+ - A missing key is visible in development and falls back deterministically in production; it
21
+ never renders the raw key to a user, and never renders empty.
22
+
23
+ ## Formatting
24
+
25
+ - Dates, times, numbers, currencies, units, percentages and relative times are formatted at
26
+ the boundary, locale-aware. **No hand-rolled format strings.**
27
+ - Timezone is explicit. A timestamp is stored and transported in the contract's canonical
28
+ form and rendered in the user's zone — never rendered in the browser's zone by accident
29
+ and never sent in it ([[forms-and-validation]]).
30
+ - Sorting and comparison of user-visible text is locale-aware; a byte-order sort is wrong in
31
+ most languages.
32
+ - Input parsing is the mirror of output formatting: a decimal comma, a local date order and
33
+ a grouped number all parse correctly.
34
+
35
+ ## Layout consequences
36
+
37
+ - Text expands — plan for roughly a third more than English. **A layout that only fits its
38
+ English copy is a defect**, and it is found at design time from the design's own longest
39
+ string, not at translation time.
40
+ - Where the design's Experience Scope names a right-to-left locale, direction is a token-
41
+ level and layout-level concern, not a per-component flip. Logical properties (start/end)
42
+ are used rather than physical ones (left/right).
43
+ - The document's language is declared, and it changes with the active locale so assistive
44
+ technology pronounces correctly ([[accessibility-implementation]]).
45
+
46
+ ## Locale selection
47
+
48
+ - The active locale is resolved once, from the design's stated source — the route, the user's
49
+ profile, or the request — and every consumer reads that one answer.
50
+ - Locale is a preference, not classified data ([[client-security]]).
51
+ - Switching locale does not lose in-progress work.
52
+
53
+ ## Related
54
+
55
+ - [[design-system]] — where the strings are rendered
56
+ - [[forms-and-validation]] — locale-aware parsing on the way in
57
+ - [[accessibility-implementation]] — language declaration and announcement
@@ -0,0 +1,67 @@
1
+ # Frontend Observability Standards — nextjs (frontend lane)
2
+
3
+ > Pure technology (domain-agnostic). NON-NEGOTIABLE where marked.
4
+ > Commands: `/aw-spec-implement-ui`.
5
+ > Detail layer under `constitution.ui.md` UX-VIII (client state carries no secret).
6
+
7
+ The service is instrumented end to end — OpenTelemetry, structured logs, trace propagation
8
+ across its whole pipeline. This lane's job is to make a user action **findable** in that
9
+ telemetry, and to add nothing to it that must not be there.
10
+
11
+ ## Correlation (NON-NEGOTIABLE)
12
+
13
+ - Every request from `lib/api/` carries the trace context, so a screen's action can be
14
+ followed into the service's traces. One HTTP layer is what makes those headers consistent
15
+ — the other reason raw `fetch` elsewhere is forbidden ([[api-client]]).
16
+ - A correlation id surfaced to the user on an error screen is a support affordance the
17
+ design specifies, and it is an id — never a stack trace, never a service message
18
+ ([[error-handling]]).
19
+ - A user-initiated flow that spans several calls carries one correlation across them, so the
20
+ flow is one story in the telemetry rather than three unrelated requests.
21
+
22
+ ## What is recorded
23
+
24
+ - Client errors — unhandled exceptions, failed mutations, contract-mapping failures — are
25
+ reported with the route, the correlation id and the error code.
26
+ - The performance vitals the budget gates on are reported per route
27
+ ([[performance-budgets]]).
28
+ - Product events, where the design names them, are recorded against a stable event name and
29
+ a documented property set.
30
+
31
+ ## What is NEVER recorded (NON-NEGOTIABLE)
32
+
33
+ Mirroring the service's own rule, and extending it to everything the client can see:
34
+
35
+ - Authentication tokens, credentials, private keys or full payment-card data — in logs,
36
+ error reports, metric labels, span attributes, breadcrumbs or session replay.
37
+ - Any field the spec's `DC-` ids classify as restricted.
38
+ - **Full request or response bodies.** A body captured "for debugging" carries whatever the
39
+ service returned, including the fields its projections redacted for other users.
40
+ - URLs with classified data in them — which is the second reason such data never reaches a
41
+ URL ([[client-security]]).
42
+
43
+ Where a report needs shape rather than content, record the shape: field names, counts,
44
+ lengths, error codes. Never the values.
45
+
46
+ ## Structured, not ad hoc
47
+
48
+ - Reporting goes through one configured layer, like requests do. `console.log` is a
49
+ development tool and is a Forbidden Pattern in production code — it is unstructured,
50
+ unsampled, unredacted, and visible to the user.
51
+ - Events carry a stable name and typed properties. A message assembled by string
52
+ interpolation cannot be queried.
53
+ - Sampling and volume are configured, not accidental. Telemetry that costs more than it
54
+ explains gets turned off, and then nothing is observable.
55
+
56
+ ## Session replay and analytics
57
+
58
+ - Any replay or analytics tool is a dependency decision recorded in the delta
59
+ ([[client-security]]) and is configured to mask classified fields **by default**, with
60
+ masking opt-out per field rather than opt-in.
61
+ - A third-party script never receives a token, a classified field or a URL carrying one.
62
+
63
+ ## Related
64
+
65
+ - [[api-client]] — where the trace headers are attached
66
+ - [[client-security]] — the storage and disclosure rules this extends
67
+ - [[error-handling]] — what the user sees when something is being reported
@@ -0,0 +1,66 @@
1
+ # Performance Budget Standards — nextjs (frontend lane)
2
+
3
+ > Pure technology (domain-agnostic). NON-NEGOTIABLE.
4
+ > Commands: `/aw-spec-design-ui`, `/aw-spec-implement-ui`.
5
+ > Detail layer under `constitution.ui.md` UX-IX (the performance budget is a gate).
6
+
7
+ A budget that is not enforced is an aspiration. Core Web Vitals thresholds and a per-route
8
+ JavaScript budget are **CI gates**: a route over its budget does not ship.
9
+
10
+ ## What the design owns
11
+
12
+ `design.ui.md §6` carries the performance row, citing the `SC-` it serves:
13
+
14
+ - The **target** for this feature's primary flow, taken from the spec's success criteria —
15
+ not a generic "should be fast".
16
+ - The **structural choice** that meets it: what renders on the server, what is deferred,
17
+ what is paginated, what is streamed. Performance is a design decision; it cannot be
18
+ retrofitted by minifying harder.
19
+ - The **device and network floor** from the Experience Scope. A target met on a developer
20
+ laptop on office wifi is not a target.
21
+
22
+ ## Rendering
23
+
24
+ - Server-render by default (UX-III). Interactivity is opted into at the leaf, so the
25
+ client bundle carries only what genuinely needs to run in the browser.
26
+ - Data the first paint needs is fetched on the server. A client fetch-on-mount for
27
+ above-the-fold content costs a round trip **and** a loading flash the design has to specify.
28
+ - Below-the-fold and interaction-triggered work is deferred — but a deferred boundary is a
29
+ loading state, and it appears in `§4` like any other.
30
+ - Streaming boundaries are placed where the design says the user can start reading, not
31
+ wherever the code happened to split.
32
+
33
+ ## Payload
34
+
35
+ - **A dependency is a design decision recorded in the delta, not an import** (UX-IX). It is
36
+ judged on what it adds to the route that carries it.
37
+ - Images are sized, modern-format and lazy below the fold; an image with no intrinsic
38
+ dimensions causes layout shift, which is a scored vital.
39
+ - Fonts are subset, preloaded where they block first paint, and have a fallback that does
40
+ not shift the layout.
41
+ - No large dependency is pulled in for a small utility, and no dependency is loaded from a
42
+ CDN at runtime ([[client-security]]).
43
+
44
+ ## Data access
45
+
46
+ - Lists are paged server-side ([[api-integration.<service-stack>]]). Fetching everything and
47
+ paging in the browser scales with the data rather than the screen.
48
+ - **The N+1 rule applies to the client too**: a list that fires one request per row is a
49
+ design defect. The contract offers a batched shape, or the delta asks for one.
50
+ - Requests are deduplicated and superseded requests cancelled ([[api-client]]).
51
+ - Caching and revalidation are declared per fetch (UX-VI) — the cheapest request is the one
52
+ not made, and the most expensive bug is the stale one.
53
+
54
+ ## The gate
55
+
56
+ - Core Web Vitals thresholds and the per-route JavaScript budget run in CI and **block**.
57
+ - A budget rise is a reviewed change with a stated reason, not a threshold quietly edited to
58
+ make the build pass.
59
+ - The budget is measured at the Experience Scope's floor, not at the best case.
60
+
61
+ ## Related
62
+
63
+ - [[state-management]] — caching, invalidation and what is fetched twice
64
+ - [[api-integration.<service-stack>]] — server-side paging and batching
65
+ - [[error-handling]] — the loading states deferral creates
66
+ - [[design-system]] — layout stability and the token-level image/font decisions
@@ -0,0 +1,52 @@
1
+ # Routing & Navigation Standards — nextjs (frontend lane)
2
+
3
+ > Pure technology (domain-agnostic). Commands: `/aw-spec-design-ui`.
4
+ > Detail layer under `constitution.ui.md` UX-III (server components) and UX-V (every
5
+ > interaction state specified).
6
+
7
+ The rules `design.ui.md §1 Navigation & Screen Structure` is authored against. The design
8
+ states the navigation SHAPE conceptually — a path pattern, a nesting, a set of siblings —
9
+ and never names a router.
10
+
11
+ ## One screen, one decision
12
+
13
+ - A screen exists because the user makes a decision there. A screen that only displays is
14
+ a component on another screen, not a route.
15
+ - A screen belongs to the feature that owns that decision. A screen reading another
16
+ aggregate's data declares the dependency; it is never duplicated into two features.
17
+ - Every screen row names the `US-` it serves. A user story with no screen home is a
18
+ coverage failure caught in `§7`, not a gap discovered at `implement-ui`.
19
+
20
+ ## Route shape
21
+
22
+ - Routes are hierarchical and readable: a nested route means a nested decision, not a
23
+ shared layout. Shared chrome is a layout concern, not a route.
24
+ - A route parameter identifies a resource; it never carries state, a filter set, or
25
+ anything the `DC-` ids restrict. Shareable view state belongs in the query string, and
26
+ the design says which state is shareable.
27
+ - The design names the ENTRY POINT of the feature's primary flow and what a direct,
28
+ bookmarked hit on each screen must do.
29
+
30
+ ## Access conditions
31
+
32
+ Every screen states its access conditions and the spec id that imposes them —
33
+ authentication state, role, or record state. Two rules follow, and both are design-level:
34
+
35
+ - Hidden, disabled and forbidden are three different outcomes. The design says which one
36
+ each condition produces; `implement-ui` does not get to choose.
37
+ - A client-side access condition is a NAVIGATION affordance, never an enforcement. The
38
+ service decides; per `CN-`, a route reachable by typing its address must fail server-side.
39
+
40
+ ## Navigation states
41
+
42
+ Per UX-V a route's own states are specified, not discovered: what shows while the screen's
43
+ data loads, what shows when the resource does not exist, and what shows when the user may
44
+ not see it. Each is an EARS unwanted-behaviour `FR-` in the spec and a `§4` row here.
45
+
46
+ ## Related
47
+
48
+ - [[component-architecture]] — what a screen composes
49
+ - [[auth-session]] — hidden vs disabled vs denied, and what an unauthenticated deep link does
50
+ - [[error-handling]] — the not-found, denied and failed states a route can reach
51
+ - [[state-management]] — what survives a navigation and what does not
52
+ - [[performance-budgets]] — what a route may cost
@@ -0,0 +1,70 @@
1
+ # Client State Standards — nextjs (frontend lane)
2
+
3
+ > Pure technology (domain-agnostic). Commands: `/aw-spec-design-ui`.
4
+ > Detail layer under `constitution.ui.md` UX-VI (caching declared), UX-VII (one mutation
5
+ > path) and UX-VIII (client state carries no secret).
6
+
7
+ The rules `design.ui.md §2 Client State` is authored against. State is a DESIGN decision:
8
+ a stale-data defect and a secret in local storage are both design defects, and both are
9
+ invisible by the time they are code.
10
+
11
+ ## Three kinds, three owners
12
+
13
+ Every entry in `§2` declares which kind it is, and the kind decides the owner:
14
+
15
+ - **Server-derived** — a projection of what the service holds. Owned by the data-fetching
16
+ layer's cache, never copied into a store. It has an invalidation trigger; a row without
17
+ one is incomplete.
18
+ - **Local UI** — open/closed, selected tab, draft input, in-flight flag. Owned by the
19
+ narrowest component that needs it. It never outlives the screen.
20
+ - **Session** — genuinely client-side, cross-screen, non-secret: locale, theme, a
21
+ multi-step flow's progress. This is the only kind a global store may hold.
22
+
23
+ Server-derived state placed in a global store is a design error, not a style preference:
24
+ it forks the cache, and the fork is what serves stale data.
25
+
26
+ ## Invalidation is part of the design
27
+
28
+ - Every server-derived row names what invalidates it — the mutation, the navigation, or
29
+ the elapsed time. "Refetch on mount" is not an invalidation policy.
30
+ - Per UX-VI a caching and revalidation policy is DECLARED, never inherited from a
31
+ default that happens to work.
32
+ - A mutation states what it invalidates in `§5`, and an optimistic update states its
33
+ rollback. Optimism without a stated rollback is not a design.
34
+
35
+ ## The concurrency token is state
36
+
37
+ A record read from a concurrency-tracked service arrives with a **version token** — an ETag
38
+ header, a version field on the DTO, or both, depending on the declared service stack
39
+ ([[api-integration.<service-stack>]] names which). **That token is part of the record's
40
+ client state and is held beside it**, not discarded on mapping.
41
+
42
+ - A record held without its token cannot be updated safely: the write either omits
43
+ `If-Match` and overwrites someone else's change, or it fails.
44
+ - The token is refreshed from every response that returns one. A stale token in state
45
+ produces a `409` the user cannot resolve by retrying.
46
+ - The token is not user-visible and never reaches the URL.
47
+
48
+ ## Derived, not duplicated
49
+
50
+ A value computable from state already held is DERIVED and recorded as such. Two rows
51
+ holding the same fact will disagree, and the design is where that is prevented.
52
+
53
+ ## What must never be held
54
+
55
+ Per UX-VIII, `§2`'s "what must NOT be held" list is mandatory and cites its spec ids:
56
+
57
+ - Any field the spec's `DC-` ids classify as restricted — including in logs, telemetry,
58
+ URLs, query strings and browser storage.
59
+ - Credentials, tokens and anything that would let the client answer a question the
60
+ service must answer.
61
+ - The RESULT of an authorization decision used as if it were the decision. Per `CN-`, the
62
+ client may hide or disable; the service enforces.
63
+
64
+ ## Related
65
+
66
+ - [[api-integration.<service-stack>]] — the paging shape, the concurrency token, the caching contract
67
+ - [[component-architecture]] — who reads the state
68
+ - [[api-client]] — where server-derived state comes from
69
+ - [[auth-session]] — what must be cleared on sign-out
70
+ - [[error-handling]] — the states a fetch or mutation passes through
@@ -0,0 +1,166 @@
1
+ # UI Constitution — nextjs (frontend lane)
2
+
3
+ > The frontend lane's governance base for this stack corpus. It heads the set mapped under
4
+ > `## /aw-spec-ui-constitution` in a project's `tech-rule-bindings.md` — this file, then the
5
+ > project team's `ui-requirements.md` — which `/appweaver constitution` ratifies into
6
+ > `.appweaver/memory/constitution.ui.md`.
7
+
8
+ Mapping this heading is also what **declares that the project has a frontend lane**. With no
9
+ heading the constitution command skips the UI half and creates no file — so a backend-only
10
+ project without a frontend lane simply leaves this file unmapped.
11
+
12
+ This base is **domain-free**, exactly like the service lane's `technology-constitution.md`: it is loaded
13
+ before the domain is selected. Domain reaches the UI lane the same way it reaches the service
14
+ lane — through the spec, as `CN-` / `DC-` / `IC-` ids. No regulatory or terminology rule
15
+ belongs here; those live in `domain-constitution.md`.
16
+
17
+ Principles are a **UX-\*** series. They run parallel to the technology base's I–XV and do not
18
+ continue them — the two govern different lanes and version independently.
19
+
20
+ ## Declared Lane
21
+
22
+ Stack **nextjs** — Next.js (TypeScript, App Router), lane id `web`, owning `web/`.
23
+
24
+ Where `.appweaver/stacks.json` declares a frontend lane, that declaration is authoritative for the
25
+ lane id and root; a scaffold that disagrees fails `STACK-MISMATCH:` rather than rewriting it.
26
+
27
+ ## Experience Principles
28
+
29
+ ### UX-I — Accessibility Floor (NON-NEGOTIABLE)
30
+ Every interactive surface meets WCAG 2.2 AA: keyboard reachability, visible focus, correct focus
31
+ order and accessible names are acceptance criteria, not polish. The conformance target arrives as
32
+ a `UX-` standard in the spec's Experience Standards; this principle makes it non-negotiable rather
33
+ than restating it.
34
+
35
+ ### UX-II — The Design System is the Only Source of Visual Truth (NON-NEGOTIABLE)
36
+ Components, spacing, type scale and colour come from the declared design system and its tokens.
37
+ No ad-hoc styling, no second component library, no inline design values.
38
+
39
+ ### UX-III — Server Components by Default
40
+ A route renders on the server unless it needs interactivity or browser-only APIs. `"use client"`
41
+ is an opt-in that a reviewer can justify from the component's own behaviour, never the default,
42
+ and it never appears at a layout root to cover a subtree.
43
+
44
+ ### UX-IV — The Contract is the Only Server Input (NON-NEGOTIABLE)
45
+ The lane consumes the feature's design contract through a generated API client and nothing else
46
+ from the service lane. It never reads the service design, never assumes a table, a handler or a
47
+ route shape, and an interface it needs but the contract lacks is a contract change — not a local
48
+ workaround.
49
+
50
+ ### UX-V — Every Interaction State is Specified
51
+ Loading, empty, error, partial and offline states are EARS unwanted-behaviour `FR-` requirements
52
+ in the spec and are realised in the router's own state files (`loading`, `error`, `not-found`).
53
+ A state the UI can reach and the spec does not describe is a spec defect routed to specify, never
54
+ invented in the component.
55
+
56
+ ### UX-VI — Caching and Revalidation are Declared, Never Inherited
57
+ Every fetch and route segment states its caching and revalidation policy explicitly. A default
58
+ that happens to work is not a policy, and serving stale content the contract marks authoritative
59
+ is a correctness bug, not a performance trade-off.
60
+
61
+ ### UX-VII — Mutations Flow Through One Path
62
+ Writes go through Server Actions or the generated API client, always revalidate what they
63
+ invalidate, and never fire from an ad-hoc `fetch` in a component. Optimistic updates declare
64
+ their rollback.
65
+
66
+ ### UX-VIII — Client State Carries No Secret
67
+ No credential, token or field the contract marks sensitive enters client state, local storage,
68
+ the URL, or telemetry. What the server can decide, the server decides; the client is not a place
69
+ to enforce an authorization rule.
70
+
71
+ ### UX-IX — Performance Budget is a Gate
72
+ Core Web Vitals thresholds and a per-route JavaScript budget are CI gates. A route that exceeds
73
+ its budget does not ship, and a heavy dependency is a design decision recorded in the delta, not
74
+ an import.
75
+
76
+ ### UX-X — Internationalization is Structural
77
+ User-visible strings come from the locale catalogue; formatting of dates, numbers and units is
78
+ locale-aware at the boundary. No concatenated sentences, and no locale assumption baked into a
79
+ component.
80
+
81
+ ### UX-XI — Frontend Test-First
82
+ Every route, form and interaction state ships with tests: component behaviour, contract-client
83
+ integration against the generated types, and an accessibility assertion per interactive surface.
84
+ Snapshot-only tests do not count as coverage.
85
+
86
+ ## Where Each Principle Is Detailed
87
+
88
+ This file is the thin authority; the enforceable rules live in the corpus beside it. Each
89
+ principle points at the file that details it and the lane command that loads it — so a
90
+ principle can be traced to the phase that applies it, and a rule file can be traced back to
91
+ the principle that ratifies it.
92
+
93
+ | Principle | Detailed in | Loaded by |
94
+ |---|---|---|
95
+ | UX-I Accessibility Floor | [[accessibility-implementation]] | design-ui · implement-ui |
96
+ | UX-II Design System | [[design-system]] · [[component-conventions]] | design-ui · implement-ui |
97
+ | UX-III Server Components by Default | [[component-architecture]] · [[performance-budgets]] | design-ui · implement-ui |
98
+ | UX-IV The Contract is the Only Server Input | [[api-integration.dotnet-webapi]] / [[api-integration.java-spring]] · [[api-client]] | design-ui · implement-ui |
99
+ | UX-V Every Interaction State is Specified | [[error-handling]] · [[routing-navigation]] · [[forms-and-validation]] | design-ui · implement-ui |
100
+ | UX-VI Caching and Revalidation are Declared | [[state-management]] · [[api-integration.<service-stack>]] | design-ui · implement-ui |
101
+ | UX-VII Mutations Flow Through One Path | [[api-client]] · [[forms-and-validation]] | implement-ui |
102
+ | UX-VIII Client State Carries No Secret | [[client-security]] · [[auth-session]] · [[state-management]] | design-ui · implement-ui |
103
+ | UX-IX Performance Budget is a Gate | [[performance-budgets]] | design-ui · implement-ui |
104
+ | UX-X Internationalization is Structural | [[i18n]] | design-ui · implement-ui |
105
+ | UX-XI Frontend Test-First | [[frontend-testing]] · [[observability]] | implement-ui |
106
+
107
+ The cross-lane pairing file is **named for the service stack** it pairs with —
108
+ `api-integration.dotnet-webapi.md`, `api-integration.java-spring.md` — and is mapped through
109
+ the `{{backend_stack}}` placeholder, so exactly one of them loads: the one matching the
110
+ backend lane `.appweaver/stacks.json` declares. A repo with no backend lane loads none, and a
111
+ backend stack with no pairing file authored yet is REPORTED rather than silently paired with
112
+ another stack's assumptions. Elsewhere in this corpus the file is referenced as
113
+ `api-integration.<service-stack>` for that reason.
114
+
115
+ ## Mandatory Frontend Folder Structure
116
+
117
+ The whole layout sits under the lane's root (`web/`) and never adds to the service lane's
118
+ structure.
119
+
120
+ ```
121
+ web/
122
+ app/ # App Router — route segments, layouts, loading/error/not-found
123
+ components/ # design-system compositions, presentational only
124
+ features/<Feature>/ # one folder per spec feature: its components, hooks, actions
125
+ lib/api/ # the GENERATED contract client + typed wrappers (never hand-edited)
126
+ lib/ # cross-feature client utilities
127
+ locales/ # locale catalogues
128
+ tests/ # component, integration and accessibility tests
129
+ ```
130
+
131
+ Generated contract clients land in `lib/api/` and are regenerated, never patched. A feature
132
+ folder mirrors the spec feature name so a slice is traceable in both lanes.
133
+
134
+ ## Conventions, Forbidden Patterns & Quality Gates
135
+
136
+ - **Naming**: components `PascalCase`, hooks `useX`, route segments kebab-case, one exported
137
+ component per file.
138
+ - **State**: server state belongs to the data layer's cache, not to a global store; a global
139
+ store holds only genuinely client-side session state.
140
+ - **Forbidden**: raw `fetch` outside `lib/api/`; business rules in components; `any` on a
141
+ contract type; hand-edited generated code; `dangerouslySetInnerHTML` without a sanitizer;
142
+ disabling the accessibility linter inline.
143
+ - **CI gates**: type-check, lint, accessibility scan, unit + integration tests, and the
144
+ performance budget. All are blocking; a lane that fails any of them fails the build.
145
+
146
+ ## Governance
147
+
148
+ This half versions independently of `technology-constitution.md` and
149
+ `domain-constitution.md` — a design-system upgrade bumps this file alone. The base amendment
150
+ procedure and SemVer policy apply unchanged; the overrides are:
151
+
152
+ - Changing the design system, the accessibility conformance target, or the performance budget
153
+ requires the design authority named for the project in addition to the Principal Engineer.
154
+ - An accessibility waiver is time-boxed, recorded against the `UX-` id it relaxes, and expires.
155
+ - Retiring the frontend lane is a decision to retire this file: unmapping the heading stops the
156
+ half being re-authored, and removing `.appweaver/memory/constitution.ui.md` is a deliberate,
157
+ separate act.
158
+
159
+ ## Ratification Metadata
160
+
161
+ > Carried into `constitution.ui.md` at ratification; the constitution command owns the version
162
+ > bump from there.
163
+
164
+ - **Version:** 1.0.0
165
+ - **Ratified:** `<YYYY-MM-DD>`
166
+ - **Last Amended:** `<YYYY-MM-DD>`
@@ -40,9 +40,9 @@ export const initCommand = new Command('init')
40
40
  if (options.dryRun) {
41
41
  console.log('📋 Dry run - would copy the following:');
42
42
  console.log(` ✓ ${assetsPath}/.aw-spec -> ${targetDir}/.aw-spec`);
43
- console.log(` ✓ ${assetsPath}/docs -> ${targetDir}/docs`);
43
+ // console.log(` ✓ ${assetsPath}/docs -> ${targetDir}/docs`);
44
44
  console.log(` ✓ ${assetsPath}/${agentFolder} -> ${targetDir}/${agentFolder}`);
45
- console.log(` ✓ ${assetsPath}/docs/VerticalSlice -> ${targetDir}/docs/VerticalSlice`);
45
+ // console.log(` ✓ ${assetsPath}/docs/VerticalSlice -> ${targetDir}/docs/VerticalSlice`);
46
46
  return;
47
47
  }
48
48
  // Copy assets