aw-spec-cli 0.1.8 → 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 (257) 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/package.json +1 -1
  257. package/assets/docs/pharma-constitution.my-ref.md +0 -86
@@ -0,0 +1,727 @@
1
+ # =============================================================================
2
+ # aw-spec-constitution (orchestrator) — create/update the SPLIT project constitution
3
+ #
4
+ # Authors up to THREE files. Each ratifies its own MAPPED rule set. The two maps live in
5
+ # the ACTIVE PROJECT (guardrails/projects/<project>/); the files they list live in the
6
+ # shared corpora (guardrails/technology/<stack>/, guardrails/domain/<industry>/), except
7
+ # the three the project's own team authors:
8
+ # .appweaver/memory/constitution.technical.md ← "## /aw-spec-constitution" in
9
+ # tech-rule-bindings.md: the stack corpus's technology-constitution.md + its
10
+ # standard technical rules + the project's service/technical-requirements.md.
11
+ # The technology base's own principle set, domain-agnostic. STANDING input to
12
+ # DESIGN + IMPLEMENT (not specify).
13
+ # .appweaver/memory/constitution.ui.md ← "## /aw-spec-ui-constitution" in
14
+ # tech-rule-bindings.md: the lane corpus's ui-constitution.md + the project's
15
+ # frontend/ui-requirements.md. The FRONTEND LANE's base (UX-*), domain-agnostic
16
+ # too. Standing input to UI-DESIGN + UI-IMPLEMENT. Authored ONLY where a
17
+ # frontend lane exists; otherwise not even created.
18
+ # .appweaver/memory/constitution.domain.md ← "## /aw-spec-constitution" in
19
+ # domain-rule-bindings.md: the industry corpus's domain-constitution.md + its
20
+ # standard industry rules + the project's domain/domain-requirements.md. Its
21
+ # principles RESUME the technical half's numbering from wherever that half ended —
22
+ # the boundary is derived per project, never a fixed number, because a technology
23
+ # base may carry any number of principles.
24
+ # SPECIFY-only + gate checklist; deliberately NOT loaded by design/implement.
25
+ # A deterministic `compose-constitution` then concatenates the authored halves into
26
+ # .appweaver/memory/constitution.md (human/compat view only; the pipeline loads the
27
+ # halves directly).
28
+ #
29
+ # SOURCES ARE MAPPED, NEVER HARDCODED. Each authoring step's `context:` is exactly the
30
+ # half it is filling — no extra document, no hardcoded workspace path, nothing the two
31
+ # maps do not list. Its sources arrive in the sticky standards, which each set's
32
+ # tech-select / domain-select include appends to. Each set is the same shape: the tier's
33
+ # constitution, then the STANDARD rules the mapped corpus shares, then the
34
+ # ONE file the project team supplies (that last one optional — a project that has not
35
+ # authored it ratifies the standard set alone). Changing what a half ratifies is a MAP
36
+ # edit, never a workflow edit.
37
+ #
38
+ # The standards set is CUMULATIVE — load_standards appends and nothing clears it — so a
39
+ # later half also carries the earlier halves' rules: technical sees 1 set, UI sees 2,
40
+ # domain sees 3. That is why the seam is stated as a one-way ordering rule and not as
41
+ # per-step scoping: what matters is that NO DOMAIN file can reach the two domain-free
42
+ # halves, and domain-select running last is what guarantees it. Each `task:` names the
43
+ # set that half may draw on, and the two domain-free halves are told to stand alone
44
+ # rather than cite each other.
45
+ #
46
+ # WHY SPLIT: the old single constitution embedded the domain (principles XVI–XX)
47
+ # and was standing input to every phase — a domain side-channel into design that
48
+ # broke "design's only domain input is the spec." Splitting keeps design/implement
49
+ # domain-free while specify still gets the full picture.
50
+ #
51
+ # The seam is enforced by ORDER: both domain-free halves are authored BEFORE
52
+ # domain-select runs, so their context can never contain a domain file. The domain
53
+ # half is authored after, from the mapped industry corpus's own constitution source. The UI half
54
+ # sits between them for exactly that reason — it is the frontend lane's counterpart
55
+ # to the technical base, not a third tier of governance, so the same seam has to
56
+ # hold for it.
57
+ #
58
+ # WHEN THE UI HALF IS AUTHORED. Three independent signals, any one of which is
59
+ # enough, checked in `ui_probe` + `ui_tech_select` below:
60
+ # 1. RULES — the active project maps `## /aw-spec-ui-constitution`. Authoritative,
61
+ # and the only signal that also SUPPLIES the lane's rules.
62
+ # 2. DECLARATION — a frontend lane in .appweaver/stacks.json.
63
+ # 3. REQUEST — the invocation names a UI stack ("… react …").
64
+ # None of them is REQUIRED, so no ordering constraint is created: a project whose
65
+ # project carries the headings gets its UI half whether or not select-stack ever ran.
66
+ # With none of them present the half is SKIPPED with a warning naming all three
67
+ # fixes — never an error, because a backend-only project is the common case and
68
+ # must behave exactly as it did before the lane model existed.
69
+ #
70
+ # Each authored half is then linted by the deterministic `constitution-verify`
71
+ # SCRIPT (residual [ALL_CAPS] placeholders, body-vs-report version, ISO dates) with
72
+ # a bounded self-correction loop (max 3) — so the whole skill works under every
73
+ # strategy (sdk/sdk-apply/spawn/agent), --checkpoint, or headless.
74
+ #
75
+ # NOT part of the per-feature pipeline. Project-level, run-once / amend-on-change.
76
+ #
77
+ # Launch: /appweaver constitution [strategy] [principles or values…]
78
+ # Action semantics: .appweaver/ORCH-DIALECT.md
79
+ # =============================================================================
80
+
81
+ name: aw-spec-constitution
82
+ description: Create or update the split project constitution — constitution.technical.md (technology base) + constitution.ui.md (the frontend lane's base, only where a lane exists) + constitution.domain.md (active domain addenda), each version-bumped with a Sync Impact Report, then composed into constitution.md. Project-level, run-once/amend — not a per-feature phase.
83
+ version: 2.4.0
84
+ agent_agnostic: true
85
+ dialect: aw-spec.orchestrator/v1
86
+
87
+ inputs:
88
+ user_input:
89
+ description: Principles or values for the project constitution (optional).
90
+ required: false
91
+ bind: USER_INPUT
92
+
93
+ scripts:
94
+ actions:
95
+ sh: .appweaver/scripts/bash/aw-spec-actions.sh
96
+ ps1: .appweaver/scripts/powershell/aw-spec-actions.ps1
97
+
98
+ # Sticky standards seed = the UNIVERSAL always-on rule only (ai-rules). The technology-
99
+ # constitution base the TECHNICAL half ratifies is no longer hardcoded here — it is now
100
+ # CONFIGURATION, loaded per-command from guardrails/projects/<project>/tech-rule-bindings.md
101
+ # under "## /aw-spec-constitution" by the tech-select module (see the tech_select step
102
+ # below). tech_select runs BEFORE the technical half AND before domain-select, so the
103
+ # technical author still sees only the technology base + ai-rules — NO domain file: the
104
+ # seam is preserved. The constitution OUTPUT files (constitution.technical.md /
105
+ # constitution.ui.md / constitution.domain.md) are referred to directly elsewhere,
106
+ # never mapped. (missing skipped)
107
+ standards:
108
+ - { path: .appweaver/ai-rules.md } # kit-resident: the universal operating rules, every flow
109
+
110
+ vars:
111
+ technical_ok: "false" # technical-half validation-loop guard, flipped by constitution-verify
112
+ domain_ok: "false" # domain-half validation-loop guard, flipped by constitution-verify
113
+ ui_ok: "false" # UI-half validation-loop guard, flipped by constitution-verify
114
+ ui_lane: "false" # set by the three-signal probe below; gates the whole UI block
115
+
116
+ workflow:
117
+
118
+ # 0a. WHICH LANES DOES THIS PROJECT HAVE. The declaration in .appweaver/stacks.json is
119
+ # the answer, and it answers for BOTH halves: a half is a lane's standing
120
+ # governance, so a lane the project declined gets no half and no file. That is
121
+ # what makes `(none)` in select-stack a real declaration rather than a shrug.
122
+ #
123
+ # --allow-missing-root because nothing here reads the subtree: constitution
124
+ # ratifies rules, and a greenfield project's source path does not exist until
125
+ # implement creates it. The on-disk check belongs to the phases that read code.
126
+ - id: lane_model
127
+ action: execute_script
128
+ script: { ref: actions }
129
+ subcommand: lane-verify
130
+ args: ["--allow-missing-root", "--command", "/appweaver constitution"]
131
+ outputs:
132
+ - { name: lane_model_ok, from: "$.ok" }
133
+ - { name: lane_model_issues, from: "$.message" }
134
+ - { name: lane_kinds, from: "$.kinds" }
135
+ - { name: be_lane_declared, from: "$.backend_declared" }
136
+ - { name: be_lane_id, from: "$.backend_lane_id" }
137
+ - { name: be_lane_profile, from: "$.backend_profile" }
138
+ - { name: be_lane_root, from: "$.backend_source_path" }
139
+ - { name: fe_lane_declared, from: "$.frontend_declared" }
140
+ - { name: fe_lane_id, from: "$.frontend_lane_id" }
141
+ - { name: fe_lane_profile, from: "$.frontend_profile" }
142
+ - { name: fe_lane_root, from: "$.frontend_source_path" }
143
+
144
+ - id: lane_model_gate
145
+ action: verify_context
146
+ require_true: lane_model_ok
147
+ on_false: stop
148
+ on_false_message: >
149
+ /appweaver constitution cannot run: {{lane_model_issues}}
150
+ Which lanes a project has decides which constitution halves it ratifies, so the
151
+ declaration has to exist before the halves are authored. Run
152
+ /appweaver select-stack first — it is the first command of both the greenfield
153
+ and the brownfield sequence.
154
+
155
+ - id: lane_kinds_gate
156
+ action: verify_context
157
+ require_non_empty: lane_kinds
158
+ on_empty: stop
159
+ on_empty_message: >
160
+ No lane is declared — .appweaver/stacks.json exists but declares neither a service
161
+ nor a UI lane, so there is nothing for a constitution to govern. Re-run
162
+ /appweaver select-stack and declare at least one lane.
163
+
164
+ # 0b. Does the SERVICE lane exist? The technical half is that lane's standing
165
+ # authority — the base loaded by design and implement — so a project that
166
+ # declared no service lane authors no technical half and no service rules.
167
+ # Ordered override rather than a branch: the engine has no boolean expressions,
168
+ # so state the declined case and let the declaration turn it back on.
169
+ # `setup_tech_flag` carries the decision to EVERY setup-constitution call in this
170
+ # workflow, the UI one included: that command creates the always-present halves as
171
+ # a side effect of whatever else it is asked to do, so a later call without the
172
+ # flag silently recreates the half an earlier call was told to skip.
173
+ - id: svc_lane_absent
174
+ action: set
175
+ vars: { svc_lane: "false", setup_tech_flag: "--no-technical" }
176
+ - id: svc_lane_declared
177
+ action: set
178
+ condition: "{{be_lane_declared}}"
179
+ vars: { svc_lane: "true", setup_tech_flag: "" }
180
+
181
+ # 0. TECHNICAL rule files → sticky standards (configuration, not hardcoded). tech-select
182
+ # reads guardrails/projects/<project>/tech-rule-bindings.md under "## /aw-spec-constitution"
183
+ # and loads the technology-constitution base into the sticky standards the TECHNICAL
184
+ # half ratifies. Placed FIRST — before the technical half AND before domain-select — so
185
+ # the technical author sees only technical files: the seam that keeps it domain-free is
186
+ # preserved. No blocking gate: an unconfigured project soft-continues (ai-rules seed only).
187
+ - id: tech_select
188
+ action: include
189
+ module: .appweaver/orchestrator/modules/tech-select.orch.yaml
190
+ with: { command: aw-spec-constitution }
191
+
192
+ # 1. Ensure the halves this project's LANES call for exist (copy each template in if
193
+ # missing). Rewrite-in-place only — never creates a second template. The domain
194
+ # half is always created: domain is not a lane, it addends whichever halves the
195
+ # project has. The UI half is created on demand at step 11, and the technical half
196
+ # is skipped outright where no service lane was declared — an unauthored template
197
+ # left in memory/ is indistinguishable from a half somebody forgot to fill in.
198
+ # Composed constitution.md is produced later by compose-constitution.
199
+ - id: setup_constitution
200
+ action: execute_script
201
+ script: { ref: actions }
202
+ subcommand: setup-constitution
203
+ args: ["{{setup_tech_flag}}"]
204
+ outputs:
205
+ - { name: constitution_technical_file, from: "$.constitution_technical_file" }
206
+ - { name: constitution_domain_file, from: "$.constitution_domain_file" }
207
+ - { name: technical_created, from: "$.technical_created" }
208
+ - { name: domain_created, from: "$.domain_created" }
209
+
210
+ # 1b. No service lane ⇒ nothing for the technical validation loop to check, so its
211
+ # guard is satisfied rather than left at its "not yet verified" default. A false
212
+ # here would report a half that was deliberately not authored as one that failed
213
+ # to validate.
214
+ - id: technical_skipped
215
+ action: set
216
+ condition: "{{svc_lane}} == false"
217
+ vars: { technical_ok: "true" }
218
+
219
+ - id: svc_lane_warning
220
+ action: verify_context
221
+ require_true: svc_lane
222
+ on_false: continue
223
+ on_false_message: >
224
+ No service lane in .appweaver/stacks.json — skipping the TECHNICAL constitution half
225
+ (constitution.technical.md is not created). This is the correct outcome for a
226
+ UI-only project: the technical half is the service lane's standing authority, read
227
+ by design and implement, and neither runs here. The domain half opens the
228
+ roman-numeral sequence at I instead of continuing one. To author it, run
229
+ /appweaver select-stack and declare a backend stack, then re-run.
230
+
231
+ # 2. Pre-execution hooks: resolve (script) then dispatch (invoking agent).
232
+ - id: resolve_pre_hooks
233
+ action: execute_script
234
+ script: { ref: actions }
235
+ subcommand: resolve-hooks
236
+ args: ["--phase", "before_constitution"]
237
+ outputs:
238
+ - { name: before_hooks, from: "$.hooks" }
239
+ - id: dispatch_pre_hooks
240
+ action: dispatch_hooks
241
+ hooks_from_variable: before_hooks
242
+
243
+ # ── TECHNICAL HALF ─────────────────────────────────────────────────────────
244
+ # Authored FIRST, while the sticky set holds only the technology base + ai-rules
245
+ # (domain-select has not run yet). This ordering is what guarantees the technical
246
+ # constitution is domain-free.
247
+
248
+ # 3. Context: the technical half being filled / amended, and nothing else. Its
249
+ # sources arrive as MAPPED rule files in the sticky standards from step 0. Every
250
+ # half is authored this way: the target file plus its mapped set, never a doc the
251
+ # map does not list.
252
+ - id: gen_technical_ctx
253
+ action: build_context
254
+ condition: "{{svc_lane}} == true"
255
+ context:
256
+ - { path: "{{constitution_technical_file}}" }
257
+
258
+ # 4. Author the TECHNICAL constitution (rewrite-in-place).
259
+ - id: gen_technical
260
+ action: agent_author
261
+ condition: "{{svc_lane}} == true"
262
+ output_target: { type: file, path: "{{constitution_technical_file}}" }
263
+ task: |
264
+ Update the TECHNICAL project constitution (the target file in context). It is
265
+ a TEMPLATE with [ALL_CAPS] placeholder tokens. This is the domain-AGNOSTIC half.
266
+ Principles/values supplied by the user: {{USER_INPUT}}
267
+ Steps:
268
+ - Fill EVERY placeholder with concrete text; leave no unexplained [BRACKET]
269
+ tokens (justify any intentionally deferred as TODO(<FIELD>): reason).
270
+ - Derive values from the technical rule files in the standards — the set the active
271
+ project maps for this command: its technology base, the standard technical rules, and
272
+ the project team's own technical-requirements — plus the user input, ai-rules and
273
+ repo context. Where the project file and a standard rule disagree, the project file
274
+ is the DEVIATION and MUST be ratified as one, naming the rule it departs from and
275
+ who approved it. Do NOT invent principles, and do NOT reach for a rule file the map
276
+ did not supply. If NO technical rule file was loaded, say so in the Sync Impact
277
+ Report and keep the principles to what the user input and repo context actually
278
+ support: a thin, honest half a later run can extend is correct, an invented one is
279
+ not.
280
+ - Author ONLY technology-base principles — the base's FULL set, as many as it
281
+ defines and no more — plus base folder structure,
282
+ base conventions/AI rules, and base governance. The count is whatever the mapped
283
+ technology base carries: do not pad the list to reach a familiar length, and do
284
+ not stop short of its last principle. Number them consecutively from I, and note
285
+ the final number in the Sync Impact Report — the domain half resumes from there.
286
+ Do NOT add any domain-specific
287
+ principle, identifier, terminology, regulatory, or interoperability rule — those
288
+ belong to the paired constitution.domain.md and MUST NOT appear here.
289
+ - Bump CONSTITUTION_VERSION by semver (MAJOR incompatible; MINOR new/expanded;
290
+ PATCH clarifications). This half versions independently of the domain half.
291
+ - Dates ISO YYYY-MM-DD: RATIFICATION_DATE = original adoption (TODO if unknown);
292
+ LAST_AMENDED_DATE = today when changed.
293
+ - Preserve heading hierarchy exactly. Principles declarative and testable.
294
+ - PREPEND a "Sync Impact Report" as an HTML comment at the very top: version
295
+ old→new, modified/added/removed principles, dependent artifacts (✅/⚠) + TODOs.
296
+ Return the complete updated technical constitution content only.
297
+
298
+ # 5. Deterministic validation loop for the technical half (max 3 patch passes).
299
+ - id: technical_validation_loop
300
+ action: loop
301
+ condition: "{{svc_lane}} == true"
302
+ while: "{{technical_ok}} != true"
303
+ max_iterations: 3
304
+ steps:
305
+ - id: tech_lint
306
+ action: execute_script
307
+ script: { ref: actions }
308
+ subcommand: constitution-verify
309
+ args: ["--file", "{{constitution_technical_file}}"]
310
+ outputs:
311
+ - { name: technical_ok, from: "$.ok" }
312
+ - { name: technical_issues, from: "$.issues" }
313
+ - id: tech_lint_break
314
+ action: break
315
+ condition: "{{technical_ok}} == true"
316
+ - id: patch_technical
317
+ action: agent_author
318
+ context: ["{{constitution_technical_file}}"]
319
+ include_standards: false # rewrite-in-place: only the technical half
320
+ output_target: { type: file, path: "{{constitution_technical_file}}" }
321
+ task: |
322
+ Fix these mechanical defects in the technical constitution (target file in
323
+ context), changing NOTHING else — preserve every principle, the heading
324
+ hierarchy, and the Sync Impact Report. Fill any listed [ALL_CAPS] placeholder
325
+ with concrete text (or a justified TODO(<FIELD>): reason); make the body's
326
+ version line AGREE with the Sync Impact Report's new version; ISO YYYY-MM-DD dates.
327
+ Defects: {{technical_issues}}
328
+ Return the complete updated technical constitution content only.
329
+
330
+ # ── UI HALF (frontend lane only) ───────────────────────────────────────────
331
+ # Placed HERE deliberately: AFTER the technical half, so the lane's rule files
332
+ # cannot leak into it, and BEFORE domain-select, so no domain file can leak into
333
+ # this one. The UI half is the frontend lane's counterpart to the technical base
334
+ # and has to be domain-free for the same reason — domain reaches the UI lane
335
+ # through the spec, exactly as it reaches the service lane.
336
+
337
+ # 6. Clear the shared module's mode before re-entering it. tech-select keeps its
338
+ # tg_* vars in the caller's scope, so a stale `all` from the step-0 include
339
+ # would otherwise survive into a run where no UI selection box ever appears.
340
+ - id: ui_tech_reset
341
+ action: set
342
+ vars: { tg_mode: "" }
343
+
344
+ # 7. THE UI LANE'S RULES. The project's `## /aw-spec-ui-constitution` heading
345
+ # supplies what governs the lane; empty candidates ⇒ tech-select soft-continues
346
+ # and nothing is loaded, the same no-map path an unconfigured project takes.
347
+ #
348
+ # It no longer decides that the lane EXISTS. That question was answered by three
349
+ # OR'd heuristics — this heading, a frontend lane in stacks.json, and a UI stack
350
+ # named in the request — and a heuristic OR can only ever turn the half ON. It had
351
+ # no way to express "this project has no UI", so a stale heading or the word
352
+ # "react" in a request authored a ratified governance file for a lane that does not
353
+ # exist. The declaration answers in both directions, which is why it is now the
354
+ # only signal read: a project that answered `(none)` in select-stack has answered,
355
+ # and it is the same file build, implement and onboard are held to.
356
+ - id: ui_tech_select
357
+ action: include
358
+ module: .appweaver/orchestrator/modules/tech-select.orch.yaml
359
+ with: { command: aw-spec-ui-constitution }
360
+ - id: ui_rule_signal
361
+ action: set
362
+ vars: { ui_rule_files: "{{tg_candidates}}" }
363
+
364
+ # 8. The lane, from the declaration. Ordered override rather than a branch: the
365
+ # engine has no conditional binding, so state the declined case and let a declared
366
+ # frontend lane turn it on.
367
+ - id: ui_lane_absent
368
+ action: set
369
+ vars:
370
+ ui_lane: "false"
371
+ ui_stack: ""
372
+ ui_evidence: ""
373
+ - id: ui_lane_declared
374
+ action: set
375
+ condition: "{{fe_lane_declared}}"
376
+ vars:
377
+ ui_lane: "true"
378
+ ui_stack: "{{fe_lane_profile}}"
379
+ ui_evidence: "lane '{{fe_lane_id}}' ({{fe_lane_profile}}) is declared in .appweaver/stacks.json, owning the source path {{fe_lane_root}}"
380
+
381
+ # 9. A mapped UI rule set with no lane to govern. Not fatal and not a reason to
382
+ # author the half — the declaration decides that — but worth saying out loud,
383
+ # because the two most likely causes have opposite fixes: a lane that was retired
384
+ # and left its mapping behind, or a lane somebody forgot to declare.
385
+ - id: ui_rules_orphan_warning
386
+ action: verify_context
387
+ require_true: ui_lane
388
+ on_false: continue
389
+ on_false_message: >
390
+ The active project maps ## /aw-spec-ui-constitution to {{ui_rule_files}}, but no
391
+ frontend lane is declared in .appweaver/stacks.json — those rules govern nothing and
392
+ the UI half is NOT authored. Either run /appweaver select-stack and declare the
393
+ UI lane, or drop the mapping if the lane was retired.
394
+ condition: "{{ui_rule_files}}"
395
+
396
+ # 10. No UI lane ⇒ WARN and skip. Never an error: a backend-only project is the
397
+ # common case, and no UI half is authored and no file created. Gated on the empty
398
+ # evidence string rather than on ui_lane, because require_true logs "gate failed"
399
+ # and this is a soft path, not a failure.
400
+ - id: ui_lane_warning
401
+ action: verify_context
402
+ require_non_empty: ui_evidence
403
+ on_empty: continue
404
+ on_empty_message: >
405
+ No frontend lane in .appweaver/stacks.json — skipping the UI constitution half
406
+ (constitution.ui.md is not created). This is the expected path for a backend-only
407
+ project. To author it, run `/appweaver select-stack`, pick a UI stack and give
408
+ it a source path, then re-run `/appweaver constitution`. Mapping
409
+ `## /aw-spec-ui-constitution` in guardrails/projects/<project>/tech-rule-bindings.md
410
+ supplies the rules that half ratifies, but no longer creates the lane on its own —
411
+ a lane exists because the project declared it.
412
+
413
+ # 11. Create the UI half from its template — on demand, unlike the other two.
414
+ # Its ABSENCE is meaningful, so a project with no lane never gets the file.
415
+ - id: setup_ui_constitution
416
+ action: execute_script
417
+ condition: "{{ui_lane}} == true"
418
+ script: { ref: actions }
419
+ subcommand: setup-constitution
420
+ args: ["--ui", "{{setup_tech_flag}}"]
421
+ outputs:
422
+ - { name: constitution_ui_file, from: "$.constitution_ui_file" }
423
+ - { name: ui_created, from: "$.ui_created" }
424
+
425
+ # 12. Context for the UI half: the file being filled/amended, and nothing else. The
426
+ # lane's UI rule set arrives as mapped rule files in the sticky standards from
427
+ # step 7 — including its declared lane, stack and root, so the Declared Lane
428
+ # section is authored from the mapping rather than inferred.
429
+ - id: gen_ui_ctx
430
+ action: build_context
431
+ condition: "{{ui_lane}} == true"
432
+ context:
433
+ - { path: "{{constitution_ui_file}}" }
434
+
435
+ # 13. Author the UI constitution (rewrite-in-place).
436
+ - id: gen_ui
437
+ action: agent_author
438
+ condition: "{{ui_lane}} == true"
439
+ output_target: { type: file, path: "{{constitution_ui_file}}" }
440
+ task: |
441
+ Update the USER EXPERIENCE constitution — the FRONTEND LANE's half (the target
442
+ file in context). It is a TEMPLATE with [ALL_CAPS] placeholder tokens. This half
443
+ is domain-AGNOSTIC, like the technical base it runs parallel to.
444
+ Principles/values supplied by the user: {{USER_INPUT}}
445
+ Why this lane was detected: {{ui_evidence}}
446
+ Declared UI stack (may be empty): {{ui_stack}}
447
+ Steps:
448
+ - Fill EVERY placeholder with concrete text; leave no unexplained [BRACKET]
449
+ tokens (justify any intentionally deferred as TODO(<FIELD>): reason).
450
+ - Derive values from the UI rule files in the standards — the set the active project
451
+ maps for this command: its frontend base and the project team's own
452
+ ui-requirements — plus the user input, the declared stack and repo context. Where
453
+ the project file and a standard rule disagree, the project file is the DEVIATION
454
+ and MUST be ratified as one, naming the principle it departs from and who approved
455
+ it. The technical rule files are also in the standards because the set is
456
+ cumulative; they belong to the OTHER lane and are NOT a source for this half. Do
457
+ NOT invent principles. If NO UI rule file was loaded, say so in the Sync Impact
458
+ Report and keep the principles to what the user input and the declared stack
459
+ actually support: a thin, honest half that a later run can extend is correct, an
460
+ invented one is not.
461
+ - Number the principles as a UX-* series (UX-I, UX-II, …). Do NOT continue the
462
+ technical half's numbering or the domain half's — this half is parallel to
463
+ the technical base, not a continuation of it, and its series is therefore
464
+ unaffected by how many principles that base carries.
465
+ - Author ONLY experience/frontend-lane material: accessibility, design system,
466
+ interaction states, client data + cache policy, performance budget,
467
+ internationalization, the lane's folder structure under its own root, and
468
+ the lane's quality gates. This half stands ALONE as the frontend lane's base:
469
+ it neither restates the service lane's principles nor cites them by number.
470
+ Add NO domain-specific principle, identifier, terminology or regulatory rule
471
+ — those belong to constitution.domain.md.
472
+ - Keep every path under the lane's own root. This half never adds to the
473
+ service lane's folder structure.
474
+ - Bump CONSTITUTION_VERSION by semver (MAJOR incompatible; MINOR new/expanded;
475
+ PATCH clarifications). This half versions independently of the other two.
476
+ - Dates ISO YYYY-MM-DD: RATIFICATION_DATE = original adoption (TODO if unknown);
477
+ LAST_AMENDED_DATE = today when changed.
478
+ - Preserve heading hierarchy exactly. Principles declarative and testable.
479
+ - PREPEND a "Sync Impact Report" as an HTML comment at the very top: version
480
+ old→new, modified/added/removed principles, dependent artifacts (✅/⚠) + TODOs.
481
+ Return the complete updated UI constitution content only.
482
+
483
+ # 14. Deterministic validation loop for the UI half (max 3 patch passes).
484
+ - id: ui_validation_loop
485
+ action: loop
486
+ condition: "{{ui_lane}} == true"
487
+ while: "{{ui_ok}} != true"
488
+ max_iterations: 3
489
+ steps:
490
+ - id: ui_lint
491
+ action: execute_script
492
+ script: { ref: actions }
493
+ subcommand: constitution-verify
494
+ args: ["--file", "{{constitution_ui_file}}"]
495
+ outputs:
496
+ - { name: ui_ok, from: "$.ok" }
497
+ - { name: ui_issues, from: "$.issues" }
498
+ - id: ui_lint_break
499
+ action: break
500
+ condition: "{{ui_ok}} == true"
501
+ - id: patch_ui
502
+ action: agent_author
503
+ context: ["{{constitution_ui_file}}"]
504
+ include_standards: false # rewrite-in-place: only the UI half
505
+ output_target: { type: file, path: "{{constitution_ui_file}}" }
506
+ task: |
507
+ Fix these mechanical defects in the UI constitution (target file in context),
508
+ changing NOTHING else — preserve every principle, the UX-* numbering, the
509
+ heading hierarchy, and the Sync Impact Report. Fill any listed [ALL_CAPS]
510
+ placeholder with concrete text (or a justified TODO(<FIELD>): reason); make the
511
+ body's version line AGREE with the Sync Impact Report's new version;
512
+ ISO YYYY-MM-DD dates.
513
+ Defects: {{ui_issues}}
514
+ Return the complete updated UI constitution content only.
515
+
516
+ # ── DOMAIN HALF ────────────────────────────────────────────────────────────
517
+ # 15. Resolve the active domain + load its rule files into the sticky set (D3).
518
+ # Gate Continue/Exit when no domain/domain-rule-bindings; then Select all/subset/none.
519
+ # Runs AFTER the technical half is done, so it cannot leak into it.
520
+ - id: domain_select
521
+ action: include
522
+ module: .appweaver/orchestrator/modules/domain-select.orch.yaml
523
+ with: { command: aw-spec-constitution }
524
+
525
+ # 16. Context for the domain half: the file being filled/amended, and nothing else.
526
+ # Its sources are the project's domain constitution set, which domain-select has just
527
+ # put into the sticky standards. Skipped when no active domain.
528
+ - id: gen_domain_ctx
529
+ action: build_context
530
+ condition: "{{dg_rulemap_exists}} == true"
531
+ context:
532
+ - { path: "{{constitution_domain_file}}" }
533
+ # The authored technical half, for its NUMBERING only. The domain principles
534
+ # resume from the number after its last one, and that number is a property of
535
+ # the mapped technology base — a base with eight principles ends at VIII, one
536
+ # with twenty ends at XX — so it cannot be stated as a constant here. Optional:
537
+ # a run whose technical half was skipped still authors the domain half, and the
538
+ # task text says what to do when this file is absent. It is NOT a content source;
539
+ # the domain half never restates a technical principle.
540
+ - { path: "{{constitution_technical_file}}", optional: true }
541
+
542
+ # 17. Author the DOMAIN addenda (rewrite-in-place). Only when a domain is active.
543
+ - id: gen_domain
544
+ action: agent_author
545
+ condition: "{{dg_rulemap_exists}} == true"
546
+ output_target: { type: file, path: "{{constitution_domain_file}}" }
547
+ task: |
548
+ Update the DOMAIN ADDENDA constitution for domain '{{domain}}' (the target file
549
+ in context). It is a TEMPLATE with [ALL_CAPS] placeholder tokens. This half carries
550
+ ONLY domain-specific material. Principles/values supplied by the user: {{USER_INPUT}}
551
+ Steps:
552
+ - Fill EVERY placeholder with concrete text; leave no unexplained [BRACKET] tokens
553
+ (justify deferrals as TODO(<FIELD>): reason). NO residual placeholder may remain.
554
+ - Derive values from the domain rule files in the standards — the set the active project
555
+ maps for this command: its domain constitution, the standard industry rules, and the
556
+ project team's own domain-requirements (optional; a project may not have authored it).
557
+ Where the project file and a standard rule disagree, the project file is the DEVIATION
558
+ and MUST be ratified as one, naming the rule it departs from and who approved it. The
559
+ technical and frontend rule files are also in the standards because the set is
560
+ cumulative; they are the OTHER halves' sources and NOT a source for this one. Do NOT
561
+ invent principles, and do NOT reach for a rule file the map did not supply. If NO
562
+ domain rule file was loaded, say so in the Sync Impact Report and keep the principles
563
+ to what the user input actually supports.
564
+ - Author ONLY the domain layer: the adopted modelling standard, the domain
565
+ principles, domain folder additions, regulatory posture & security addenda, and
566
+ domain governance overrides. For each domain principle, state which technical
567
+ principle it EXTENDS. Do NOT restate the technical half's principles or the base
568
+ governance — reference them. Where constitution.technical.md is absent from
569
+ context the project declared no service lane and there is no technical half to
570
+ extend: state each principle on its own terms and say so in the Sync Impact
571
+ Report, rather than naming a principle that does not exist.
572
+ - ADOPTED MODELLING STANDARD: name the methodology the technical half actually
573
+ mandates and cite that principle BY ITS ACTUAL NUMERAL, read from
574
+ constitution.technical.md in context. The numeral is a property of THIS project's
575
+ technology base — never a fixed value carried over from another constitution. If
576
+ the technical half mandates no modelling methodology — or is absent because the
577
+ project declared no service lane — say so plainly rather than supplying one;
578
+ specify loads this file and not the technical half, so whatever this section
579
+ claims is what specify will treat as ratified.
580
+ - NUMBER the domain principles by RESUMING the technical half's series. Read
581
+ constitution.technical.md in context, find its LAST principle number, and start
582
+ at the next one: a technical half ending at XII starts the domain at XIII, one
583
+ ending at XX starts it at XXI. Do NOT assume XVI — that is only where the
584
+ shipped sample corpora happen to land, and a project's technology base may define
585
+ any number of principles. Numbering must run unbroken across the two halves:
586
+ no gap, no restart, and NO number used by both. If constitution.technical.md is
587
+ absent from context, say so in the Sync Impact Report and start the domain
588
+ principles at I, so the gap is visible rather than silently guessed.
589
+ - Bump CONSTITUTION_VERSION by semver; this half versions independently of the
590
+ technical half. Dates ISO YYYY-MM-DD.
591
+ - Preserve heading hierarchy exactly. PREPEND a "Sync Impact Report" HTML comment:
592
+ version old→new, changed domain principles, dependent artifacts (✅/⚠) + TODOs.
593
+ Return the complete updated domain addenda content only.
594
+
595
+ # 18. Deterministic validation loop for the domain half (max 3). Skipped if no domain.
596
+ - id: domain_validation_loop
597
+ action: loop
598
+ condition: "{{dg_rulemap_exists}} == true"
599
+ while: "{{domain_ok}} != true"
600
+ max_iterations: 3
601
+ steps:
602
+ - id: dom_lint
603
+ action: execute_script
604
+ script: { ref: actions }
605
+ subcommand: constitution-verify
606
+ args: ["--file", "{{constitution_domain_file}}"]
607
+ outputs:
608
+ - { name: domain_ok, from: "$.ok" }
609
+ - { name: domain_issues, from: "$.issues" }
610
+ - id: dom_lint_break
611
+ action: break
612
+ condition: "{{domain_ok}} == true"
613
+ - id: patch_domain
614
+ action: agent_author
615
+ context: ["{{constitution_domain_file}}"]
616
+ include_standards: false # rewrite-in-place: only the domain half
617
+ output_target: { type: file, path: "{{constitution_domain_file}}" }
618
+ task: |
619
+ Fix these mechanical defects in the domain addenda constitution (target file in
620
+ context), changing NOTHING else — preserve every principle, the heading hierarchy,
621
+ and the Sync Impact Report. Fill any listed [ALL_CAPS] placeholder (or a justified
622
+ TODO(<FIELD>): reason); make the body version AGREE with the Sync Impact Report;
623
+ ISO YYYY-MM-DD dates.
624
+ Defects: {{domain_issues}}
625
+ Return the complete updated domain addenda content only.
626
+
627
+ # 19. Compose the authored halves into the human/compat constitution.md (deterministic).
628
+ # Order technical → domain → ui. Any half that is missing or still an unauthored
629
+ # template is skipped, so this needs no conditions of its own.
630
+ - id: compose_constitution
631
+ action: execute_script
632
+ script: { ref: actions }
633
+ subcommand: compose-constitution
634
+ outputs:
635
+ - { name: composed_file, from: "$.composed_file" }
636
+ - { name: domain_included, from: "$.domain_included" }
637
+ - { name: ui_included, from: "$.ui_included" }
638
+ - { name: numbering_ok, from: "$.numbering_ok" }
639
+ - { name: numbering_issues, from: "$.issues" }
640
+ - { name: technical_last, from: "$.technical_last" }
641
+ - { name: domain_first, from: "$.domain_first" }
642
+
643
+ # 19b. Numbering gate. Composition is the only place both roman-numeral halves are
644
+ # read together, so it is where a collision between them surfaces. Announce and
645
+ # continue: the halves are authored and the composed view shows the clash, which
646
+ # is what the reader needs to fix it — deleting that would help nobody.
647
+ # Ordered override: the var holds "ok" unless the check reported a problem,
648
+ # because require_non_empty reports on EMPTY.
649
+ - id: numbering_default
650
+ action: set
651
+ vars: { numbering_gate: "ok" }
652
+ - id: numbering_detect
653
+ action: set
654
+ condition: "{{numbering_ok}} == false"
655
+ vars: { numbering_gate: "" }
656
+ - id: numbering_warning
657
+ action: verify_context
658
+ require_non_empty: numbering_gate
659
+ on_empty: continue
660
+ on_empty_message: >
661
+ Principle numbering does not run cleanly across the halves: {{numbering_issues}}
662
+ (technical half ends at {{technical_last}}, domain half starts at {{domain_first}}).
663
+ The domain half must resume at the number FOLLOWING the technical half's last
664
+ principle — that boundary is a property of the mapped technology base, not a fixed
665
+ value, so a base of any length is legal and only the continuation matters. Renumber
666
+ the domain half in .appweaver/memory/constitution.domain.md and re-run; the composed
667
+ constitution.md was still written so the clash is visible.
668
+
669
+ # 20. A UI half composed in on a run that found no lane means the lane was retired
670
+ # after the half was authored. Warn, and change nothing: a ratified governance
671
+ # file is never deleted automatically, and retiring a lane is a decision.
672
+ # Ordered override again, inverted — the var holds "ok" except on the stale path,
673
+ # because require_non_empty reports on EMPTY.
674
+ - id: ui_stale_default
675
+ action: set
676
+ vars: { ui_stale_ok: "ok" }
677
+ - id: ui_stale_detect
678
+ action: set
679
+ condition: "{{ui_included}} == true"
680
+ vars: { ui_stale_ok: "" }
681
+ - id: ui_stale_clear
682
+ action: set
683
+ condition: "{{ui_lane}} == true"
684
+ vars: { ui_stale_ok: "ok" }
685
+ - id: ui_stale_warning
686
+ action: verify_context
687
+ require_non_empty: ui_stale_ok
688
+ on_empty: continue
689
+ on_empty_message: >
690
+ .appweaver/memory/constitution.ui.md exists and was composed into constitution.md,
691
+ but this run found no frontend lane — the lane was most likely retired after the
692
+ half was authored. Nothing was deleted: a ratified governance file is never
693
+ removed automatically. Delete that file by hand if the lane is gone for good and
694
+ re-run; otherwise restore the lane's signal.
695
+
696
+ # 21. Post-execution hooks.
697
+ - id: resolve_post_hooks
698
+ action: execute_script
699
+ script: { ref: actions }
700
+ subcommand: resolve-hooks
701
+ args: ["--phase", "after_constitution"]
702
+ outputs:
703
+ - { name: after_hooks, from: "$.hooks" }
704
+ - id: dispatch_post_hooks
705
+ action: dispatch_hooks
706
+ hooks_from_variable: after_hooks
707
+
708
+ outputs:
709
+ constitution_technical_file: "{{constitution_technical_file}}"
710
+ constitution_domain_file: "{{constitution_domain_file}}"
711
+ constitution_ui_file: "{{constitution_ui_file}}"
712
+ composed_file: "{{composed_file}}"
713
+ domain_included: "{{domain_included}}"
714
+ ui_included: "{{ui_included}}"
715
+ technical_validation_ok: "{{technical_ok}}"
716
+ technical_validation_issues: "{{technical_issues}}"
717
+ domain_validation_ok: "{{domain_ok}}"
718
+ domain_validation_issues: "{{domain_issues}}"
719
+ service_lane: "{{svc_lane}}"
720
+ service_lane_declared: "{{be_lane_id}} ({{be_lane_profile}}) at {{be_lane_root}}"
721
+ ui_lane: "{{ui_lane}}"
722
+ ui_lane_evidence: "{{ui_evidence}}"
723
+ ui_rule_files: "{{ui_rule_files}}"
724
+ ui_validation_ok: "{{ui_ok}}"
725
+ ui_validation_issues: "{{ui_issues}}"
726
+ note: "Split constitution authored, one half per LANE the project declared in .appweaver/stacks.json. service_lane / ui_lane report which lanes were found there, and the declaration is the ONLY signal read: a half is a lane's standing governance, so a lane declared `(none)` in select-stack gets no half AND no file. constitution.technical.md is the service lane's base (standing input to design + implement); constitution.ui.md is the UI lane's UX-* base (standing input to ui-design + ui-implement); constitution.domain.md is the domain addenda (standing input to specify + a gate checklist), and it is always authored because domain is not a lane — it addends whichever halves exist. All are composed into constitution.md, which now tolerates an absent technical half: a UI-only project's domain half opens the roman-numeral sequence at I instead of continuing one, and numbering_checked reports false because that check has no subject rather than because it silently passed. Mapping ## /aw-spec-ui-constitution supplies the rules the UI half ratifies but no longer creates the lane on its own — a mapped rule set with no declared lane produces a warning naming both fixes. ui_lane false with ui_included true means a lane was retired after its half was authored: the file is left alone and the log says so, because a ratified governance file is never deleted automatically. If a validation_ok is false, the matching validation_issues lists what still needs a manual touch. See each half's Sync Impact Report for its version bump. Suggested commit: 'docs: amend split constitution'."
727
+ next: "Loaded per concern — /appweaver specify loads constitution.domain.md; design + implement load constitution.technical.md; ui-design + ui-implement load constitution.ui.md. Re-run /appweaver constitution to amend, including to pick up a lane declared or dropped after this run — re-run /appweaver select-stack first to change which lanes exist."