aw-spec-cli 0.1.8 → 0.1.10

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,1822 @@
1
+ # =============================================================================
2
+ # aw-spec-onboard (orchestrator) — the entry step of the Brownfield DEVELOPMENT flow
3
+ #
4
+ # Onboard an EXISTING codebase into aw-spec so it can be DEVELOPED (evolved, not
5
+ # migrated) governed exactly like greenfield and as lightly as OpenSpec. Runs ONCE
6
+ # per repo, over the WHOLE codebase (project-level, not per-slice). It does two
7
+ # things, both from a single deterministic whole-repo scan — no slice is adopted yet:
8
+ #
9
+ # 1. FEATURE MAP — a HIGH-LEVEL OKF discovery index of the features/aggregates the
10
+ # code contains (folders/concepts + a bounded-context map + the tech stack). It
11
+ # is a shallow map to pick from, NOT a deep reverse — the deep per-feature
12
+ # reverse (spec.md + design.md) is /appweaver adopt, done just-in-time when
13
+ # you are about to develop that feature.
14
+ #
15
+ # 2. GOVERNANCE SCAFFOLD — the PROJECT-level governing tier, established once from
16
+ # the whole-repo vantage so forward development is consistent from the first
17
+ # change: the split constitution (technical + domain), the guardrails/projects/
18
+ # brf-<domain>/domain/ rule-file set (+ domain-rule-bindings), the domain charter
19
+ # that set is headed by, and the activated domain. Because nothing is adopted yet, this tier is
20
+ # a PROVISIONAL scaffold evidenced by the SCAN (project identity + bounded-context
21
+ # map are firm; principles/rules are marked provisional). adopt then RECONCILES
22
+ # each with the slice's own evidence (BR-/CN-/DC-/IC- ids) when that feature is
23
+ # developed — the "created here, updated when taking each slice" contract.
24
+ #
25
+ # ONBOARD → adopt <Feature> (JIT) → specify → design → analyze-delta-design → implement-delta → build → finalize-delta → analyze-slice → close-delta ← you are here
26
+ #
27
+ # Establishing the PROJECT-scoped constitution here (whole-repo vantage) — not from a
28
+ # single adopted slice — is deliberate: it keeps governance project-scoped from day
29
+ # one and stops a first-adopted feature from biasing it (adopt only ADDS evidence).
30
+ #
31
+ # This is the DEVELOPMENT flow — there is NO migration content: no migration backlog,
32
+ # no seams/adopt-order, no strangler, no parity, no cutover. Modernization/migration
33
+ # is a separate, later phase. Reuses proven machinery unchanged (the scan, the
34
+ # constitution scripts, the neutral rev-templates skeletons); the new agent PROMPTS read
35
+ # the SCAN + representative SOURCE, not adopted docs. It also REVERSE-ENGINEERS the repo's
36
+ # own technical structure into a project-specific design + delta-design template pair
37
+ # (installed as the project template overrides), so forward development follows the
38
+ # as-built architecture, not the greenfield four-layer layout.
39
+ #
40
+ # ONE ORACLE — THE CODE. Every artifact this workflow writes is evidenced from source, and
41
+ # the discipline is structural rather than instructional: no greenfield constitution, rule
42
+ # file or document template is ever placed in a step's context. Where a shape reference is
43
+ # needed, the step reads a NEUTRAL SKELETON from rev-templates/ that carries the format and
44
+ # deliberately carries no principle set, no rule, no layering and no technology. That is
45
+ # why "do not copy the exemplar" never has to be trusted — there is no exemplar present.
46
+ #
47
+ # CODE-DERIVED RULE SETS + MAPS (both tiers): onboard authors, from the code ALONE
48
+ # (never a greenfield rule file), BOTH the DOMAIN rule-file set
49
+ # (guardrails/projects/brf-<domain>/domain/*.domain.md +
50
+ # domain-rule-bindings.md) AND the TECHNICAL rule-file set (guardrails/projects/brf-<domain>/service/*.md
51
+ # + tech-rule-bindings.md), then WIRES each per-workflow. This is what makes the WHOLE
52
+ # forward pipeline AND adopt govern against THIS codebase's rules — resolve-domain /
53
+ # resolve-tech read the activated brf-<domain>'s maps, so no workflow ever falls back to a
54
+ # rule file from another project. Both sets are evidenced-only (a rule
55
+ # is written only for a concern the code exhibits) and may be seeded with an optional list
56
+ # of concerns to look for (onboard still DECIDES presence + implementation from the code).
57
+ # The technical set carries ONE file for /specify — service/domain-modelling.md, the AS-BUILT
58
+ # modelling METHODOLOGY (how this code expresses a domain model: what marks an aggregate
59
+ # root, entity vs value object, where invariants live, the context boundary). It is the
60
+ # code-derived analog of the greenfield corpus's technology/<stack>/domain-driven-design.md, and the only
61
+ # thing this tier is ever allowed to put under `## /aw-spec-specify`. WHAT the model is
62
+ # stays in the domain set (its domain-model file); HOW to model lives here.
63
+ #
64
+ # THE FRONTEND LANE (only where the CODE has one). A repo with a user interface gets the
65
+ # lane's governance reverse-engineered on the same terms as the other two tiers — from the
66
+ # code and nothing else:
67
+ # .appweaver/memory/constitution.ui.md — the lane's UX-* base, authored from the UI
68
+ # source (never from a greenfield UI template's content), then linted like the other
69
+ # halves and composed in. Parallel to the technical base, so its numbering is its own.
70
+ # guardrails/projects/brf-<domain>/frontend/*.md — the code-derived lane rule set, the detail
71
+ # layer under those UX-* principles, plus `## /aw-spec-ui-constitution` appended to
72
+ # tech-rule-bindings.md so a later /appweaver constitution re-ratifies from THIS
73
+ # project's lane rules.
74
+ # .appweaver/templates/overrides/ui-design-template.md + ui-delta-design-template.md — the
75
+ # lane's own document pair, reverse-engineered from the UI source the same way the
76
+ # service pair is reverse-engineered from the service code. The lane is governed by a
77
+ # different constitution half and implemented by different commands, so it gets its own
78
+ # design document rather than a section inside the service design; the only thing that
79
+ # crosses between them is the design contract. Their consumers (⌛ ui-design,
80
+ # ui-implement) are not built yet — the templates are written now because the
81
+ # whole-repo evidence for them exists exactly once, at onboard.
82
+ # RUN /appweaver select-stack FIRST. It is the first command of the brownfield
83
+ # sequence and this workflow REFUSES to run without it, because it needs to be told three
84
+ # things before it can start: which lanes this project has, where each lane's source is,
85
+ # and what each lane's stack is. Those decide which constitution halves and rule sets get
86
+ # generated, which subtrees are scanned, and what technology the derived rules name.
87
+ # select-stack detects all three from the repo's own files and proposes them, so answering
88
+ # it on an existing codebase is mostly confirmation — but it is a person's confirmation,
89
+ # which is exactly what detection on a legacy repo needs. A declared source path that is
90
+ # not a directory stops this run with the fix named rather than producing a scaffold
91
+ # reverse-engineered from nothing.
92
+ #
93
+ # WHICH LANES EXIST is therefore the DECLARATION's answer, and it answers in both
94
+ # directions — a project that declared `(none)` for the UI lane gets no UI half, no
95
+ # frontend rule files and no `## /aw-spec-ui-*` mapping, and one that declared `(none)`
96
+ # for the service lane gets no technical half and no service rules. The deterministic
97
+ # scan is still what reads the code, now pointed AT the declared subtree: it decides what
98
+ # the governance SAYS, and the declaration decides what there is to govern. A declared
99
+ # lane whose source path holds nothing recognisable is reported, because the governance
100
+ # derived from it will be thin.
101
+ #
102
+ # ONE ORACLE, UNCHANGED. Nothing about where the CONTENT comes from has moved. Every
103
+ # constitution half, rule file and design template below is derived from this repository's
104
+ # own source plus a NEUTRAL skeleton, with no greenfield corpus, filled constitution or
105
+ # kit template in context. The declaration selects the subtree; it supplies no governance.
106
+ #
107
+ # THIS WORKFLOW NEVER WRITES .appweaver/stacks.json. It used to, back when a repo could
108
+ # reach onboard undeclared: it ran its own detection pass, recorded what it found marked
109
+ # `origin: reverse-engineered`, and was gated never to overwrite a lane a person had
110
+ # confirmed. With the declaration required at the top, that gate can never open and the
111
+ # pass was re-deriving an answer the run already had. `lane-declare` has one caller again
112
+ # — select-stack — and this workflow only reads.
113
+ #
114
+ # Never modifies source — every write lands in the OKF bundle, the specs governance dir,
115
+ # guardrails/projects/ (domain/ + service/ + frontend/ rule sets + both maps), or the
116
+ # .appweaver/templates/overrides/ design templates.
117
+ #
118
+ # Launch: /appweaver onboard [domain-name / scope hint] [; concerns: a, b, c]
119
+ # e.g. /appweaver onboard Pharma
120
+ # e.g. /appweaver onboard "Pharma; concerns: auditing, concurrency, authorization"
121
+ # =============================================================================
122
+
123
+ name: aw-spec-onboard
124
+ description: Onboard an existing codebase for brownfield DEVELOPMENT — a deterministic whole-repo scan produces a high-level OKF feature map (folders/concepts) PLUS the project-level governance scaffold (split constitution + guardrails/projects/brf-<domain>/ with its DOMAIN rule files at domain/ + domain-rule-bindings + code-derived TECHNICAL rule files at service/ + tech-rule-bindings + activated domain), all provisional-from-scan and refined per slice by adopt. Where the scan finds a frontend lane in the CODE, it also authors that lane's half — constitution.ui.md (UX-*) — and its code-derived rule files at brf-<domain>/frontend/, mapped under `## /aw-spec-ui-constitution`; a backend-only repo gets none of it. Every rule tier is reverse-engineered from the CODE alone (never a greenfield rule file), evidenced-only, and WIRED per-workflow so the whole forward pipeline AND adopt govern against THIS codebase — never a greenfield fallback. It also reverse-engineers the repo's own technical structure into a project-specific design + delta-design template pair, installed as the project template overrides, and — where the lane exists — the frontend lane's own pair from the UI source. Every authoring step is shaped by a NEUTRAL rev-templates skeleton; no greenfield constitution, rule file or document template is ever placed in context. Accepts an optional concerns list to look for (onboard decides which are actually present). Reads any declared lane, never writes one. No migration content; never modifies source.
125
+ version: 1.6.0
126
+ agent_agnostic: true
127
+ dialect: aw-spec.orchestrator/v1
128
+
129
+ inputs:
130
+ user_input:
131
+ description: >-
132
+ Optional free-text hint. May carry (a) a domain name for the governance project
133
+ (e.g. Pharma → guardrails/projects/brf-pharma/); (b) a scope/focus hint for the
134
+ feature map; and/or (c) a CONCERNS LIST to look for, as a "concerns: a, b, c"
135
+ clause (e.g. "Pharma; concerns: auditing, concurrency, authorization"). The
136
+ concerns are a SEARCH HINT only — both rule-set authors still DECIDE which
137
+ concerns are actually present from the code, and are never limited to the list.
138
+ When omitted, the domain defaults to the PROJECT name from the OKF overview,
139
+ then the repo basename; concerns are auto-discovered from the code.
140
+ required: false
141
+ bind: USER_INPUT
142
+
143
+ scripts:
144
+ inventory:
145
+ sh: .appweaver/scripts/bash/aw-inventory.sh
146
+ ps1: .appweaver/scripts/powershell/aw-inventory.ps1
147
+ revcon:
148
+ sh: .appweaver/scripts/bash/aw-rev-constitution.sh
149
+ ps1: .appweaver/scripts/powershell/aw-rev-constitution.ps1
150
+ actions:
151
+ sh: .appweaver/scripts/bash/aw-spec-actions.sh
152
+ ps1: .appweaver/scripts/powershell/aw-spec-actions.ps1
153
+
154
+ # The sticky set carries the kit's universal operating rules and NOTHING project-shaped.
155
+ # agent_generate ALWAYS injects the standards set (it cannot opt out), so keeping it to
156
+ # behaviour-only guarantees no governance skeleton or exemplar from another project leaks
157
+ # into the feature-map agent. Every step is fed EXACTLY what it needs via build_context;
158
+ # the technical-half author gets its neutral shape skeleton through context, not here.
159
+ standards:
160
+ - { path: .appweaver/ai-rules.md } # kit-resident: the universal operating rules, every flow
161
+
162
+ vars:
163
+ bundle_present: "false" # inventory bundle_guard driver
164
+ conformant: "false" # OKF conformance-gate driver
165
+ pack_present: "false" # project anti-clobber driver
166
+ technical_ok: "false" # technical-half lint guard
167
+ domain_ok: "false" # domain-half lint guard
168
+ ui_ok: "false" # UI-half lint guard
169
+ ui_lane: "false" # set from the DECLARATION below; gates the whole frontend block
170
+ svc_lane: "false" # set from the DECLARATION below; gates the whole service block
171
+
172
+ workflow:
173
+
174
+ # ═══════════════════ PART 1 — FEATURE MAP (high-level discovery) ═════════════
175
+ # A deterministic scan + one enrichment agent, mirroring inventory's shape but
176
+ # producing a SHALLOW discovery index (drop the migration backlog / seams /
177
+ # adopt-order — this is development, not migration).
178
+
179
+ # 0. WHICH LANES, AND WHERE IS THEIR SOURCE. select-stack is the first command of
180
+ # the brownfield sequence, and this is why: onboard reverse-engineers governance
181
+ # OUT of a subtree, so it has to be told which subtree before it starts. The
182
+ # declaration answers three questions at once — which lanes exist (so which
183
+ # constitution halves and rule sets to generate), where each lane's source is (so
184
+ # what to scan), and what each lane's stack is (so the derived rules name the
185
+ # right technology).
186
+ #
187
+ # The on-disk check is ON here, unlike in constitution: this run is about to READ
188
+ # those directories. A declared path that is not there stops the run with the fix
189
+ # named, rather than producing a governance scaffold reverse-engineered from
190
+ # nothing.
191
+ - id: lane_model
192
+ action: execute_script
193
+ script: { ref: actions }
194
+ subcommand: lane-verify
195
+ args: ["--command", "/appweaver onboard"]
196
+ outputs:
197
+ - { name: lane_model_ok, from: "$.ok" }
198
+ - { name: lane_model_issues, from: "$.message" }
199
+ - { name: lane_kinds, from: "$.kinds" }
200
+ - { name: be_declared, from: "$.backend_declared" }
201
+ - { name: be_lane_id, from: "$.backend_lane_id" }
202
+ - { name: be_profile, from: "$.backend_profile" }
203
+ - { name: be_root, from: "$.backend_source_path" }
204
+ - { name: fe_declared, from: "$.frontend_declared" }
205
+ - { name: fe_lane_id, from: "$.frontend_lane_id" }
206
+ - { name: fe_profile, from: "$.frontend_profile" }
207
+ - { name: fe_root, from: "$.frontend_source_path" }
208
+
209
+ - id: lane_model_gate
210
+ action: verify_context
211
+ require_true: lane_model_ok
212
+ on_false: stop
213
+ on_false_message: >
214
+ /appweaver onboard cannot run: {{lane_model_issues}}
215
+ onboard reverse-engineers this repository's governance out of its source, so it
216
+ has to be told which subtrees hold which lane before it starts scanning. Run
217
+ /appweaver select-stack first — it detects what this repo already is, proposes
218
+ the stack and the source path for each lane, and lets you correct both.
219
+
220
+ - id: lane_kinds_gate
221
+ action: verify_context
222
+ require_non_empty: lane_kinds
223
+ on_empty: stop
224
+ on_empty_message: >
225
+ No lane is declared — .appweaver/stacks.json exists but declares neither a service
226
+ nor a UI lane, so onboard has no source to reverse-engineer. Re-run
227
+ /appweaver select-stack and declare at least one lane.
228
+
229
+ # 1. DETERMINISTIC scan of the current codebase → JSON substrate (files, churn,
230
+ # categories, aggregate_signals = candidate feature roots), and reports whether
231
+ # a bundle already holds curation.
232
+ #
233
+ # SCOPED BY THE DECLARATION. Backend signals come from outside the UI lane's
234
+ # subtree (and inside the service lane's); frontend signals come from the UI
235
+ # lane's subtree alone. This substrate is inlined verbatim into every agent
236
+ # request this run makes, so an unscoped scan puts the whole frontend file list in
237
+ # front of the step deriving the SERVICE rules and every backend aggregate in front
238
+ # of the steps deriving the UI's — while each prompt tells the model to ignore what
239
+ # it has just been handed. Scoping removes the material instead of arguing with it,
240
+ # and shrinks six payloads at the same time.
241
+ - id: scan
242
+ action: execute_script
243
+ script: { ref: inventory }
244
+ subcommand: scan
245
+ args: ["--service-root", "{{be_root}}", "--ui-root", "{{fe_root}}"]
246
+ outputs:
247
+ - { name: inventory_json, from: "$.inventory_json" }
248
+ - { name: root, from: "$.root" }
249
+ - { name: head, from: "$.head" }
250
+ - { name: file_count, from: "$.file_count" }
251
+ - { name: aggregate_count, from: "$.aggregate_count" }
252
+ - { name: bundle_dir, from: "$.bundle_dir" }
253
+ - { name: bundle_present, from: "$.bundle_present" }
254
+ - { name: bundle_md_count, from: "$.bundle_md_count" }
255
+ # The frontend lane, as the CODE evidences it. `frontend_present` is true only
256
+ # where a candidate root reached lane strength (a frontend build config, or a
257
+ # real set of component/view files) — loose scripts and stylesheets under a
258
+ # wwwroot/ are reported in the substrate but are NOT a lane.
259
+ - { name: frontend_present, from: "$.frontend_present" }
260
+ - { name: frontend_separable, from: "$.frontend_separable" }
261
+ - { name: frontend_roots, from: "$.frontend_roots" }
262
+ - { name: frontend_root_count, from: "$.frontend_root_count" }
263
+ # The PRIMARY root / kind / stack — the single values the lane declaration needs.
264
+ - { name: frontend_root, from: "$.frontend_root" }
265
+ - { name: frontend_kind, from: "$.frontend_kind" }
266
+ - { name: frontend_stack, from: "$.frontend_stack" }
267
+ # Did the DECLARED UI subtree actually contain UI? A declared lane is a lane
268
+ # either way — this is what separates governance reverse-engineered from real
269
+ # source from governance derived from an empty directory.
270
+ - { name: ui_evidence_found, from: "$.ui_evidence_found" }
271
+ - { name: backend_file_count, from: "$.backend_file_count" }
272
+ - { name: frontend_file_count, from: "$.frontend_file_count" }
273
+ - { name: scoped_service_root, from: "$.declared_service_root" }
274
+ - { name: scoped_ui_root, from: "$.declared_ui_root" }
275
+
276
+ # 1b. Substance gate: no candidate features → nothing to map.
277
+ - id: require_aggregates
278
+ action: verify_context
279
+ require_true: aggregate_count
280
+ on_false: stop
281
+ on_false_message: "Scan found no candidate features in {{root}} (file_count={{file_count}}). Point /appweaver onboard at a codebase with a recognizable domain/vertical-slice layout, or scan a subtree that contains one."
282
+
283
+ # 1c. Curation guard (OKF rule): a bundle that already has concept files is
284
+ # curation — regenerating from scratch would destroy it.
285
+ - id: bundle_guard
286
+ action: verify_context
287
+ require_value: bundle_present
288
+ equals: "false"
289
+ on_mismatch: stop
290
+ on_mismatch_message: "The OKF feature-map bundle at {{bundle_dir}} already holds {{bundle_md_count}} concept file(s) — onboard would overwrite that curation. Back up or remove {{bundle_dir}} to re-onboard from scratch."
291
+
292
+ # 1d. FRONTEND LANE — the DECLARATION decides that it exists, and the CODE decides
293
+ # what its governance says. Those are two different questions and they used to be
294
+ # answered by one signal.
295
+ #
296
+ # Before, the scan's own strength test (a frontend build config, or UI_STRONG_MIN
297
+ # component files) both found the lane and supplied its evidence. That test exists
298
+ # to stop a scan INVENTING a lane out of a wwwroot/ of loose scripts, which is the
299
+ # right instinct and the wrong authority: it also meant a real lane the heuristic
300
+ # scored one file short simply did not exist, and no amount of declaring it helped.
301
+ # Now the project says which lanes it has and where their source is, and the scan
302
+ # — pointed at that subtree — says what is in there.
303
+ #
304
+ # ONE ORACLE, UNCHANGED. Nothing about where the CONTENT comes from has moved:
305
+ # every rule, principle and template below is still derived from this repository's
306
+ # own source and from a neutral skeleton, with no greenfield corpus in context.
307
+ # The declaration selects the subtree; it never supplies a word of the governance.
308
+ # No service lane ⇒ the technical lint loop has nothing to check, so its guard is
309
+ # satisfied rather than left at its "not yet verified" default; a declared lane
310
+ # restores it, because that half does get authored and does get linted.
311
+ - id: svc_lane_absent
312
+ action: set
313
+ vars: { svc_lane: "false", technical_ok: "true", setup_tech_flag: "--no-technical" }
314
+ - id: svc_lane_declared
315
+ action: set
316
+ condition: "{{be_declared}}"
317
+ vars: { svc_lane: "true", technical_ok: "false", setup_tech_flag: "" }
318
+
319
+ # A repo with no service lane. Rare in brownfield and real — a static site, a
320
+ # component library, a front end whose API lives in another repository. The
321
+ # technical half, the service rule set and the service design templates are all the
322
+ # SERVICE lane's, so none of them is authored, and saying so is better than leaving
323
+ # someone to notice that guardrails/projects/<p>/service/ is empty.
324
+ - id: svc_lane_warning
325
+ action: verify_context
326
+ require_true: svc_lane
327
+ on_false: continue
328
+ on_false_message: >
329
+ No service lane in .appweaver/stacks.json — skipping the TECHNICAL constitution
330
+ half, the service rule set (the project's own service/ folder) and the
331
+ service design/delta-design template overrides. All three are the service lane's,
332
+ and this project declared it has none. The domain rule set, the domain half and —
333
+ where a UI lane is declared — the whole frontend tier are authored as usual. If
334
+ this repo does have backend source, run /appweaver select-stack, declare it and
335
+ re-run onboard.
336
+
337
+ - id: ui_lane_absent
338
+ action: set
339
+ vars:
340
+ ui_lane: "false"
341
+ ui_evidence: ""
342
+ ui_declaration_note: "no frontend lane is declared in .appweaver/stacks.json — this repo is governed as backend-only"
343
+ - id: ui_lane_declared
344
+ action: set
345
+ condition: "{{fe_declared}}"
346
+ vars:
347
+ ui_lane: "true"
348
+ ui_evidence: "lane '{{fe_lane_id}}' ({{fe_profile}}) is declared at the source path {{fe_root}}; the scan found UI source there — {{frontend_roots}}"
349
+ ui_declaration_note: "lane '{{fe_lane_id}}' ({{fe_profile}}) at {{fe_root}} — the declared source path this run reverse-engineered the UI governance out of"
350
+
351
+ # A declared UI lane whose source path holds nothing a scan recognises as UI. The
352
+ # path exists — lane-verify already refused the run otherwise — so this is not a
353
+ # broken declaration, it is an empty one: a lane scaffolded but not yet built, or a
354
+ # source path one directory too high. Announce and continue rather than stop: the
355
+ # declaration is a person's statement and is left exactly as it stands, but the UI
356
+ # governance below will be thin, and it is better to say why now than to let someone
357
+ # discover a UX base derived from an empty directory.
358
+ - id: ui_evidence_warning
359
+ action: verify_context
360
+ condition: "{{ui_lane}} == true"
361
+ require_true: ui_evidence_found
362
+ on_false: continue
363
+ on_false_message: >
364
+ Frontend lane '{{fe_lane_id}}' is declared at {{fe_root}}, but the scan found no
365
+ component, view or build-config files under that path ({{frontend_file_count}}
366
+ file(s) there in total). The UI governance authored below is reverse-engineered
367
+ from that subtree, so it will be thin or empty. Check that the source path points
368
+ at the directory holding the UI — /appweaver select-stack can move it — or
369
+ retire the lane there with (none) if this repo has no UI yet.
370
+
371
+ # 2. Pre-execution hooks.
372
+ - id: resolve_pre_hooks
373
+ action: execute_script
374
+ script: { ref: actions }
375
+ subcommand: resolve-hooks
376
+ args: ["--phase", "before_onboard"]
377
+ outputs:
378
+ - { name: before_hooks, from: "$.hooks" }
379
+ - id: dispatch_pre_hooks
380
+ action: dispatch_hooks
381
+ hooks_from_variable: before_hooks
382
+
383
+ # 3. ENRICHMENT — turn the substrate into a HIGH-LEVEL OKF feature map. Context via
384
+ # build_context (agent_generate reads the envelope): the factual substrate, the
385
+ # OKF format authority, and an OPTIONAL DDD vocabulary aid for naming (no
386
+ # migration/pipeline reference — this is development).
387
+ - id: ctx_author
388
+ action: build_context
389
+ context:
390
+ - { path: "{{inventory_json}}" } # the deterministic substrate (aggregate_signals etc.)
391
+ - { path: .appweaver/templates/okf-concept-template.md } # OKF v0.1 format authority (frontmatter, index, log, rules) — format only, zero project content
392
+ - id: author_bundle
393
+ action: agent_generate
394
+ tools: "Read,Write,Edit"
395
+ permission_mode: acceptEdits
396
+ task: |
397
+ Act as the OKF enrichment agent for the Brownfield DEVELOPMENT onboard step.
398
+ Produce a CONFORMANT OKF v0.1 knowledge bundle at {{bundle_dir}} that is a
399
+ HIGH-LEVEL FEATURE MAP — a discovery index of the features/aggregates this
400
+ codebase contains, organized BY AGGREGATE ROOT — from the deterministic
401
+ substrate {{inventory_json}} (in context). Follow the OKF concept template in
402
+ context for format (frontmatter, index.md/log.md rules, cross-linking, hard rules).
403
+ Domain/scope hint (optional): {{USER_INPUT}}
404
+
405
+ THIS IS A MAP, NOT A DEEP REVERSE. Keep every feature concept SHALLOW — enough
406
+ to recognize and pick the feature to develop next. The deep per-feature reverse
407
+ (spec.md + design.md) is /appweaver adopt, run just-in-time when a feature is
408
+ about to be developed. Do NOT deep-model invariants/behaviour here.
409
+
410
+ Read the substrate first. Its `aggregate_signals` are CANDIDATE feature roots,
411
+ each with its files grouped by layer plus detected entities; `ui_attribution`
412
+ says which FRONTEND files serve which of those roots (and which serve none);
413
+ `git.history.churn` ranks significance; the category lists and `top_level_dirs`
414
+ fill in the rest.
415
+ Signals are input, not decisions — YOU draw the real feature boundaries:
416
+ - Merge a src module and its mirror test module into ONE feature (e.g.
417
+ src/.../MedicinalProducts + tests/.../MedicinalProducts → MedicinalProduct).
418
+ - Treat service-level / shared infrastructure (a shared persistence context,
419
+ cross-cutting adapters, host / service-defaults projects) as a Platform/Shared
420
+ concept, NOT a feature.
421
+ - Fold value objects, entities, domain events, commands and endpoints into the
422
+ feature that OWNS them — one feature concept, not one per type.
423
+ NAME EVERY CONCEPT IN THE CODE'S OWN VOCABULARY — read the identifiers the source
424
+ actually uses. "Aggregate", "entity" and "value object" are how aw-spec ORGANIZES a
425
+ feature map; they are not a claim that this codebase is modelled that way. Where the
426
+ code expresses its model differently, record what it does and keep the aw-spec
427
+ grouping around it.
428
+
429
+ Write the bundle (all paths under {{bundle_dir}}; bundle-relative links begin
430
+ with "/", per OKF §5.1):
431
+ - `index.md` (bundle root) — frontmatter EXACTLY `okf_version: "0.1"` and nothing
432
+ else; body = sections of bulleted links reusing each concept's `description`.
433
+ - `architecture/overview.md` (type: Reference) — the system at a glance. Its
434
+ `## Purpose` section MUST open with the whole solution/product name in bold
435
+ followed by "is a …" (e.g. "**Medicinal.Healthcare** is a …") — this bold token
436
+ is the PROJECT NAME the governance tier is named after, so get it right. Then:
437
+ the FEATURE MAP (each feature + one-line responsibility — NO seam/clean-torn
438
+ column, NO adopt-order), the tech stack, named external references / integration
439
+ points, and links to every other concept.
440
+ - `architecture/platform.md` (type: Reference) — the SHARED / cross-cutting
441
+ TECHNICAL note: the actual technology base (language, framework, persistence,
442
+ eventing, hosting), the shared infrastructure (persistence context, host /
443
+ service-defaults),
444
+ cross-cutting concerns (auth posture, concurrency, observability) AS-BUILT. This
445
+ is the evidence the technical constitution is scaffolded from — describe what the
446
+ code ACTUALLY does, mark anything stubbed/optional/inactive as such.
447
+ - `architecture/frontend.md` (type: Reference) — WRITE THIS ONLY IF the substrate's
448
+ `frontend_signals.present` is true; omit the file entirely otherwise (a backend-only
449
+ repo must not get one). It is the UI counterpart of the platform note and the
450
+ evidence the frontend lane's constitution is scaffolded from. Read the candidate
451
+ roots in `frontend_signals` and then READ REPRESENTATIVE UI SOURCE from their
452
+ component/route/store file lists, and record AS-BUILT: the lane root(s) and whether
453
+ the UI is separable or rendered inside the service tree; what it is built with (name
454
+ it from the code — the `framework_markers` are markers, not conclusions); how
455
+ components are organized and named; routing/navigation; where client state and
456
+ server data-fetching live; styling and any design-system or component library in
457
+ use; the accessibility, internationalization and error/loading-state handling the
458
+ code ACTUALLY exhibits; and the lane's build, lint and test tooling. State
459
+ inconsistency as inconsistency and absence as absence — an app with no
460
+ accessibility attributes is recorded as having none, never as needing them.
461
+ This note is also where the SHARED UI surface is recorded — `ui_attribution.
462
+ unattributed` lists the files serving no single aggregate (app shell, layout,
463
+ design system, global styles). Describe what they provide; they belong here
464
+ precisely because no slice owns them.
465
+ - `aggregates/<feature>.md` (type: Aggregate) — ONE per feature root, SHALLOW:
466
+ Responsibilities; the entities / value objects / domain events / commands / API
467
+ endpoints / persistence it OWNS (named at a glance from the signal's layer
468
+ files — a list, not a deep model); and the candidate `specs/<Feature>/` slice
469
+ name (feature = aggregate). Set `source_files` to the module's files, grouped
470
+ with YAML comment headers by each file's OWN folder — the path segment that
471
+ VARIES across the files after their shared parent (the layer folder in a
472
+ vertical slice; the tier project in an n-tier app; tests → a single `tests`
473
+ group). Do NOT impose a fixed Domain/Application/UI taxonomy — the CODE's
474
+ folders ARE the grouping. Set `timestamp` to the latest commit time across them.
475
+ Then set `ui_source_files` to the FRONTEND files that serve this aggregate,
476
+ grouped the same way. The substrate's `ui_attribution` proposes them per
477
+ aggregate — it is a NAME match, so confirm each against what the file actually
478
+ is and move or drop one it got wrong. Keep the key and leave it EMPTY where the
479
+ aggregate has no UI (and on a backend-only repo, where every concept has none);
480
+ never fold these paths into `source_files`, which stays the service surface.
481
+ - `aggregates/index.md` — the bounded-context / feature map (no frontmatter beyond
482
+ OKF index rules) linking every feature concept.
483
+ - An `index.md` in EVERY subdirectory (no frontmatter).
484
+ - `log.md` (bundle root) — first line under a `## <today's date>` heading must be
485
+ `Commit: ` + backtick + `{{head}}` + backtick (validator rule E4), then a
486
+ one-line Initialization entry noting the concept count.
487
+ Do NOT write a migration-backlog, a seam/clean-torn analysis, or an adopt-order —
488
+ those are migration artifacts and are out of scope for the development flow.
489
+
490
+ Provenance + safety (OKF hard rules):
491
+ - Stamp every concept `origin: reverse-engineered` and `generated_by:
492
+ aw-spec-onboard/1.6.0` in frontmatter.
493
+ - The CODE is the source of truth; capture what IS (quirks included), not what
494
+ SHOULD be. Where intent is unclear from code + git history, add a concrete
495
+ `open_questions` entry rather than inventing one.
496
+ - NEVER fabricate facts, and NEVER emit secrets/tokens/credentials/internal
497
+ hostnames — describe shape, never values.
498
+ - Write ONLY inside {{bundle_dir}}; do NOT modify any source file.
499
+ Report the bundle tree and the concept count by type.
500
+ outputs:
501
+ - { name: bundle_files, from: "$.files" }
502
+
503
+ - id: verify_authored
504
+ action: verify_context
505
+ require_non_empty: bundle_files
506
+ on_empty: stop
507
+ on_empty_message: "No feature-map files were written to {{bundle_dir}}. Ensure the substrate {{inventory_json}} has aggregate_signals and re-run."
508
+
509
+ # 4. CONFORMANCE gate — OKF v0.1 validator (errors block; warnings noted).
510
+ - id: validate_bundle
511
+ action: execute_script
512
+ script: { ref: inventory }
513
+ subcommand: validate
514
+ args: ["--bundle", "{{bundle_dir}}", "--repo-root", "{{root}}"]
515
+ outputs:
516
+ - { name: conformant, from: "$.conformant" }
517
+ - { name: okf_errors, from: "$.errors" }
518
+ - { name: okf_warnings, from: "$.warnings" }
519
+ - { name: concepts, from: "$.concepts" }
520
+
521
+ - id: conformance_gate
522
+ action: verify_context
523
+ require_true: conformant
524
+ on_false: stop
525
+ on_false_message: "The OKF feature map at {{bundle_dir}} is NON-CONFORMANT (errors: {{okf_errors}}). Fix the reported ERRORs (unparseable frontmatter, missing `type`, malformed index.md/log.md) and re-run."
526
+
527
+ # ═══════════════ PART 2 — GOVERNANCE SCAFFOLD (project-level) ════════════════
528
+ # Establish the governing tier ONCE, from the feature map just written (the whole-
529
+ # repo vantage). No slice is adopted, so list-adopted returns slice_count=0 but STILL
530
+ # yields project_name / overview / project_context (domain evidence) and
531
+ # design_context (= overview + platform: the technical evidence) from the bundle.
532
+ # There is NO require_adopted gate here — that is the whole point of onboarding first.
533
+
534
+ - id: project_ctx
535
+ action: execute_script
536
+ script: { ref: revcon }
537
+ subcommand: list-adopted
538
+ outputs:
539
+ - { name: slice_count, from: "$.slice_count" }
540
+ - { name: spec_context, from: "$.spec_context" } # at onboard = project_context (no specs yet)
541
+ - { name: design_context, from: "$.design_context" } # at onboard = overview + platform (the tech evidence)
542
+ - { name: project_context, from: "$.project_context" } # overview + aggregates/index + platform + index
543
+ - { name: project_name, from: "$.project_name" }
544
+ - { name: overview, from: "$.overview" }
545
+
546
+ # Slugify + `brf-` prefix the domain name and create guardrails/projects/brf-<domain>/.
547
+ # Name: explicit arg → PROJECT name from the OKF overview → repo basename. Guarded
548
+ # against clobbering a project that already holds .md files.
549
+ - id: pack_setup
550
+ action: execute_script
551
+ script: { ref: revcon }
552
+ subcommand: project-setup
553
+ args: ["--name", "{{USER_INPUT}}", "--fallback", "{{project_name}}"]
554
+ outputs:
555
+ - { name: domain_slug, from: "$.domain_slug" }
556
+ - { name: pack_dir, from: "$.pack_dir" }
557
+ - { name: domain_rule_bindings, from: "$.domain_rule_bindings" }
558
+ - { name: domain_constitution_source, from: "$.domain_constitution_source" }
559
+ - { name: pack_present, from: "$.pack_present" }
560
+
561
+ - id: pack_guard
562
+ action: verify_context
563
+ require_value: pack_present
564
+ equals: "false"
565
+ on_mismatch: stop
566
+ on_mismatch_message: "The project guardrails/projects/{{domain_slug}}/ already holds curated rule files — onboard would overwrite them. Back up or remove that folder to re-onboard, or amend it via /appweaver constitution."
567
+
568
+ # ── DOMAIN RULE SET (provisional, evidenced by the SCAN) ────────────────────
569
+ # Feed NEUTRAL shape skeletons (rev-templates/, zero content to leak) + the rule-
570
+ # partition authority + the project context (the feature map). NO adopted specs
571
+ # exist — the evidence is the OKF overview + aggregates/index + platform.
572
+ - id: ctx_pack
573
+ action: build_context
574
+ context:
575
+ - { path: "{{inventory_json}}" } # the COMPLETE deterministic scan substrate — read representative SOURCE from its file lists (the OKF map only SUMMARISES this)
576
+ - { path: .appweaver/orchestrator/rev-templates/domain-rule-bindings.skeleton.md, optional: true }
577
+ - { path: .appweaver/orchestrator/rev-templates/domain-rule-file.skeleton.md, optional: true }
578
+ - { path: .appweaver/orchestrator/rev-templates/domain-requirements.skeleton.md, optional: true }
579
+ - { path: .appweaver/RULE-PARTITION.md } # the rule-partition authority (which command reads what)
580
+ context_from: project_context
581
+ - id: author_pack
582
+ action: agent_generate
583
+ tools: "Read,Write,Edit"
584
+ permission_mode: acceptEdits
585
+ task: |
586
+ Scaffold the PROJECT-level DOMAIN RULE SET for **{{project_name}}** (domain
587
+ {{domain_slug}}) into guardrails/projects/{{domain_slug}}/domain/ (the dir exists),
588
+ plus the domain map guardrails/projects/{{domain_slug}}/domain-rule-bindings.md at the
589
+ project root. A project keeps its three rule classes in domain/ · service/ · frontend/
590
+ and both maps at its root; adopt reconciles this set in place, so a file written
591
+ anywhere else is unreachable.
592
+
593
+ EVIDENCE = THE CODE ITSELF (deep read), NOT the shallow map. The OKF FEATURE MAP in
594
+ context (architecture/overview.md, aggregates/index.md, architecture/platform.md)
595
+ only SUMMARISES the codebase. READ REPRESENTATIVE SOURCE to extract the real domain
596
+ rules: use {{inventory_json}} (in context) to locate the domain-carrying files —
597
+ entities, value objects, aggregates, domain events, invariant checks, validation —
598
+ across the aggregate_signals, and Read enough of them to state each rule from what
599
+ the code ACTUALLY enforces. Do NOT invent a rule the code does not evidence, and do
600
+ NOT rely on the map alone. There are NO adopted specs yet; this is the whole-repo
601
+ vantage — describe the domain / bounded context AS A WHOLE, so any feature later
602
+ slots in without a rewrite.
603
+
604
+ CONCERNS HINT: {{USER_INPUT}} may carry a "concerns: a, b, c" clause. Treat any listed
605
+ concern as a SEARCH HINT — go look for it in the code — but you still DECIDE presence
606
+ from evidence: include a concern's rule file ONLY if the code exhibits it, drop a
607
+ listed concern the code shows none of, and ADD an unlisted concern the code clearly
608
+ evidences. Ignore any non-concerns text (the domain name / scope hint).
609
+
610
+ PROVISIONAL BY CONSTRUCTION. Because no slice is adopted, you have the domain's
611
+ SHAPE (its features, ubiquitous language, bounded-context map, evident concerns)
612
+ but not yet its enumerated rule ids. Write each rule at the level the feature map
613
+ evidences and mark unresolved specifics `PROVISIONAL — reconciled at adopt`
614
+ (adopt fills the exact BR-/CN-/DC-/IC- ids when the feature is developed). NEVER
615
+ invent a rule the code/feature-map does not evidence.
616
+
617
+ SKELETONS ARE SHAPE ONLY. The *.skeleton.md files (rev-templates/) show HEADINGS,
618
+ frontmatter, the rule-partition and tone — and carry NO domain content. Copy the
619
+ SHAPE; never treat a bracketed [TOKEN] or example marker as a value to assert.
620
+
621
+ EVIDENCED-ONLY (lean): write a `<concern>.domain.md` ONLY for a concern the
622
+ feature map / platform note actually exhibits. NAME EACH FILE AFTER THE CONCERN THE
623
+ CODE EXHIBITS, never after a methodology the code may not follow — a filename is an
624
+ assertion too. Consider, include only if evidenced:
625
+ - domain-model.domain.md — the ubiquitous language + bounded-context /
626
+ feature map, WHAT this codebase's model is. Written wherever the code carries a
627
+ discernible domain model; omitted where it carries none (a pure script/ETL repo).
628
+ This is the domain tier's authority for /specify.
629
+ - data-classification.domain.md — only if the overview shows classified data.
630
+ - auditing.domain.md — only if the platform note shows audit/immutability.
631
+ - authorization.domain.md — only if an auth posture is evident.
632
+ - persistence.domain.md — only if retention/immutability/no-hard-delete is evident.
633
+ - cqrs.domain.md — only if the platform note shows a command/query split.
634
+ - eventing.domain.md — only if domain events are evident.
635
+ - api-versioning.domain.md — only if the API surface is versioned.
636
+ Plus, as needed:
637
+ - a domain reference file per distinct domain identifier/standard the overview names.
638
+ - domain-requirements.md — the PROJECT overview: open with a
639
+ `[DOMAIN: Bounded Contexts / Modules]` map (from the overview + aggregates
640
+ index), then per-subsection pointers, platform topology, governance overrides.
641
+ Stamp every file `origin: reverse-engineered`, `generated_by: aw-spec-onboard/1.6.0`,
642
+ and note the project is a provisional scaffold reconciled per slice at adopt.
643
+
644
+ domain-rule-bindings.md (MANDATORY — /specify's resolve-domain reads this exact filename).
645
+ Wire ONLY the files you generated, preserving the RULE PARTITION:
646
+ - `## /aw-spec-constitution` — `domain/domain-constitution.md` FIRST (the project's
647
+ charter; a later step in this same run authors it, so wire the bullet now), then the
648
+ domain identity/regulatory/interop files → domain principles.
649
+ - `## /aw-spec-specify` — the FULL domain set (specify models the domain, lifts CN-/DC-/IC-).
650
+ - `## /aw-spec-design` — `_None — design loads no domain file. Domain reaches design only through the spec._`
651
+ - `## /aw-spec-implement` — `_None — implement loads no domain file. Domain reaches implement only through design.md._`
652
+ - `## /aw-spec-gate` — the conformance-checklist set (the *.domain.md files).
653
+ Each bullet is a workspace-relative path `- guardrails/projects/{{domain_slug}}/domain/<file>`.
654
+ Write ONLY inside guardrails/projects/{{domain_slug}}/ (domain/ + the map). Report the
655
+ files written.
656
+ outputs:
657
+ - { name: pack_files, from: "$.files" }
658
+
659
+ - id: verify_pack
660
+ action: verify_context
661
+ require_non_empty: pack_files
662
+ on_empty: stop
663
+ on_empty_message: "No domain rule files were written to guardrails/projects/{{domain_slug}}/domain/. Ensure the feature map carries a modellable domain (a feature map + ubiquitous language) and re-run."
664
+ - id: require_domain_rule_bindings
665
+ action: verify_context
666
+ required_files: ["{{domain_rule_bindings}}"]
667
+
668
+ # ── DOMAIN CONSTITUTION SOURCE — <project>/domain/domain-constitution.md ────────────
669
+ # Named and placed exactly as a greenfield industry corpus names and places its charter,
670
+ # and already wired as the first `## /aw-spec-constitution` bullet by the step above.
671
+ - id: ctx_domain_source
672
+ action: build_context
673
+ context:
674
+ - { path: "{{domain_rule_bindings}}" }
675
+ - { path: .appweaver/orchestrator/rev-templates/domain-constitution.skeleton.md, optional: true }
676
+ context_from: project_context
677
+ - id: author_domain_source
678
+ action: agent_author
679
+ include_standards: false
680
+ output_target: { type: file, path: "{{domain_constitution_source}}" }
681
+ task: |
682
+ Author the DOMAIN CONSTITUTION SOURCE (the output target) — the human-readable
683
+ charter for the WHOLE PROJECT **{{project_name}}** (domain {{domain_slug}}),
684
+ scaffolded from the OKF feature map (architecture/overview.md, aggregates/index.md
685
+ — in context) and the generated project's domain-rule-bindings.md. Follow the SHAPE of the
686
+ neutral skeleton domain-constitution.skeleton.md (in context) — its Project-Identity
687
+ + Domain-Principle structure — so the normal /appweaver constitution can
688
+ re-derive the domain half later. The skeleton carries NO content; every value
689
+ comes from the feature-map evidence.
690
+
691
+ PROJECT CHARTER, NOT AN AGGREGATE SPEC, and PROVISIONAL (no slice adopted yet).
692
+ Structure:
693
+ - Title `# {{project_name}} Domain Constitution (as-built, provisional)` and a
694
+ one-line origin note (`origin: reverse-engineered`, today's date).
695
+ - `## Project Identity` — project name = {{project_name}}; mission (from the
696
+ overview Purpose); bounded-context / feature map (from the overview feature map +
697
+ aggregates/index.md — list the features AND named external references as
698
+ contexts); architecture posture (from platform.md).
699
+ - `## Domain Principles` — principles the domain embodies, TITLED by DOMAIN CONCERN
700
+ (not by a feature name), each a declarative rule that would hold across features.
701
+ Number with a stable "D1, D2, …" convention (the composed constitution assigns
702
+ exact roman numerals after the technology base). Cite the feature-map evidence;
703
+ mark any principle whose exact rule ids are not yet enumerable `PROVISIONAL —
704
+ reconciled at adopt`.
705
+ - AS-BUILT: state the rule the code evidences; do NOT prescribe an ideal it does
706
+ not meet, and do NOT create a debt/backlog (migration is a later phase) — simply
707
+ omit an aspiration the code shows none of.
708
+ - Reference (do not restate) the technology base and the project's rule files.
709
+ Return the charter markdown only.
710
+
711
+ # ── SPLIT CONSTITUTION — scaffold the two memory halves ──────────────────────
712
+ # Create the halves this project's LANES call for. The domain half is always created
713
+ # — domain is not a lane, it addends whichever halves exist — and the technical half
714
+ # only where a service lane is declared. `setup_tech_flag` carries that decision to
715
+ # EVERY setup-constitution call in this workflow, the UI one included: this command
716
+ # creates the always-present halves as a side effect of whatever else it is asked to
717
+ # do, so a later call without the flag silently recreates the half an earlier call
718
+ # was told to skip.
719
+ - id: setup_constitution
720
+ action: execute_script
721
+ script: { ref: actions }
722
+ subcommand: setup-constitution
723
+ args: ["{{setup_tech_flag}}"]
724
+ outputs:
725
+ - { name: constitution_technical_file, from: "$.constitution_technical_file" }
726
+ - { name: constitution_domain_file, from: "$.constitution_domain_file" }
727
+
728
+ # TECHNICAL HALF — from the OKF overview + platform note (design_context), DOMAIN-FREE.
729
+ # The neutral technical shape skeleton is fed via CONTEXT (not the sticky standards
730
+ # set, which is empty), so nothing leaks into the Part-1 feature-map agent.
731
+ - id: ctx_technical
732
+ action: build_context
733
+ condition: "{{svc_lane}} == true"
734
+ context:
735
+ - { path: "{{constitution_technical_file}}" }
736
+ - { path: .appweaver/orchestrator/rev-templates/technical-constitution.skeleton.md, optional: true }
737
+ - { path: .appweaver/orchestrator/rev-templates/ai-rules.reference.md, optional: true }
738
+ context_from: design_context
739
+ - id: author_technical
740
+ action: agent_author
741
+ condition: "{{svc_lane}} == true"
742
+ include_standards: false
743
+ output_target: { type: file, path: "{{constitution_technical_file}}" }
744
+ task: |
745
+ Scaffold the TECHNICAL project constitution (the target file in context) —
746
+ AS-BUILT, from the OKF architecture overview + platform note (in context) that
747
+ describe this codebase's ACTUAL technology base. It is a TEMPLATE with [ALL_CAPS]
748
+ tokens; this is the domain-AGNOSTIC half. No slice is adopted, so the evidence is
749
+ the SCAN (overview stack + platform note), and principles are PROVISIONAL —
750
+ reconciled with real code coordinates when features are adopted.
751
+
752
+ EVIDENCE-FIRST — DISCOVER the principle set; do NOT inherit it. The skeleton
753
+ (technical-constitution.skeleton.md, in context) is a NEUTRAL SHAPE REFERENCE ONLY
754
+ — heading style, Sync-Impact-Report shape, evidence-line pattern — and carries NO
755
+ principle set. Author a principle ONLY for a technology trait the platform note /
756
+ overview actually evidences (the framework, persistence, eventing, concurrency,
757
+ hosting, testing, auth posture that ARE there). Cite the evidence on every
758
+ principle (e.g. "(evidence: platform.md persistence; overview stack)"); mark it
759
+ `PROVISIONAL — code coordinate reconciled at adopt` where the exact file/type is
760
+ not yet pinned.
761
+ - State PARTIAL / STUBBED / OPTIONAL traits AT THE LEVEL THE CODE REACHES, never a
762
+ template ideal (e.g. permissive-stub auth is not "Security by Default").
763
+ - OMIT pure-aspiration traits the platform note shows ZERO of. Do NOT create an
764
+ as-built-debt/backlog sink — migration is a separate later phase; an unmet ideal
765
+ is simply not asserted here.
766
+ - The project name is **{{project_name}}** — use it for the title / any
767
+ [PROJECT_NAME] token so this half, the domain half, and the charter name the
768
+ SAME project (never the outer tooling folder or a namespace).
769
+ - Do NOT add any domain-specific principle, identifier, terminology, regulatory or
770
+ interop rule — those belong to constitution.domain.md.
771
+ - NUMBER the discovered principles with sequential roman numerals from I, NO gaps,
772
+ NO padding. STATE the hand-off in the Sync Impact Report ("Technical principles:
773
+ I–<N>; domain half continues at <N+1>").
774
+ - Fill EVERY placeholder; leave no unexplained [BRACKET] (justify a genuine
775
+ deferral as TODO(<FIELD>): reason). Bump CONSTITUTION_VERSION by semver; ISO
776
+ YYYY-MM-DD dates (RATIFICATION_DATE = today). Preserve heading hierarchy.
777
+ - PREPEND a "Sync Impact Report" HTML comment: version old→new, the DISCOVERED
778
+ principle set, any trait DELIBERATELY OMITTED for lack of evidence (with why),
779
+ the technical count / domain hand-off numeral, and dependent artifacts (✅/⚠).
780
+ Return the complete updated technical constitution content only.
781
+
782
+ - id: technical_validation_loop
783
+ action: loop
784
+ condition: "{{svc_lane}} == true"
785
+ while: "{{technical_ok}} != true"
786
+ max_iterations: 3
787
+ steps:
788
+ - id: tech_lint
789
+ action: execute_script
790
+ script: { ref: actions }
791
+ subcommand: constitution-verify
792
+ args: ["--file", "{{constitution_technical_file}}"]
793
+ outputs:
794
+ - { name: technical_ok, from: "$.ok" }
795
+ - { name: technical_issues, from: "$.issues" }
796
+ - id: tech_lint_break
797
+ action: break
798
+ condition: "{{technical_ok}} == true"
799
+ - id: patch_technical
800
+ action: agent_author
801
+ context: ["{{constitution_technical_file}}"]
802
+ include_standards: false
803
+ output_target: { type: file, path: "{{constitution_technical_file}}" }
804
+ task: |
805
+ Fix these mechanical defects in the technical constitution (target file in
806
+ context), changing NOTHING else — preserve every principle, the heading
807
+ hierarchy, and the Sync Impact Report. Fill any listed [ALL_CAPS] placeholder
808
+ with concrete text (or a justified TODO(<FIELD>): reason); make the body's
809
+ version line AGREE with the Sync Impact Report; ISO YYYY-MM-DD dates.
810
+ Defects: {{technical_issues}}
811
+ Return the complete updated technical constitution content only.
812
+
813
+ # ── UI HALF (frontend lane only) ────────────────────────────────────────────
814
+ # Placed HERE for the same reason the greenfield constitution places it here: AFTER
815
+ # the technical half, so the service lane's rules cannot leak into the lane's own
816
+ # base, and BEFORE the domain half, so no domain file can leak into either. Domain
817
+ # reaches the UI lane through the spec, exactly as it reaches the service lane.
818
+ #
819
+ # The direction is INVERTED from greenfield. There, this half ratifies the project's
820
+ # mapped frontend rule files; here those files do not exist yet, so the evidence is
821
+ # the UI SOURCE — read through the scan substrate — and the project is generated
822
+ # afterwards as the detail layer under whatever this half ratifies. That is the same
823
+ # order the technical tier already uses in this workflow.
824
+
825
+ # Create the UI half from its template — on demand, unlike the other two. Its
826
+ # ABSENCE is meaningful: a repo with no UI never gets the file at all.
827
+ - id: setup_ui_constitution
828
+ action: execute_script
829
+ condition: "{{ui_lane}} == true"
830
+ script: { ref: actions }
831
+ subcommand: setup-constitution
832
+ args: ["--ui", "{{setup_tech_flag}}"]
833
+ outputs:
834
+ - { name: constitution_ui_file, from: "$.constitution_ui_file" }
835
+ - { name: ui_created, from: "$.ui_created" }
836
+
837
+ - id: ctx_ui
838
+ action: build_context
839
+ condition: "{{ui_lane}} == true"
840
+ context:
841
+ - { path: "{{constitution_ui_file}}" } # the target half being filled
842
+ - { path: "{{inventory_json}}" } # PRIMARY: the COMPLETE deterministic substrate — frontend_signals + the UI file lists to read source from
843
+ - { path: .appweaver/orchestrator/rev-templates/ui-constitution.skeleton.md, optional: true } # SHAPE ONLY: heading style, Sync-Impact-Report shape, evidence-line pattern (zero UI content)
844
+ - { path: "{{bundle_dir}}/architecture/frontend.md", optional: true } # SECONDARY (shallow): the OKF as-built frontend note — corroborate, don't rely on alone
845
+ - id: author_ui
846
+ action: agent_author
847
+ condition: "{{ui_lane}} == true"
848
+ include_standards: false
849
+ output_target: { type: file, path: "{{constitution_ui_file}}" }
850
+ task: |
851
+ Scaffold the USER EXPERIENCE constitution — the FRONTEND LANE's half (the target
852
+ file in context) — for **{{project_name}}**, AS-BUILT and PROVISIONAL. It is a
853
+ TEMPLATE with [ALL_CAPS] tokens. This half is domain-AGNOSTIC, like the technical
854
+ base it runs parallel to.
855
+ Why this lane was detected: {{ui_evidence}}
856
+ Lane declaration: {{ui_declaration_note}}
857
+ User hint (optional, may name nothing about the UI): {{USER_INPUT}}
858
+
859
+ EVIDENCE = THE UI CODE ITSELF (deep read). Authority, in order:
860
+ 1. THE ACTUAL UI SOURCE (ground truth). Use {{inventory_json}} (in context):
861
+ `frontend_signals` lists the candidate lane roots with their kind
862
+ (spa / server-rendered / desktop), their framework markers, and their
863
+ component / route / store / style file lists. READ ENOUGH OF THOSE FILES to
864
+ state each principle from what the UI ACTUALLY does. Do NOT assert an
865
+ experience trait you have not seen in the code.
866
+ 2. The OKF architecture/frontend.md note (in context, if present) — SECONDARY,
867
+ shallow corroboration only.
868
+ The `framework_markers` are MARKERS, not conclusions — name the stack from the code.
869
+ Never carry over a principle, a folder convention, an accessibility target or a
870
+ quality gate from a greenfield UI template, another project, or your own experience
871
+ of how frontends are usually governed. If this code does not show it, it is not a
872
+ principle here.
873
+
874
+ EVIDENCE-FIRST — DISCOVER the principle set; do NOT inherit it. The skeleton
875
+ (ui-constitution.skeleton.md, in context) is a NEUTRAL SHAPE REFERENCE ONLY and
876
+ names no framework, router, component library, design system or conformance
877
+ standard. Copy the SHAPE; discover the CONTENT from the code.
878
+ - `## Declared Lane` — name the lane, what it is built with, and the root it owns,
879
+ ALL READ FROM THE CODE. Where the UI is rendered inside the service tree and owns
880
+ no root of its own, say exactly that: it is a legitimate as-built lane, reversed
881
+ in place. Where a declaration exists and disagrees with the code, REPORT the
882
+ disagreement rather than resolving it silently.
883
+ - Author a UX principle ONLY for an experience trait the UI code evidences, and cite
884
+ the evidence inline on each one (e.g. "(evidence: <real component/route/store
885
+ path>)"). State PARTIAL / INCONSISTENT / ABSENT traits at the level the code
886
+ actually reaches — an app with no accessibility attributes does not get an
887
+ accessibility principle written as though it were met.
888
+ - OMIT a concern the UI shows ZERO of. Do NOT create a debt/backlog sink —
889
+ modernization is a separate later phase, and an unmet ideal is simply not asserted.
890
+ - Where the codebase is INCONSISTENT, state the DOMINANT convention as the rule and
891
+ record the divergence with its coordinates. Do not pick a winner the code has not.
892
+ - NUMBER the principles as a UX-* series (UX-I, UX-II, …). Do NOT continue the
893
+ technical half's numbering or the domain half's — this half is PARALLEL to the
894
+ technical base, so its series is unaffected by how many principles that base has.
895
+ - This half stands ALONE as the frontend lane's base: it neither restates the service
896
+ lane's principles nor cites them by number. Add NO domain-specific principle,
897
+ identifier, terminology or regulatory rule — those belong to constitution.domain.md.
898
+ - Keep every path under the lane's own root. This half never adds to the service
899
+ lane's folder structure.
900
+ - The project name is **{{project_name}}** — use it for the title / any [PROJECT_NAME]
901
+ token, so all the halves name the SAME project.
902
+ - Mark the half PROVISIONAL: it is scaffolded from the whole-repo scan, and a later
903
+ adopt / constitution run reconciles it against per-slice evidence.
904
+ - Fill EVERY placeholder; leave no unexplained [BRACKET] (justify a genuine deferral
905
+ as TODO(<FIELD>): reason). Bump CONSTITUTION_VERSION by semver — this half versions
906
+ independently of the other two. ISO YYYY-MM-DD dates (RATIFICATION_DATE = today).
907
+ Preserve heading hierarchy.
908
+ - PREPEND a "Sync Impact Report" HTML comment: version old→new, the lane, the
909
+ DISCOVERED UX principle set, any experience concern DELIBERATELY OMITTED for lack
910
+ of evidence (with why), and dependent artifacts (✅/⚠).
911
+ Return the complete updated UI constitution content only.
912
+
913
+ - id: ui_validation_loop
914
+ action: loop
915
+ condition: "{{ui_lane}} == true"
916
+ while: "{{ui_ok}} != true"
917
+ max_iterations: 3
918
+ steps:
919
+ - id: ui_lint
920
+ action: execute_script
921
+ script: { ref: actions }
922
+ subcommand: constitution-verify
923
+ args: ["--file", "{{constitution_ui_file}}"]
924
+ outputs:
925
+ - { name: ui_ok, from: "$.ok" }
926
+ - { name: ui_issues, from: "$.issues" }
927
+ - id: ui_lint_break
928
+ action: break
929
+ condition: "{{ui_ok}} == true"
930
+ - id: patch_ui
931
+ action: agent_author
932
+ context: ["{{constitution_ui_file}}"]
933
+ include_standards: false
934
+ output_target: { type: file, path: "{{constitution_ui_file}}" }
935
+ task: |
936
+ Fix these mechanical defects in the UI constitution (target file in context),
937
+ changing NOTHING else — preserve every principle, the UX-* numbering, the heading
938
+ hierarchy, and the Sync Impact Report. Fill any listed [ALL_CAPS] placeholder with
939
+ concrete text (or a justified TODO(<FIELD>): reason); make the body's version line
940
+ AGREE with the Sync Impact Report; ISO YYYY-MM-DD dates.
941
+ Defects: {{ui_issues}}
942
+ Return the complete updated UI constitution content only.
943
+
944
+ # The UI half's lint verdict only carries meaning where a lane exists. On a backend-only
945
+ # repo no half was created, so the run reports that rather than a bare false a reader
946
+ # would take for a half that needs a manual touch.
947
+ - id: ui_validation_state_absent
948
+ action: set
949
+ vars: { ui_validation_state: "n/a — no frontend lane, no UI half authored" }
950
+ - id: ui_validation_state_present
951
+ action: set
952
+ condition: "{{ui_lane}} == true"
953
+ vars: { ui_validation_state: "{{ui_ok}}" }
954
+
955
+ # DOMAIN HALF — from the project + charter, principles continue the technical numbering.
956
+ - id: ctx_domain
957
+ action: build_context
958
+ context:
959
+ - { path: "{{constitution_domain_file}}" }
960
+ - { path: "{{constitution_technical_file}}" } # to CONTINUE its numbering (evidenced-only ⇒ not a fixed XV)
961
+ - { path: "{{domain_constitution_source}}" }
962
+ - { path: "{{domain_rule_bindings}}" }
963
+ context_from: project_context
964
+ - id: author_domain
965
+ action: agent_author
966
+ include_standards: false
967
+ output_target: { type: file, path: "{{constitution_domain_file}}" }
968
+ task: |
969
+ Scaffold the DOMAIN ADDENDA constitution for the WHOLE PROJECT **{{project_name}}**
970
+ (domain {{domain_slug}}) — the target file in context — AS-BUILT and PROVISIONAL,
971
+ from the OKF project context (overview, aggregates/index — in context) + the
972
+ domain-constitution source + the generated project (domain-rule-bindings in context; READ
973
+ the project's rule files under guardrails/projects/{{domain_slug}}/). It is a TEMPLATE
974
+ with [ALL_CAPS] tokens; this half carries ONLY domain material.
975
+ - Name the SAME project as the technical half / charter: title / any [PROJECT_NAME]
976
+ token = {{project_name}}. This is a PROJECT constitution, not an aggregate spec —
977
+ govern the domain / bounded context as a whole.
978
+ - Fill EVERY template placeholder — an unfilled one keeps this half out of the
979
+ composed constitution. Brackets of your OWN in the prose are fine: a regulation,
980
+ standard or identifier the domain actually cites is content, not a leftover slot.
981
+ - ADOPTED MODELLING STANDARD: name the methodology the technical half actually
982
+ mandates and cite that principle BY ITS ACTUAL NUMERAL, read from
983
+ constitution.technical.md in context. That half is evidenced-only here, so the
984
+ numeral is whatever the code supported — never a value carried over from another
985
+ constitution. If it mandates no modelling methodology, say so plainly rather than
986
+ supplying one.
987
+ - Author ONLY the domain layer: domain principles, domain folder additions,
988
+ regulatory/security posture, domain governance — from the project + charter. NUMBER
989
+ them by CONTINUING the technical half's roman numerals: READ
990
+ constitution.technical.md (in context), find its LAST numeral N, start the first
991
+ domain principle at N+1 (do NOT assume it ends at XV). TITLE each by DOMAIN
992
+ CONCERN (not a feature name); state which technical principle (by its ACTUAL
993
+ numeral) it EXTENDS. Do NOT restate the technical principles — reference them.
994
+ Mark any principle whose exact rule ids are not yet enumerable `PROVISIONAL —
995
+ reconciled at adopt`.
996
+ - Include a short domain identity / bounded-context map (from the charter).
997
+ - AS-BUILT: the principle is what the code evidences; do NOT introduce a domain
998
+ rule the feature map does not evidence, and do NOT create a debt/backlog.
999
+ - Bump CONSTITUTION_VERSION by semver; ISO YYYY-MM-DD dates. Preserve heading
1000
+ hierarchy. PREPEND a "Sync Impact Report" HTML comment (version old→new, domain
1001
+ principles, dependent artifacts ✅/⚠ + TODOs).
1002
+ Return the complete updated domain addenda content only.
1003
+
1004
+ - id: domain_validation_loop
1005
+ action: loop
1006
+ while: "{{domain_ok}} != true"
1007
+ max_iterations: 3
1008
+ steps:
1009
+ - id: dom_lint
1010
+ action: execute_script
1011
+ script: { ref: actions }
1012
+ subcommand: constitution-verify
1013
+ args: ["--file", "{{constitution_domain_file}}"]
1014
+ outputs:
1015
+ - { name: domain_ok, from: "$.ok" }
1016
+ - { name: domain_issues, from: "$.issues" }
1017
+ - id: dom_lint_break
1018
+ action: break
1019
+ condition: "{{domain_ok}} == true"
1020
+ - id: patch_domain
1021
+ action: agent_author
1022
+ context: ["{{constitution_domain_file}}"]
1023
+ include_standards: false
1024
+ output_target: { type: file, path: "{{constitution_domain_file}}" }
1025
+ task: |
1026
+ Fix these mechanical defects in the domain addenda constitution (target file
1027
+ in context), changing NOTHING else — preserve every principle, the heading
1028
+ hierarchy, and the Sync Impact Report. Fill any listed [ALL_CAPS] placeholder
1029
+ (or a justified TODO(<FIELD>): reason); make the body version AGREE with the
1030
+ Sync Impact Report; ISO YYYY-MM-DD dates.
1031
+ Defects: {{domain_issues}}
1032
+ Return the complete updated domain addenda content only.
1033
+
1034
+ # ── COMPOSE + ACTIVATE ───────────────────────────────────────────────────────
1035
+ - id: compose_constitution
1036
+ action: execute_script
1037
+ script: { ref: actions }
1038
+ subcommand: compose-constitution
1039
+ outputs:
1040
+ - { name: composed_file, from: "$.composed_file" }
1041
+ - { name: domain_included, from: "$.domain_included" }
1042
+ # The UI half appends after the two roman-numeral halves and runs its own UX-*
1043
+ # series, so it never enters the numbering check below.
1044
+ - { name: ui_included, from: "$.ui_included" }
1045
+ - { name: numbering_ok, from: "$.numbering_ok" }
1046
+ - { name: numbering_issues, from: "$.issues" }
1047
+ - { name: technical_last, from: "$.technical_last" }
1048
+ - { name: domain_first, from: "$.domain_first" }
1049
+
1050
+ # Numbering gate — the twin of the greenfield constitution workflow's. Brownfield
1051
+ # needs it MORE, not less: the technical half here is evidenced-only, so its length is
1052
+ # discovered from the code rather than fixed by a mapped base, and the domain half is
1053
+ # authored in the same run against a numeral it has just been told to read. Announce
1054
+ # and continue: both halves are written and the composed view shows the clash.
1055
+ # Ordered override — the var holds "ok" unless the check reported a problem, because
1056
+ # require_non_empty reports on EMPTY.
1057
+ - id: numbering_default
1058
+ action: set
1059
+ vars: { numbering_gate: "ok" }
1060
+ - id: numbering_detect
1061
+ action: set
1062
+ condition: "{{numbering_ok}} == false"
1063
+ vars: { numbering_gate: "" }
1064
+ - id: numbering_warning
1065
+ action: verify_context
1066
+ require_non_empty: numbering_gate
1067
+ on_empty: continue
1068
+ on_empty_message: >
1069
+ Principle numbering does not run cleanly across the reverse-engineered halves:
1070
+ {{numbering_issues}} (technical half ends at {{technical_last}}, domain half starts
1071
+ at {{domain_first}}). The technical half is evidenced-only, so its last numeral is
1072
+ whatever the code actually supported — the domain half must resume from the number
1073
+ FOLLOWING it, never from a fixed value. Renumber the domain half in
1074
+ .appweaver/memory/constitution.domain.md and re-run compose; the composed
1075
+ constitution.md was still written so the clash is visible.
1076
+
1077
+ # Auto-activate: point .appweaver/domain.json at the scaffolded project so the forward CR
1078
+ # loop governs development with it from the first change.
1079
+ - id: activate_domain
1080
+ action: execute_script
1081
+ script: { ref: actions }
1082
+ subcommand: set-domain
1083
+ args: ["--domain", "{{domain_slug}}"]
1084
+ outputs:
1085
+ - { name: active_domain, from: "$.domain" }
1086
+ - { name: map_exists, from: "$.map_exists" }
1087
+
1088
+ # ═══════════ TECHNICAL RULE SET (code-derived) — the technical twin of the ═══════
1089
+ # domain set above. This is what stops adopt AND the whole forward
1090
+ # pipeline from falling back to greenfield technical rules.
1091
+ #
1092
+ # Runs AFTER the technical constitution is authored + validated (technical_validation_loop)
1093
+ # so its ratified principles are on hand: each generated tech rule file is the DETAIL layer
1094
+ # under a constitution.technical.md principle (thin ratified line ↑ / enforceable rule ↓).
1095
+ # Evidence = the CODE (deep read via inventory_json's file lists) + the validated technical
1096
+ # constitution + the shallow platform note (corroboration only). Writes:
1097
+ # 1. guardrails/projects/<domain>/service/<concern>.md — evidenced-only code-derived tech rule
1098
+ # files (the ANALOG of a greenfield project's architecture · security · governance set, but reverse-
1099
+ # engineered from THIS code, never a greenfield file), INCLUDING the one file that
1100
+ # feeds /specify: service/domain-modelling.md, the as-built modelling METHODOLOGY (the
1101
+ # analog of the greenfield corpus's technology/<stack>/domain-driven-design.md). Without it brownfield
1102
+ # specify has a model but no HOW-to-model standard, and models a NEW feature in a
1103
+ # different idiom than the code it joins, and
1104
+ # 2. guardrails/projects/<domain>/tech-rule-bindings.md — the TECHNICAL map (resolve-tech +
1105
+ # tech-select read it by that exact name), wiring the generated files per-workflow.
1106
+ # Because onboard already ACTIVATED brf-<domain>, the forward pipeline's + adopt's tech_select
1107
+ # steps now resolve to THESE files — never another project's rules, ever. The project
1108
+ # lives inside pack_dir, so pack_guard (above) already protects it from clobber.
1109
+ - id: ctx_tech_pack
1110
+ action: build_context
1111
+ condition: "{{svc_lane}} == true"
1112
+ context:
1113
+ - { path: "{{inventory_json}}" } # PRIMARY: the COMPLETE deterministic substrate — read representative SOURCE from its file lists
1114
+ - { path: "{{constitution_technical_file}}" } # PRIMARY: the VALIDATED as-built technology base — the ratified principles these files detail
1115
+ - { path: .appweaver/orchestrator/rev-templates/tech-rule-bindings.skeleton.md, optional: true } # SHAPE ONLY: the technical map's headings + partition + table (zero real files)
1116
+ - { path: .appweaver/orchestrator/rev-templates/technical-rule-file.skeleton.md, optional: true } # SHAPE ONLY: one code-derived tech rule file's shape (zero real tech)
1117
+ - { path: .appweaver/RULE-PARTITION.md } # the rule-partition authority (which command reads what)
1118
+ - { path: "{{bundle_dir}}/architecture/platform.md", optional: true } # SECONDARY (shallow): the OKF as-built platform note — corroborate, don't rely on alone
1119
+ context_from: design_context
1120
+ - id: author_tech_pack
1121
+ action: agent_generate
1122
+ condition: "{{svc_lane}} == true"
1123
+ tools: "Read,Write,Edit"
1124
+ permission_mode: acceptEdits
1125
+ task: |
1126
+ Scaffold the PROJECT-level TECHNICAL RULE SET for **{{project_name}}** (domain
1127
+ {{domain_slug}}) — the CODE-DERIVED replacement for the greenfield technical rule set —
1128
+ into guardrails/projects/{{domain_slug}}/service/ (create it), plus the technical map
1129
+ guardrails/projects/{{domain_slug}}/tech-rule-bindings.md. This is the TECHNICAL twin of the
1130
+ already-generated domain set: it feeds the HOW phases (design/implement/build/…) plus
1131
+ ONE modelling-methodology file for /specify (see domain-modelling below) — and nothing
1132
+ else ever reaches /specify from this tier.
1133
+
1134
+ EVIDENCE = THE CODE ITSELF (deep read) + THE VALIDATED TECHNICAL CONSTITUTION. Authority,
1135
+ in order:
1136
+ 1. THE ACTUAL SOURCE CODE (ground truth). Use {{inventory_json}} (in context) to locate
1137
+ representative files across top_level_dirs + a few aggregate_signals, and Read enough
1138
+ to state each technical rule from what the code ACTUALLY does — the folder/tier/module
1139
+ convention, the dependency direction, the persistence approach, concurrency handling,
1140
+ testing convention, the auth/cross-cutting posture. Do NOT assert structure you have
1141
+ not seen in the code.
1142
+ 2. constitution.technical.md (in context) — the VALIDATED as-built technology base. Each
1143
+ generated tech rule file is the DETAIL under one of ITS principles; cite the principle
1144
+ numeral on the rules it details. Never contradict it; never restate it wholesale.
1145
+ 3. The OKF platform.md (in context, if present) — SECONDARY, shallow corroboration only.
1146
+ NEVER reference, read, copy, or list a rule file belonging to another project
1147
+ (guardrails/projects/<other>/**) — those are the
1148
+ greenfield fixture, NOT this project's rules. Every path you write lives under
1149
+ guardrails/projects/{{domain_slug}}/service/.
1150
+
1151
+ CONCERNS HINT: {{USER_INPUT}} may carry a "concerns: a, b, c" clause. Treat any listed
1152
+ concern as a SEARCH HINT — look for it in the code — but DECIDE presence from evidence:
1153
+ write a tech rule file for a concern ONLY if the code exhibits it, drop a listed concern
1154
+ the code shows none of, and ADD an unlisted concern the code clearly evidences. Ignore any
1155
+ non-concerns text.
1156
+
1157
+ EVIDENCED-ONLY (lean). Write a `service/<concern>.md` ONLY for a technology concern the code
1158
+ actually exhibits — e.g. as-built-architecture, persistence, concurrency, testing,
1159
+ security-posture, api-surface, eventing, observability, hosting. Follow the SHAPE of
1160
+ technical-rule-file.skeleton.md (in context): frontmatter (origin: reverse-engineered,
1161
+ generated_by: aw-spec-onboard/1.6.0, concern), a one-line framing, rules each citing a CODE
1162
+ COORDINATE (real file/folder path or named type) + the constitution principle numeral where
1163
+ it maps. The skeleton carries NO real technology — copy the shape only. State stubs/partials
1164
+ AS-BUILT (do not upgrade a stub into a greenfield ideal); omit a concern the code shows none
1165
+ of (migration is a separate later phase — no debt/backlog sink here).
1166
+
1167
+ PLUS ONE SPECIAL FILE — `service/domain-modelling.md` (concern: domain-modelling). This is the
1168
+ ONE file in this project that feeds /specify, and it is a MODELLING METHODOLOGY: HOW this
1169
+ codebase expresses a domain model, not WHAT the model is (the model itself is the domain
1170
+ project's domain-model file, already written — do NOT restate or duplicate it).
1171
+ Read the code and state the AS-BUILT modelling conventions, each citing a code coordinate:
1172
+ - what marks an aggregate root, and how a root is reached (base class / marker interface
1173
+ / naming), plus the identity convention (typed id? primitive? value object?);
1174
+ - entity vs value object — how the code distinguishes them, and where each lives;
1175
+ - where invariants actually live (root method / domain service / validator / DB
1176
+ constraint) — state what the code DOES, even if that is "enforced in the handler";
1177
+ - the bounded-context / module boundary and what may cross it (ids only? DTOs? entities?);
1178
+ - domain events, if the code has them: what raises one, and where it is dispatched;
1179
+ - the naming/ubiquitous-language convention the code visibly follows.
1180
+ Write it even when the conventions are partial or inconsistent — say so AS-BUILT and cite
1181
+ the divergent coordinates; that is exactly what /specify needs in order to model a NEW
1182
+ feature the way this codebase already models. Contains NO business vocabulary and NO
1183
+ technology/architecture rules (those are the other files). Omit this file ONLY if the code
1184
+ has no discernible domain model at all (e.g. a pure script/ETL repo).
1185
+
1186
+ tech-rule-bindings.md (MANDATORY — resolve-tech + the tech-select module read this exact
1187
+ filename). Follow the SHAPE of tech-rule-bindings.skeleton.md (in context) and the rule
1188
+ partition (.appweaver/RULE-PARTITION.md, in context). Wire ONLY files you generated, under these headings, and
1189
+ ONLY a heading you have a generated file for (an absent heading soft-continues → loads
1190
+ nothing):
1191
+ - `## /aw-spec-specify` — EXACTLY ONE bullet: `service/domain-modelling.md`, the modelling methodology. NEVER an architecture / persistence / codegen / security file here — specify is the domain phase and any technology rule under this heading breaks its domain purity. Omit the heading only if you did not write domain-modelling.md.
1192
+ - `## /aw-spec-design` — the as-built architecture / cross-cutting rules the design author mediates the spec against.
1193
+ - `## /aw-spec-implement` — the code-generation / convention set the generator builds against (from design.md).
1194
+ - `## /aw-spec-implement-delta` — the same code-generation set, scoped to a change's delta-design.
1195
+ - `## /aw-spec-build` — the layering + convention rules the compile-fixer respects.
1196
+ - `## /aw-spec-analyze-slice` — the conformance rules the design↔code gate validates against.
1197
+ - `## /aw-spec-adopt` — the technical reference set the reversed design mediates against (a subset of design's).
1198
+ - `## /aw-spec-constitution` — the standards a later `/appweaver constitution` re-ratifies the TECHNICAL half from. You authored that half from code evidence before these files existed; this heading is what makes a re-run author from THIS project's rules rather than from an empty set. Ratifiable standards only, no worked `examples/` sample, no domain file.
1199
+ - `## /aw-spec-run` — the runtime / execution conventions the app-run step honors (add ONLY if the code evidences a runtime/hosting concern file; NOT data-migration — migration is the deferred later phase).
1200
+ Each bullet is a
1201
+ workspace-relative path `- guardrails/projects/{{domain_slug}}/service/<file>`. Close with the
1202
+ quick-reference table. Write ONLY inside guardrails/projects/{{domain_slug}}/ (service/ + the map);
1203
+ modify no source. Report the files written + the concerns you found present (with the code
1204
+ paths that evidence them).
1205
+ outputs:
1206
+ - { name: tech_pack_files, from: "$.files" }
1207
+
1208
+ - id: verify_tech_pack
1209
+ action: verify_context
1210
+ condition: "{{svc_lane}} == true"
1211
+ require_non_empty: tech_pack_files
1212
+ on_empty: stop
1213
+ on_empty_message: "No technical rule files were written to guardrails/projects/{{domain_slug}}/service/. Ensure the scan substrate (inventory_json) + the validated technical constitution carry an as-built technology base and re-run."
1214
+ - id: require_tech_rule_bindings
1215
+ action: verify_context
1216
+ required_files: ["{{pack_dir}}/tech-rule-bindings.md"]
1217
+
1218
+ # Did the modelling methodology reach /specify? The map is the only route this tier has
1219
+ # into the domain phase, and `## /aw-spec-specify` carrying service/domain-modelling.md
1220
+ # is what stops brownfield specify from modelling a new feature in a different idiom
1221
+ # than the code it joins. Read it back through the same resolver /specify uses — the
1222
+ # project is already activated, so this asks the question exactly as specify will.
1223
+ # Announce, don't stop: a repo with no discernible domain model legitimately has no such
1224
+ # file, and the run's remaining work is worth keeping either way.
1225
+ - id: probe_specify_wiring
1226
+ action: execute_script
1227
+ condition: "{{svc_lane}} == true"
1228
+ on_error: continue
1229
+ script: { ref: actions }
1230
+ subcommand: resolve-tech
1231
+ args: ["--command", "aw-spec-specify"]
1232
+ outputs:
1233
+ - { name: specify_rules, from: "$.candidates" }
1234
+ - id: warn_specify_wiring
1235
+ action: verify_context
1236
+ condition: "{{svc_lane}} == true"
1237
+ require_non_empty: specify_rules
1238
+ on_empty: continue
1239
+ on_empty_message: >
1240
+ guardrails/projects/{{domain_slug}}/tech-rule-bindings.md maps nothing under
1241
+ `## /aw-spec-specify`, so brownfield specify will model new features with no
1242
+ as-built modelling methodology to follow. That is correct only where the code has no
1243
+ discernible domain model (a pure script/ETL repo). Otherwise add
1244
+ service/domain-modelling.md — HOW this codebase expresses a domain model, not what
1245
+ the model is — and wire it as the single bullet under that heading.
1246
+
1247
+ # ═══════════ FRONTEND RULE SET (code-derived) — the LANE's tier ════════════════
1248
+ # The third generated project, written only where the code has a UI. It is the DETAIL
1249
+ # layer under the UX-* principles the half above ratified (thin ratified line ↑ /
1250
+ # enforceable rule ↓), exactly as service/ is the detail layer under the technical half.
1251
+ #
1252
+ # Runs AFTER the technical set because both write the SAME map file: the technical set
1253
+ # authors tech-rule-bindings.md, and this step APPENDS the lane's heading to it. That
1254
+ # heading is what makes a later /appweaver constitution re-ratify the UI half from
1255
+ # THIS project's lane rules — and it is also the authoritative signal that the project
1256
+ # HAS a frontend lane, so writing it is what lets the greenfield constitution command
1257
+ # find the lane on every future run without stacks.json or a named stack.
1258
+ - id: ctx_ui_pack
1259
+ action: build_context
1260
+ condition: "{{ui_lane}} == true"
1261
+ context:
1262
+ - { path: "{{inventory_json}}" } # PRIMARY: the COMPLETE deterministic substrate — frontend_signals + the UI file lists to read source from
1263
+ - { path: "{{constitution_ui_file}}" } # PRIMARY: the VALIDATED as-built UX-* base — the ratified principles these files detail
1264
+ - { path: "{{pack_dir}}/tech-rule-bindings.md" } # the map to APPEND to — read it so the edit preserves what the technical set wrote
1265
+ - { path: .appweaver/orchestrator/rev-templates/frontend-rule-file.skeleton.md, optional: true } # SHAPE ONLY: one code-derived lane rule file's shape (zero real UI tech)
1266
+ - { path: .appweaver/orchestrator/rev-templates/tech-rule-bindings.skeleton.md, optional: true } # SHAPE ONLY: the technical map's headings + partition + table
1267
+ - { path: .appweaver/RULE-PARTITION.md } # the rule-partition authority (which command reads what)
1268
+ - { path: "{{bundle_dir}}/architecture/frontend.md", optional: true } # SECONDARY (shallow): the OKF as-built frontend note
1269
+ - id: author_ui_pack
1270
+ action: agent_generate
1271
+ condition: "{{ui_lane}} == true"
1272
+ tools: "Read,Write,Edit"
1273
+ permission_mode: acceptEdits
1274
+ task: |
1275
+ Scaffold the PROJECT-level FRONTEND RULE-FILE PACK for **{{project_name}}** (domain
1276
+ {{domain_slug}}) — the CODE-DERIVED lane rules — into
1277
+ guardrails/projects/{{domain_slug}}/frontend/ (create it), and WIRE it into the existing
1278
+ guardrails/projects/{{domain_slug}}/tech-rule-bindings.md. This is the FRONTEND LANE's
1279
+ twin of the service/ set you have already generated: it is the detail layer under
1280
+ constitution.ui.md's UX-* principles, and it governs only code under the lane's root.
1281
+
1282
+ EVIDENCE = THE UI CODE ITSELF (deep read) + THE VALIDATED UI CONSTITUTION. Authority,
1283
+ in order:
1284
+ 1. THE ACTUAL UI SOURCE (ground truth). Use {{inventory_json}} (in context):
1285
+ `frontend_signals` gives the lane roots, their kind, their framework markers and
1286
+ their component / route / store / style file lists. Read enough of those files to
1287
+ state each rule from what the UI ACTUALLY does. Do NOT assert a convention you
1288
+ have not seen in the code.
1289
+ 2. constitution.ui.md (in context) — the VALIDATED as-built UX-* base. Each file
1290
+ here is the DETAIL under one of ITS principles; cite the UX numeral on the rules
1291
+ it details. Never contradict it; never restate it wholesale.
1292
+ 3. The OKF architecture/frontend.md (in context, if present) — SECONDARY, shallow.
1293
+ NEVER reference, read, copy, or list a rule file belonging to another project
1294
+ (guardrails/projects/<other>/**) — those are the greenfield fixture, NOT this project's
1295
+ rules. Never carry over a convention, an accessibility target, a folder taxonomy or a
1296
+ quality gate from a greenfield UI rule file or from how frontends are usually built.
1297
+ Every path you write lives under guardrails/projects/{{domain_slug}}/frontend/.
1298
+
1299
+ EVIDENCED-ONLY (lean). Follow the SHAPE of frontend-rule-file.skeleton.md (in context):
1300
+ frontmatter (origin: reverse-engineered, generated_by: aw-spec-onboard/1.6.0, concern),
1301
+ a one-line framing, then rules each citing a CODE COORDINATE (a real component / route /
1302
+ store / stylesheet / config path) and the UX principle numeral where it maps.
1303
+ - `frontend/ui-constitution.md` — ALWAYS, the lane's base file: the lane declaration
1304
+ (id, what it is built with, the root it owns, whether it is separable or rendered
1305
+ inside the service tree) plus the whole-lane rules. This is the file a later
1306
+ /appweaver constitution re-ratifies the UI half from, so it must stand on its own.
1307
+ - Then a `frontend/<concern>.md` ONLY for an experience concern the UI code actually
1308
+ exhibits — e.g. component-model, routing-and-navigation, state-and-data,
1309
+ styling-and-design-system, accessibility, interaction-states, forms-and-validation,
1310
+ internationalization, performance, ui-testing. Drop any the code shows none of; add
1311
+ any it clearly evidences that is not on that list.
1312
+ State inconsistency AS-BUILT: give the DOMINANT convention as the rule and record the
1313
+ divergence with its coordinates. Do not upgrade a partial into a greenfield ideal, and
1314
+ do not create a debt/backlog sink — modernization is a separate later phase.
1315
+
1316
+ WIRE THE MAP — EDIT guardrails/projects/{{domain_slug}}/tech-rule-bindings.md IN PLACE.
1317
+ It already exists and carries the technical headings you wrote; PRESERVE all of them
1318
+ byte-for-byte. Make exactly two additions:
1319
+ 1. A `## /aw-spec-ui-constitution` section, placed after the last technical heading
1320
+ and BEFORE the closing quick-reference table. Bullet ONLY the frontend files you
1321
+ just generated, `frontend/ui-constitution.md` first, each as a workspace-relative
1322
+ path `- guardrails/projects/{{domain_slug}}/frontend/<file>`. Ratifiable lane
1323
+ standards only — no domain file, no technical file, no example. Precede them with
1324
+ a short HTML comment saying what this half ratifies and that the heading is also
1325
+ the authoritative signal that the project has a frontend lane.
1326
+ 2. Its row in the quick-reference table, in the same format as the existing rows.
1327
+ Do NOT add `## /aw-spec-ui-design` or `## /aw-spec-ui-implement`: those commands do not
1328
+ exist yet, and a heading mapping files for a command nobody runs is a claim the kit
1329
+ cannot honour. They arrive with the UI lane's own phases.
1330
+
1331
+ Write ONLY inside guardrails/projects/{{domain_slug}}/ (frontend/ + the map edit); modify
1332
+ no source. Report the files written, the concerns you found present with the code paths
1333
+ that evidence them, and the concerns you deliberately omitted.
1334
+ outputs:
1335
+ - { name: ui_pack_files, from: "$.files" }
1336
+
1337
+ - id: verify_ui_pack
1338
+ action: verify_context
1339
+ condition: "{{ui_lane}} == true"
1340
+ require_non_empty: ui_pack_files
1341
+ on_empty: stop
1342
+ on_empty_message: "A frontend lane was detected ({{ui_evidence}}) but no lane rule files were written to guardrails/projects/{{domain_slug}}/frontend/. Check that the scan substrate's frontend_signals carry readable UI source, then re-run."
1343
+
1344
+ # Did the lane's heading land in the map? The files above are only half the wiring:
1345
+ # `## /aw-spec-ui-constitution` is what a later /appweaver constitution re-ratifies
1346
+ # the UI half from, and it is the authoritative signal that this project HAS a lane.
1347
+ # Written by an in-place edit, so read it back through the resolver that will look for
1348
+ # it. Announce, don't stop — the rule files are on disk and the heading is one edit away.
1349
+ - id: probe_ui_wiring
1350
+ action: execute_script
1351
+ condition: "{{ui_lane}} == true"
1352
+ on_error: continue
1353
+ script: { ref: actions }
1354
+ subcommand: resolve-tech
1355
+ args: ["--command", "aw-spec-ui-constitution"]
1356
+ outputs:
1357
+ - { name: ui_map_rules, from: "$.candidates" }
1358
+ - id: warn_ui_wiring
1359
+ action: verify_context
1360
+ condition: "{{ui_lane}} == true"
1361
+ require_non_empty: ui_map_rules
1362
+ on_empty: continue
1363
+ on_empty_message: >
1364
+ The lane rule files were written to guardrails/projects/{{domain_slug}}/frontend/,
1365
+ but guardrails/projects/{{domain_slug}}/tech-rule-bindings.md maps nothing under
1366
+ `## /aw-spec-ui-constitution`. Without that heading a later /appweaver
1367
+ constitution finds no lane rules to re-ratify the UI half from, and reads this
1368
+ project as backend-only. Add the heading after the last technical one, bulleting
1369
+ frontend/ui-constitution.md first, then the rest of the frontend/ set.
1370
+
1371
+ # ═══════════ LANE DECLARATION — read back, never written ═══════════════════════
1372
+ # onboard does not declare lanes. It used to: before select-stack was the first
1373
+ # command of this sequence, a repo could arrive here with no declaration at all, so
1374
+ # onboard ran its own detection pass and recorded what it found, marked
1375
+ # `origin: reverse-engineered` and gated never to overwrite a lane a person had
1376
+ # confirmed. With the declaration now REQUIRED at the top of this workflow — it is
1377
+ # what told the scan which subtrees to read — that gate can never open, and the
1378
+ # detection pass was re-deriving an answer the run already had.
1379
+ #
1380
+ # So `lane-declare` is the sole writer again, with one caller: select-stack, where a
1381
+ # person picks. That is a stronger property than the two-caller version, and it is
1382
+ # still a grep rather than a convention.
1383
+ #
1384
+ # What remains is a read-back through the same reader every other workflow uses, so
1385
+ # the run reports the lanes it actually scanned under rather than a second opinion
1386
+ # about them.
1387
+ - id: lane_readback
1388
+ action: execute_script
1389
+ on_error: continue
1390
+ script: { ref: actions }
1391
+ subcommand: lane-resolve
1392
+ outputs:
1393
+ - { name: stacks_file, from: "$.path" }
1394
+ - { name: declared_lanes, from: "$.lanes" }
1395
+ - { name: be_lane_root, from: "$.backend_source_path" }
1396
+ - { name: be_lane_profile, from: "$.backend_profile" }
1397
+ - { name: fe_lane_root, from: "$.frontend_source_path" }
1398
+ - { name: fe_lane_profile, from: "$.frontend_profile" }
1399
+
1400
+ # ═══════════ CODE-DERIVED DESIGN TEMPLATES (reverse-engineered) ═══════════════
1401
+ # Runs LAST in onboard — AFTER the governance tier is authored + validated + composed
1402
+ # (compose_constitution above) — so the strongest reverse-engineered evidence is on hand:
1403
+ # the ACTUAL SOURCE CODE + the deterministic scan substrate (inventory_json) + the
1404
+ # VALIDATED technical constitution (the as-built technology base). Establish this repo's
1405
+ # DESIGN CONVENTION by REVERSE-ENGINEERING its own technical structure into a project-
1406
+ # specific design + delta-design template pair, written to the PROJECT-LEVEL override slot
1407
+ # (.appweaver/templates/overrides/{design,delta-design}-template.md — resolve_template
1408
+ # Priority-1). The forward `design` phase's brownfield branch (design-scaffold reports
1409
+ # override_active ⇒ design_mode == bootstrap_bf) then authors EVERY new feature against the
1410
+ # as-built architecture, and a CHANGE authors its delta-design against the SAME code-derived
1411
+ # sections (cr-setup scaffolds the delta from resolve_template("delta-design-template") ⇒
1412
+ # the override) — no adopt required, consistent with the master design.md adopt emits.
1413
+ #
1414
+ # GROUNDED IN CODE + REVERSE-ENGINEERED FILES ONLY. The Part-1 OKF feature map is a SHALLOW
1415
+ # discovery index (by design — NOT a deep reverse), so it is NOT the authority: the section
1416
+ # skeleton is derived from the CODE itself + inventory_json (complete, deterministic) + the
1417
+ # validated technical constitution, with the OKF map as secondary corroboration.
1418
+ #
1419
+ # NO GREENFIELD TEMPLATE IS IN CONTEXT — this tier reads a NEUTRAL SKELETON from
1420
+ # rev-templates/, exactly as the constitution halves and both rule sets already do. The
1421
+ # greenfield design templates carry a Domain/Application/API/Infrastructure layering in
1422
+ # their headings, their example rows and their authoring prose, and a prompt telling an
1423
+ # author not to copy the exemplar in front of it is the weakest control this kit has.
1424
+ # rev-templates/{design,delta-design}-template.skeleton.md carry the SAME neutral bones
1425
+ # (header block, the §1.2 domain/data-model anchor, the traceability spine, the two
1426
+ # deferral ledgers, Change History, the tech-agnostic authoring rules) with the layering
1427
+ # removed and every structural section left as a slot the code fills. The generated
1428
+ # template keeps the §0–§6 shape the forward `design` bootstrap_bf branch expects and the
1429
+ # two anchors aw-xref keys on, so no workflow change is needed to consume it.
1430
+ #
1431
+ # WHERE A FRONTEND LANE EXISTS the lane gets its OWN pair (ui-design-template +
1432
+ # ui-delta-design-template, below), so this pair covers the SERVICE lane only and excludes
1433
+ # the lane's roots from the structure it derives. One lane's template never describes the
1434
+ # other's code. Re-onboard is gated upstream (bundle_guard / pack_guard) — remove the OKF
1435
+ # bundle to regenerate.
1436
+
1437
+ # DESIGN template — the code-derived evidence (code + inventory + technical constitution)
1438
+ # plus a NEUTRAL skeleton for the bones. No greenfield template is in context.
1439
+ - id: ctx_design_template
1440
+ action: build_context
1441
+ condition: "{{svc_lane}} == true"
1442
+ context:
1443
+ - { path: "{{inventory_json}}" } # PRIMARY: the COMPLETE deterministic substrate (top_level_dirs, aggregate_signals' per-layer file groupings) — the OKF markdown only SUMMARISES this
1444
+ - { path: "{{constitution_technical_file}}" } # PRIMARY: the VALIDATED as-built technology base (framework/persistence/concurrency/hosting/testing/cross-cutting)
1445
+ - { path: .appweaver/orchestrator/rev-templates/design-template.skeleton.md } # SHAPE ONLY: the neutral bones + the pinned anchors + tech-agnostic authoring rules (zero layering, zero technology)
1446
+ - { path: .appweaver/DESIGN-FORMAT.md } # the HLD contract + its Brownfield variant note (which anchors are pinned, and why)
1447
+ - { path: "{{bundle_dir}}/architecture/platform.md", optional: true } # SECONDARY (shallow): the OKF as-built platform note — corroborate, don't rely on alone
1448
+ - { path: "{{bundle_dir}}/architecture/overview.md", optional: true } # SECONDARY (shallow): the OKF feature map + stack
1449
+ - { path: "{{bundle_dir}}/aggregates/index.md", optional: true } # SECONDARY (shallow): the bounded-context / feature map
1450
+ - id: gen_design_template
1451
+ action: agent_generate
1452
+ condition: "{{svc_lane}} == true"
1453
+ tools: "Read,Write,Edit"
1454
+ permission_mode: acceptEdits
1455
+ task: |
1456
+ REVERSE-ENGINEER this repo's design convention into a PROJECT-SPECIFIC design
1457
+ TEMPLATE and Write it to .appweaver/templates/overrides/design-template.md (create the
1458
+ overrides/ dir if absent). It is a TEMPLATE — concrete project-derived section HEADERS
1459
+ with [PLACEHOLDER] tokens + authoring HTML comments the forward `design` phase fills
1460
+ per feature — NOT a filled design.
1461
+
1462
+ GROUND EVERYTHING IN THE CODE + THE REVERSE-ENGINEERED FILES — not the shallow OKF map
1463
+ and not any architecture you know from elsewhere. Evidence authority, in order:
1464
+ 1. THE ACTUAL SOURCE CODE (ground truth). Read REPRESENTATIVE source files across the
1465
+ repo's top_level_dirs and a few aggregate_signals (from {{inventory_json}}) — enough
1466
+ to CONFIRM from the code the recurring folder/tier/module convention + the dependency
1467
+ direction it actually follows. Do NOT assert structure you have not seen in the code.
1468
+ 2. {{inventory_json}} — the COMPLETE deterministic scan substrate (top_level_dirs, each
1469
+ aggregate_signal's files grouped by layer, categories, tech stack). The OKF markdown
1470
+ only SUMMARISES this, shallowly — prefer the substrate + the code over it.
1471
+ 3. The TECHNICAL CONSTITUTION (constitution.technical.md, in context) — the VALIDATED
1472
+ as-built technology base (framework, persistence, concurrency, hosting, testing,
1473
+ cross-cutting posture). It is the authority for §1.1 As-Built Architecture + §3.
1474
+ 4. The OKF platform.md / overview.md / aggregates/index.md (in context, if present) —
1475
+ SECONDARY, shallow corroboration only (Part 1 is a discovery map, NOT a deep
1476
+ reverse). Never rely on them alone.
1477
+
1478
+ THE SKELETON IS SHAPE ONLY. rev-templates/design-template.skeleton.md (in context)
1479
+ carries the neutral bones, the pinned anchors and the authoring rules — and NO layering,
1480
+ NO architecture style and NO technology, because naming one would answer the question
1481
+ this step exists to ask the code. Copy the SHAPE; discover the STRUCTURE. Never carry a
1482
+ Domain/Application/API/Infrastructure layering — or any other reference architecture —
1483
+ into §1.1 or §2 from memory. DESIGN-FORMAT.md (in context, § Brownfield variant) states
1484
+ which anchors are pinned and why.
1485
+
1486
+ SERVICE LANE ONLY. Frontend lane roots this repo has: {{frontend_roots}} (empty = none).
1487
+ Where that is non-empty, EXCLUDE those roots when deriving the structure — the lane has
1488
+ its own design template pair, generated next, and one lane's template must never describe
1489
+ the other's code. A UI tier that is NOT a separable lane (rendered inside the service
1490
+ tree) stays here as one of this project's own structural axes.
1491
+
1492
+ Identify the RECURRING structural convention across features (the real layer/tier/module
1493
+ folders + the dependency rule) from evidence 1–3 — this ONE template governs every
1494
+ future feature.
1495
+
1496
+ Then AUTHOR the template on the skeleton's §0–§6 shape (the shape the forward `design`
1497
+ brownfield branch expects — keep these section numbers + headings):
1498
+ - Keep the skeleton's header block (Aggregate / Design home / Source spec / Version /
1499
+ Status) and its TECHNOLOGY-AGNOSTIC authoring rules (behaviour as signatures +
1500
+ pre/post/invariant/raises, contracts as field shapes, NO code; every element traces to
1501
+ a spec id). Fill [GENERATED_STRUCTURE_NOTE] with this project's convention.
1502
+ - §0 Design Overview + `### Ubiquitous Language (design delta)` — carry over as-is.
1503
+ - §1 Architecture Context & Domain Model:
1504
+ §1.1 As-Built Architecture — describe THIS project's real structural convention you
1505
+ discovered FROM THE CODE + the technical constitution (name the actual layer/tier/
1506
+ module folders with representative code paths, the dependency direction, the tech
1507
+ base). A new feature ALIGNS to this.
1508
+ §1.2 Domain / Data Model — PINNED ANCHOR, carry the skeleton's guidance over
1509
+ unchanged (entities & value objects = spec Key Entities; invariants = spec BR-nnn;
1510
+ aggregate boundary; lifecycle/states; cross-slice references-by-id). aw-xref reads
1511
+ this section for reference edges, so it keeps its position.
1512
+ - §2 Component & Behaviour Design — ONE `### 2.n` subsection PER RECURRING STRUCTURAL
1513
+ AXIS the project actually uses, each TITLED after the project's OWN folder/tier name.
1514
+ The count and the titles are the code's answer; the skeleton's slots are positions, not
1515
+ a set to fill. In each, template the components that live there + their behaviour in
1516
+ signature form + the ports/contracts. Keep exactly one subsection whose heading
1517
+ contains the word "Integration" (the External Integrations table — one port/adapter row
1518
+ per IC-): aw-xref matches it by keyword, so it is pinned regardless of layout.
1519
+ - §3 Cross-Cutting Concerns — one row per concern THIS project's governance carries, read
1520
+ from the technical constitution (Serves = a spec id or a §5 DA-n). Do not import a
1521
+ standard concern list the constitution does not evidence.
1522
+ - §4 Traceability — carry the skeleton's spine over (every FR/BR/CN/DC/IC/US/SC has a
1523
+ design home; the Section column uses the project's OWN section refs).
1524
+ - §5 Assumptions (DA-n) — carry over, "None (as of vX.Y)".
1525
+ - §6 Deviations / Deferred Decisions (WA-n) — carry over, AS-BUILT: it records genuine
1526
+ deviations, NOT "organised unlike a reference architecture" (that is the as-built
1527
+ shape, §1.1).
1528
+ - Change History — carry over.
1529
+ Keep every [PLACEHOLDER] and authoring comment so `design` can fill it — and in those
1530
+ comments DIRECT the downstream author (forward `design` / adopt) to GROUND each filled
1531
+ section in the ACTUAL CODE + the reverse-engineered files (cite real file/folder paths and
1532
+ the relevant technical-constitution principle). Do NOT invent project structure the code
1533
+ does not show; where the convention is unclear, template a generic axis and flag it in a
1534
+ comment. Write ONLY the override file; modify no source.
1535
+ Report the file written + the structural axes you derived (with the code paths that
1536
+ evidence them).
1537
+ outputs:
1538
+ - { name: design_template_files, from: "$.files" }
1539
+
1540
+ - id: verify_design_template
1541
+ action: verify_context
1542
+ condition: "{{svc_lane}} == true"
1543
+ require_non_empty: design_template_files
1544
+ on_empty: stop
1545
+ on_empty_message: "No design template was written to .appweaver/templates/overrides/design-template.md. Ensure the scan substrate (inventory_json) + the technical constitution are present and re-run."
1546
+
1547
+ # DELTA-DESIGN template — MIRROR the just-generated master template's OWN sections so a
1548
+ # change classifies ADDED/MODIFIED/REMOVED against the code-derived structure, not the
1549
+ # greenfield four layers. Aligns with the delta-design module (classifies "per the
1550
+ # master's OWN section structure").
1551
+ - id: ctx_delta_design_template
1552
+ action: build_context
1553
+ condition: "{{svc_lane}} == true"
1554
+ context:
1555
+ - { path: .appweaver/templates/overrides/design-template.md, optional: true } # PRIMARY: the JUST-generated code-derived master — mirror its ACTUAL sections
1556
+ - { path: .appweaver/orchestrator/rev-templates/delta-design-template.skeleton.md } # SHAPE ONLY: the neutral change-record bones (zero layering, zero technology)
1557
+ - { path: "{{constitution_technical_file}}" } # the validated as-built technology base (keep the delta consistent with the master)
1558
+ - id: gen_delta_design_template
1559
+ action: agent_generate
1560
+ condition: "{{svc_lane}} == true"
1561
+ tools: "Read,Write,Edit"
1562
+ permission_mode: acceptEdits
1563
+ task: |
1564
+ Author the matching PROJECT-SPECIFIC DELTA-design TEMPLATE and Write it to
1565
+ .appweaver/templates/overrides/delta-design-template.md. It is a TEMPLATE (placeholders
1566
+ + authoring comments) for classifying a CHANGE to a feature as ADDED / MODIFIED /
1567
+ REMOVED against the master design.md.
1568
+
1569
+ MIRROR the just-generated master template (.appweaver/templates/overrides/design-template.md,
1570
+ in context — Read it): its ADDED/MODIFIED/REMOVED tables must key off the master's OWN
1571
+ code-derived sections (§1.1/§1.2, the §2.n axes it derived, §3). Use the skeleton's
1572
+ "Section (§ in design.md)" column and fill its example rows with the ACTUAL sections of
1573
+ the generated master template. Never name a layering — neither one you know nor one the
1574
+ master did not derive.
1575
+ - CARRY OVER the neutral parts of rev-templates/delta-design-template.skeleton.md (in
1576
+ context): Change summary, Cross-section impact, Regression targets, New assumptions/
1577
+ deviations (DA-n / WA-n), On close. Keep behaviour technology-agnostic (signatures +
1578
+ contracts, no code); a shared element is MODIFIED in place, never duplicated; every
1579
+ changed element serves a spec id.
1580
+ - This aligns with the delta-design module, which classifies "per the master's OWN
1581
+ section structure" — so the template MUST NOT hardcode a fixed layering.
1582
+ Keep every [PLACEHOLDER] and authoring comment. Write ONLY the override file; modify no
1583
+ source. Report the file written.
1584
+ outputs:
1585
+ - { name: delta_design_template_files, from: "$.files" }
1586
+
1587
+ - id: verify_delta_design_template
1588
+ action: verify_context
1589
+ condition: "{{svc_lane}} == true"
1590
+ require_non_empty: delta_design_template_files
1591
+ on_empty: stop
1592
+ on_empty_message: "No delta-design template was written to .appweaver/templates/overrides/delta-design-template.md. Re-run onboard after confirming the design template override was generated."
1593
+
1594
+ # ═══════ UI DESIGN TEMPLATES (frontend lane only) — the LANE's own pair ═══════
1595
+ # The lane's twin of the two steps above, on the same terms: reverse-engineered from
1596
+ # the UI SOURCE, shaped by a NEUTRAL skeleton, installed in the project override slot
1597
+ # (.appweaver/templates/overrides/{ui-design,ui-delta-design}-template.md). Written ONLY
1598
+ # where the scan found a lane, so a backend-only repo gets neither file — the same
1599
+ # "absence is meaningful" property constitution.ui.md has.
1600
+ #
1601
+ # WHY THE LANE NEEDS ITS OWN PAIR rather than a section inside the service design: the
1602
+ # two lanes are governed by different constitution halves and different map headings,
1603
+ # they are implemented by different commands, and the ONLY thing that crosses between
1604
+ # them is the design contract. A UI section inside design.md would put the lane's
1605
+ # structure under the service lane's rules and hand ⌛ ui-design the whole service
1606
+ # design to read — precisely the context leak the contract projection exists to stop.
1607
+ #
1608
+ # THE SECTION LIST IS RATIFIED, THE CONTENT IS THE CODE'S. aw-spec specifies what
1609
+ # design.ui.md contains (navigation & screen structure · client state · component
1610
+ # structure · interaction & flow · contract binding · cross-cutting · traceability ·
1611
+ # DA-n · WA-n); the skeleton carries exactly that, framework-free. What this step
1612
+ # derives from the lane's source is what goes IN those sections — the real composition
1613
+ # axes, the state and styling conventions, the screen vocabulary.
1614
+ #
1615
+ # THE CONSUMERS ARE ⌛ NOT BUILT (B-14 / B-15: ui-design, ui-implement, the three-master
1616
+ # merge in finalize-delta). The templates are written now anyway, and deliberately: the
1617
+ # evidence for them is the whole-repo vantage that exists exactly once, at onboard, and
1618
+ # resolve_template finds them by name the day those commands land. Nothing reads them
1619
+ # before then, and nothing breaks for their absence in a repo that never onboarded.
1620
+ - id: ctx_ui_design_template
1621
+ action: build_context
1622
+ condition: "{{ui_lane}} == true"
1623
+ context:
1624
+ - { path: "{{inventory_json}}" } # PRIMARY: the COMPLETE deterministic substrate — frontend_signals + the component/route/store/style file lists to read source from
1625
+ - { path: "{{constitution_ui_file}}" } # PRIMARY: the VALIDATED as-built UX-* base — the ratified principles this structure must serve
1626
+ - { path: .appweaver/orchestrator/rev-templates/ui-design-template.skeleton.md } # SHAPE ONLY: the ratified section list + neutral bones (zero framework, zero component library)
1627
+ - { path: "{{pack_dir}}/frontend/ui-constitution.md", optional: true } # the generated lane rule set's base file — the detail layer under those principles
1628
+ - { path: "{{bundle_dir}}/architecture/frontend.md", optional: true } # SECONDARY (shallow): the OKF as-built frontend note
1629
+ - id: gen_ui_design_template
1630
+ action: agent_generate
1631
+ condition: "{{ui_lane}} == true"
1632
+ tools: "Read,Write,Edit"
1633
+ permission_mode: acceptEdits
1634
+ task: |
1635
+ REVERSE-ENGINEER this repo's FRONTEND LANE into a PROJECT-SPECIFIC UI DESIGN TEMPLATE
1636
+ and Write it to .appweaver/templates/overrides/ui-design-template.md (create the
1637
+ overrides/ dir if absent). It is a TEMPLATE — concrete lane-derived section content
1638
+ with [PLACEHOLDER] tokens + authoring HTML comments that ⌛ `ui-design` fills per
1639
+ feature into specs/<Feature>/design.ui.md — NOT a filled design.
1640
+ The lane: {{ui_evidence}} · roots: {{frontend_roots}}
1641
+
1642
+ GROUND EVERYTHING IN THE LANE'S OWN CODE. Evidence authority, in order:
1643
+ 1. THE ACTUAL UI SOURCE (ground truth). Use {{inventory_json}} (in context):
1644
+ `frontend_signals` gives the lane roots, their kind (spa / server-rendered /
1645
+ desktop), their framework markers and their component / route / store / style
1646
+ file lists. READ ENOUGH OF THOSE FILES to state each structural claim from what
1647
+ the UI ACTUALLY does. Do NOT assert a convention you have not seen.
1648
+ 2. constitution.ui.md (in context) — the VALIDATED as-built UX-* base. The template's
1649
+ authoring comments point the downstream author at the UX principle each section
1650
+ serves; cite them by their real numerals.
1651
+ 3. The generated frontend/ui-constitution.md and the OKF architecture/frontend.md
1652
+ (in context, if present) — the lane's own rule detail and a shallow corroboration.
1653
+ STAY INSIDE THE LANE. Derive structure ONLY from code under the lane's roots. The
1654
+ service lane has its own template, generated just above; this one never describes
1655
+ server-side structure.
1656
+
1657
+ THE SKELETON IS SHAPE ONLY. rev-templates/ui-design-template.skeleton.md (in context)
1658
+ carries the ratified section list, the neutral bones and the authoring rules — and
1659
+ names NO framework, router, state library, component library, design system or styling
1660
+ approach. That omission is deliberate and you MUST preserve it: the generated template
1661
+ stays technology-agnostic even though you derived it from a real stack, because the
1662
+ framework binds later at ⌛ `ui-implement` from constitution.ui.md plus that command's
1663
+ rule set. Describe a component by its RESPONSIBILITY, its INPUTS as field shapes, the
1664
+ EVENTS it raises and the STATES it can be in — never by a framework's own vocabulary.
1665
+
1666
+ Identify the RECURRING composition convention across the lane's screens (how screens
1667
+ are organised and named, what is shared, where client state lives, how server data is
1668
+ fetched and invalidated, how styling is applied) — this ONE template governs every
1669
+ future feature's UI.
1670
+
1671
+ Then AUTHOR the template on the skeleton's shape, keeping its section numbers and
1672
+ headings:
1673
+ - Keep the header block and the TECHNOLOGY-AGNOSTIC authoring rules. Fill
1674
+ [GENERATED_LANE_STRUCTURE_NOTE] and §0's `### As-Built Lane Structure` with this
1675
+ lane's real convention, each claim carrying a representative path. Where the UI is
1676
+ rendered inside the service tree and owns no root of its own, say exactly that.
1677
+ - §1 Navigation & Screen Structure — template the screen inventory and the navigation
1678
+ shape THIS lane uses, described conceptually (a path pattern, a stack, a tab set),
1679
+ read from the routing code and never named after a router.
1680
+ - §2 Client State — template the state kinds this lane actually holds and the
1681
+ invalidation triggers it actually uses. If the lane holds no client state beyond
1682
+ form fields, say so as-built rather than templating a store it does not have.
1683
+ - §3 Component Structure — ONE `### 3.n` subsection PER RECURRING COMPOSITION AXIS the
1684
+ lane uses, each TITLED with the lane's OWN name for it. The count and titles are the
1685
+ code's answer; the skeleton's slots are positions, not a set to fill.
1686
+ - §4 Interaction & Flow and §6 Cross-Cutting — KEEP BOTH, always, even where this lane
1687
+ shows little. They are the two sections a backend-shaped process drops and where
1688
+ most UI defects live. Where the code handles no error or empty state, template the
1689
+ section so the downstream author must record that as-built — never delete it.
1690
+ - §5 Contract Binding — keep the lane boundary intact: the binding table reads the
1691
+ ⌛ design-contract projection, never the service design. Note in the authoring
1692
+ comment that where no contract document exists yet the author binds against the
1693
+ spec's own IC-/FR- surface and logs a §8 assumption.
1694
+ - §7 Traceability, §8 Assumptions (DA-n), §9 Deviations (WA-n), Change History — carry
1695
+ over; the §7 Section column uses THIS template's own section refs.
1696
+ Keep every [PLACEHOLDER] and authoring comment so ⌛ `ui-design` can fill it — and in
1697
+ those comments DIRECT the downstream author to GROUND each filled section in the
1698
+ ACTUAL UI CODE and the lane's governance (cite real component/route/store/stylesheet
1699
+ paths and the constitution.ui.md UX numeral). Do NOT invent lane structure the code
1700
+ does not show; where the convention is inconsistent, template the DOMINANT form and
1701
+ flag the divergence in a comment. Write ONLY the override file; modify no source.
1702
+ Report the file written + the composition axes you derived (with the code paths that
1703
+ evidence them).
1704
+ outputs:
1705
+ - { name: ui_design_template_files, from: "$.files" }
1706
+
1707
+ - id: verify_ui_design_template
1708
+ action: verify_context
1709
+ condition: "{{ui_lane}} == true"
1710
+ require_non_empty: ui_design_template_files
1711
+ on_empty: stop
1712
+ on_empty_message: "A frontend lane was detected ({{ui_evidence}}) but no UI design template was written to .appweaver/templates/overrides/ui-design-template.md. Check that the scan substrate's frontend_signals carry readable UI source, then re-run."
1713
+
1714
+ # UI DELTA-DESIGN template — MIRROR the just-generated UI master's OWN sections, exactly
1715
+ # as the service delta mirrors the service master.
1716
+ - id: ctx_ui_delta_design_template
1717
+ action: build_context
1718
+ condition: "{{ui_lane}} == true"
1719
+ context:
1720
+ - { path: .appweaver/templates/overrides/ui-design-template.md, optional: true } # PRIMARY: the JUST-generated lane master — mirror its ACTUAL sections
1721
+ - { path: .appweaver/orchestrator/rev-templates/ui-delta-design-template.skeleton.md } # SHAPE ONLY: the neutral change-record bones (zero framework)
1722
+ - { path: "{{constitution_ui_file}}" } # the validated UX-* base (keep the delta consistent with the master)
1723
+ - id: gen_ui_delta_design_template
1724
+ action: agent_generate
1725
+ condition: "{{ui_lane}} == true"
1726
+ tools: "Read,Write,Edit"
1727
+ permission_mode: acceptEdits
1728
+ task: |
1729
+ Author the matching PROJECT-SPECIFIC UI DELTA-design TEMPLATE and Write it to
1730
+ .appweaver/templates/overrides/ui-delta-design-template.md. It is a TEMPLATE
1731
+ (placeholders + authoring comments) for classifying a CHANGE to a feature's
1732
+ EXPERIENCE as ADDED / MODIFIED / REMOVED against the master design.ui.md.
1733
+
1734
+ MIRROR the just-generated lane master (.appweaver/templates/overrides/ui-design-template.md,
1735
+ in context — Read it): its ADDED/MODIFIED/REMOVED tables must key off that master's OWN
1736
+ sections, including whatever composition axes its §3 derived. Use the skeleton's
1737
+ "Section (§ in design.ui.md)" column and fill its example rows with the ACTUAL sections
1738
+ of the generated master. Never name a framework or a UI taxonomy the master did not
1739
+ derive.
1740
+ - CARRY OVER the neutral parts of rev-templates/ui-delta-design-template.skeleton.md
1741
+ (in context): Change summary, Interaction states touched, Contract impact,
1742
+ Cross-section impact, Regression targets, New assumptions/deviations (DA-n / WA-n),
1743
+ On close.
1744
+ - KEEP the "Interaction states touched" section whatever this lane's code shows: a new
1745
+ interaction that ships without its loading, empty, error and permission-denied states
1746
+ is an incomplete delta, and the template is where that is enforced.
1747
+ - KEEP the lane boundary: contract impact is raised BACK to the service lane, never
1748
+ worked around in the client.
1749
+ - A shared component or state container is MODIFIED in place, never duplicated into the
1750
+ change; every changed element serves a spec id; behaviour stays technology-agnostic
1751
+ (responsibilities, field shapes, events — no code).
1752
+ Keep every [PLACEHOLDER] and authoring comment. Write ONLY the override file; modify no
1753
+ source. Report the file written.
1754
+ outputs:
1755
+ - { name: ui_delta_design_template_files, from: "$.files" }
1756
+
1757
+ - id: verify_ui_delta_design_template
1758
+ action: verify_context
1759
+ condition: "{{ui_lane}} == true"
1760
+ require_non_empty: ui_delta_design_template_files
1761
+ on_empty: stop
1762
+ on_empty_message: "No UI delta-design template was written to .appweaver/templates/overrides/ui-delta-design-template.md. Re-run onboard after confirming the UI design template override was generated."
1763
+
1764
+ # Post-execution hooks.
1765
+ - id: resolve_post_hooks
1766
+ action: execute_script
1767
+ script: { ref: actions }
1768
+ subcommand: resolve-hooks
1769
+ args: ["--phase", "after_onboard"]
1770
+ outputs:
1771
+ - { name: after_hooks, from: "$.hooks" }
1772
+ - id: dispatch_post_hooks
1773
+ action: dispatch_hooks
1774
+ hooks_from_variable: after_hooks
1775
+
1776
+ outputs:
1777
+ bundle_dir: "{{bundle_dir}}"
1778
+ aggregate_count: "{{aggregate_count}}"
1779
+ concepts: "{{concepts}}"
1780
+ warnings: "{{okf_warnings}}"
1781
+ domain_slug: "{{domain_slug}}"
1782
+ pack_dir: "{{pack_dir}}"
1783
+ domain_rule_bindings: "{{domain_rule_bindings}}"
1784
+ tech_rule_bindings: "{{pack_dir}}/tech-rule-bindings.md"
1785
+ pack_files: "{{pack_files}}"
1786
+ tech_pack_files: "{{tech_pack_files}}"
1787
+ ui_pack_files: "{{ui_pack_files}}"
1788
+ domain_constitution_source: "{{domain_constitution_source}}"
1789
+ constitution_technical_file: "{{constitution_technical_file}}"
1790
+ constitution_domain_file: "{{constitution_domain_file}}"
1791
+ constitution_ui_file: "{{constitution_ui_file}}"
1792
+ composed_file: "{{composed_file}}"
1793
+ active_domain: "{{active_domain}}"
1794
+ # The lanes this run was told to govern, and what their source turned out to hold.
1795
+ service_lane: "{{svc_lane}}"
1796
+ ui_lane: "{{ui_lane}}"
1797
+ ui_lane_evidence: "{{ui_evidence}}"
1798
+ ui_lane_declaration: "{{ui_declaration_note}}"
1799
+ ui_source_evidence_found: "{{ui_evidence_found}}"
1800
+ ui_included: "{{ui_included}}"
1801
+ ui_validation_ok: "{{ui_validation_state}}"
1802
+ frontend_roots: "{{frontend_roots}}"
1803
+ # The lane declaration this run READ. select-stack wrote it; onboard never touches it.
1804
+ stacks_file: "{{stacks_file}}"
1805
+ backend_lane: "{{be_lane_id}} ({{be_profile}}) at {{be_root}}"
1806
+ frontend_lane: "{{fe_lane_id}} ({{fe_profile}}) at {{fe_root}}"
1807
+ # What the scan was scoped to, and how many files each lane's substrate was built
1808
+ # from. Backend signals exclude the UI subtree; frontend signals are that subtree.
1809
+ scanned_service_root: "{{scoped_service_root}}"
1810
+ scanned_ui_root: "{{scoped_ui_root}}"
1811
+ scanned_backend_files: "{{backend_file_count}}"
1812
+ scanned_ui_files: "{{frontend_file_count}}"
1813
+ design_template_override: ".appweaver/templates/overrides/design-template.md"
1814
+ delta_design_template_override: ".appweaver/templates/overrides/delta-design-template.md"
1815
+ design_template_files: "{{design_template_files}}"
1816
+ delta_design_template_files: "{{delta_design_template_files}}"
1817
+ # The lane's own template pair. Empty on a backend-only repo — no lane, no files.
1818
+ ui_design_template_files: "{{ui_design_template_files}}"
1819
+ ui_delta_design_template_files: "{{ui_delta_design_template_files}}"
1820
+ technical_validation_ok: "{{technical_ok}}"
1821
+ domain_validation_ok: "{{domain_ok}}"
1822
+ next: "Onboarded {{project_name}}: a high-level feature map at {{bundle_dir}} + a PROVISIONAL project governance scaffold, domain {{active_domain}} ACTIVATED, and — reverse-engineered from THIS code alone — the rule tiers wired per-workflow: the DOMAIN set (guardrails/projects/{{domain_slug}}/domain/*.domain.md + domain-rule-bindings.md) always, and each LANE's set where that lane is declared. ONE HALF AND ONE RULE SET PER LANE: service_lane / ui_lane report which lanes .appweaver/stacks.json declared, and the declaration is what decided. A declared service lane gets constitution.technical.md, guardrails/projects/{{domain_slug}}/service/*.md + tech-rule-bindings.md, and the service design/delta-design template overrides; a declared UI lane gets constitution.ui.md, guardrails/projects/{{domain_slug}}/frontend/*.md mapped under ## /aw-spec-ui-constitution, and its own template pair. A lane declared (none) in select-stack gets none of it, which is the correct outcome and not an omission. LANE DECLARATION: read, never written — select-stack is its sole writer, and this run scanned the source paths it named (scanned_service_root / scanned_ui_root). The scan was SCOPED by them, so the backend substrate excludes the UI subtree and the frontend substrate is that subtree: scanned_backend_files / scanned_ui_files report each. ui_source_evidence_found false means the UI lane's declared path held nothing a scan recognises as UI, so its governance is thin — move the source path with /appweaver select-stack and re-run. The build/test/run commands on each lane are that PROFILE's defaults and may not match a legacy layout — review them, and re-run /appweaver select-stack to correct any lane. Because the domain is activated, resolve-domain + resolve-tech now route the WHOLE forward pipeline AND adopt to these code-derived rules — never another project's rules as a fallback. Code-derived design + delta-design templates are installed as the project template overrides (.appweaver/templates/overrides/) so a NEW feature is developed against the as-built architecture with NO adopt — every section derived from a NEUTRAL skeleton plus this repo's own structure, with no greenfield template in context. Where the lane exists, the SAME pair is generated for it (ui-design-template.md + ui-delta-design-template.md) from the UI source; ui-design-template.md is consumed by /appweaver adopt, which reverses a slice's design.ui.md from it wherever that slice owns part of the lane's surface; ui-delta-design-template.md still waits, since ui-design / ui-implement are not built yet. Develop an EXISTING feature just-in-time: /appweaver adopt <Feature> reverse-engineers its spec.md + design.md + source-map.md and completes that feature's OKF concept; its governance reconcile is currently HELD, so the scaffold this run wrote stays as it is. Develop a NEW feature straight through the forward pipeline (/appweaver specify → design → implement). Then drive every change through the CR delta loop (/appweaver specify → design → analyze-delta-design → implement-delta → build → finalize-delta → analyze-slice → close-delta). If a validation_ok is false, its constitution half needs a manual touch (see its Sync Impact Report)."