aw-spec-cli 0.1.8 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (257) hide show
  1. package/assets/.appweaver/DESIGN-FORMAT.md +200 -0
  2. package/assets/.appweaver/ORCH-DIALECT.md +156 -0
  3. package/assets/.appweaver/RULE-PARTITION.md +175 -0
  4. package/assets/.appweaver/STACK-PROFILES.md +461 -0
  5. package/assets/.appweaver/ai-rules.md +180 -0
  6. package/assets/.appweaver/domain.json +1 -0
  7. package/assets/.appweaver/extensions/.registry +19 -0
  8. package/assets/.appweaver/extensions/agent-context/README.md +57 -0
  9. package/assets/.appweaver/extensions/agent-context/agent-context-config.yml +4 -0
  10. package/assets/.appweaver/extensions/agent-context/commands/aw-spec.agent-context.update.md +26 -0
  11. package/assets/.appweaver/extensions/agent-context/extension.yml +37 -0
  12. package/assets/.appweaver/extensions/agent-context/scripts/bash/update-agent-context.sh +201 -0
  13. package/assets/.appweaver/extensions/agent-context/scripts/powershell/update-agent-context.ps1 +237 -0
  14. package/assets/.appweaver/extensions.yml +16 -0
  15. package/assets/.appweaver/feature.json +3 -0
  16. package/assets/.appweaver/init-options.json +9 -0
  17. package/assets/.appweaver/integration.json +15 -0
  18. package/assets/.appweaver/integrations/aw-spec.manifest.json +9 -0
  19. package/assets/.appweaver/interpreter/run-skill.py +1176 -0
  20. package/assets/.appweaver/memory/constitution.md +50 -0
  21. package/assets/.appweaver/orchestrator/.smoke-out/smoke.md +6 -0
  22. package/assets/.appweaver/orchestrator/AGENT-PROFILE.md +94 -0
  23. package/assets/.appweaver/orchestrator/README.md +300 -0
  24. package/assets/.appweaver/orchestrator/adapters/claude_agent_sdk.py +74 -0
  25. package/assets/.appweaver/orchestrator/adapters/google_antigravity.py +74 -0
  26. package/assets/.appweaver/orchestrator/modules/delta-design.orch.yaml +105 -0
  27. package/assets/.appweaver/orchestrator/modules/delta-spec.orch.yaml +101 -0
  28. package/assets/.appweaver/orchestrator/modules/domain-select.orch.yaml +90 -0
  29. package/assets/.appweaver/orchestrator/modules/lane-gate.orch.yaml +126 -0
  30. package/assets/.appweaver/orchestrator/modules/tech-select.orch.yaml +123 -0
  31. package/assets/.appweaver/orchestrator/orchestrator.py +1721 -0
  32. package/assets/.appweaver/orchestrator/rev-templates/ai-rules.reference.md +40 -0
  33. package/assets/.appweaver/orchestrator/rev-templates/delta-design-template.skeleton.md +101 -0
  34. package/assets/.appweaver/orchestrator/rev-templates/design-template.skeleton.md +245 -0
  35. package/assets/.appweaver/orchestrator/rev-templates/domain-constitution.skeleton.md +63 -0
  36. package/assets/.appweaver/orchestrator/rev-templates/domain-requirements.skeleton.md +48 -0
  37. package/assets/.appweaver/orchestrator/rev-templates/domain-rule-bindings.skeleton.md +59 -0
  38. package/assets/.appweaver/orchestrator/rev-templates/domain-rule-file.skeleton.md +39 -0
  39. package/assets/.appweaver/orchestrator/rev-templates/frontend-rule-file.skeleton.md +63 -0
  40. package/assets/.appweaver/orchestrator/rev-templates/tech-rule-bindings.skeleton.md +116 -0
  41. package/assets/.appweaver/orchestrator/rev-templates/technical-constitution.skeleton.md +106 -0
  42. package/assets/.appweaver/orchestrator/rev-templates/technical-rule-file.skeleton.md +54 -0
  43. package/assets/.appweaver/orchestrator/rev-templates/ui-constitution.skeleton.md +125 -0
  44. package/assets/.appweaver/orchestrator/rev-templates/ui-delta-design-template.skeleton.md +123 -0
  45. package/assets/.appweaver/orchestrator/rev-templates/ui-design-template.skeleton.md +294 -0
  46. package/assets/.appweaver/orchestrator/workflows/_smoke.orch.yaml +160 -0
  47. package/assets/.appweaver/orchestrator/workflows/aw-spec-add-component.orch.yaml +270 -0
  48. package/assets/.appweaver/orchestrator/workflows/aw-spec-adopt.orch.yaml +934 -0
  49. package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-delta-design.orch.yaml +251 -0
  50. package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-design.orch.yaml +265 -0
  51. package/assets/.appweaver/orchestrator/workflows/aw-spec-analyze-slice.orch.yaml +437 -0
  52. package/assets/.appweaver/orchestrator/workflows/aw-spec-build.orch.yaml +197 -0
  53. package/assets/.appweaver/orchestrator/workflows/aw-spec-characterize.orch.yaml +475 -0
  54. package/assets/.appweaver/orchestrator/workflows/aw-spec-close-delta.orch.yaml +181 -0
  55. package/assets/.appweaver/orchestrator/workflows/aw-spec-constitution.orch.yaml +727 -0
  56. package/assets/.appweaver/orchestrator/workflows/aw-spec-demo.orch.yaml +100 -0
  57. package/assets/.appweaver/orchestrator/workflows/aw-spec-dependency-tree.orch.yaml +69 -0
  58. package/assets/.appweaver/orchestrator/workflows/aw-spec-deploy.orch.yaml +85 -0
  59. package/assets/.appweaver/orchestrator/workflows/aw-spec-design-ui.orch.yaml +386 -0
  60. package/assets/.appweaver/orchestrator/workflows/aw-spec-design.orch.yaml +382 -0
  61. package/assets/.appweaver/orchestrator/workflows/aw-spec-finalize-delta.orch.yaml +462 -0
  62. package/assets/.appweaver/orchestrator/workflows/aw-spec-foundation.orch.yaml +265 -0
  63. package/assets/.appweaver/orchestrator/workflows/aw-spec-implement-delta.orch.yaml +253 -0
  64. package/assets/.appweaver/orchestrator/workflows/aw-spec-implement-ui.orch.yaml +267 -0
  65. package/assets/.appweaver/orchestrator/workflows/aw-spec-implement.orch.yaml +287 -0
  66. package/assets/.appweaver/orchestrator/workflows/aw-spec-inventory.orch.yaml +238 -0
  67. package/assets/.appweaver/orchestrator/workflows/aw-spec-onboard.orch.yaml +1822 -0
  68. package/assets/.appweaver/orchestrator/workflows/aw-spec-parity.orch.yaml +293 -0
  69. package/assets/.appweaver/orchestrator/workflows/aw-spec-run.orch.yaml +194 -0
  70. package/assets/.appweaver/orchestrator/workflows/aw-spec-select-domain.orch.yaml +83 -0
  71. package/assets/.appweaver/orchestrator/workflows/aw-spec-select-feature.orch.yaml +128 -0
  72. package/assets/.appweaver/orchestrator/workflows/aw-spec-select-stack.orch.yaml +296 -0
  73. package/assets/.appweaver/orchestrator/workflows/aw-spec-specify.orch.yaml +439 -0
  74. package/assets/.appweaver/scripts/bash/aw-inventory.sh +17 -0
  75. package/assets/.appweaver/scripts/bash/aw-parity.sh +13 -0
  76. package/assets/.appweaver/scripts/bash/aw-rev-constitution.sh +13 -0
  77. package/assets/.appweaver/scripts/bash/aw-spec-actions.sh +2626 -0
  78. package/assets/.appweaver/scripts/bash/aw-xref.sh +15 -0
  79. package/assets/.appweaver/scripts/bash/common.sh +533 -0
  80. package/assets/.appweaver/scripts/powershell/aw-inventory.ps1 +17 -0
  81. package/assets/.appweaver/scripts/powershell/aw-parity.ps1 +13 -0
  82. package/assets/.appweaver/scripts/powershell/aw-rev-constitution.ps1 +13 -0
  83. package/assets/.appweaver/scripts/powershell/aw-spec-actions.ps1 +2232 -0
  84. package/assets/.appweaver/scripts/powershell/aw-xref.ps1 +15 -0
  85. package/assets/.appweaver/scripts/python/aw-component-catalog.py +121 -0
  86. package/assets/.appweaver/scripts/python/aw-inventory.py +1180 -0
  87. package/assets/.appweaver/scripts/python/aw-parity.py +380 -0
  88. package/assets/.appweaver/scripts/python/aw-rev-constitution.py +329 -0
  89. package/assets/.appweaver/scripts/python/aw-stack.py +1251 -0
  90. package/assets/.appweaver/scripts/python/aw-xref.py +1330 -0
  91. package/assets/.appweaver/scripts/python/validate_okf.py +352 -0
  92. package/assets/.appweaver/stack-profiles/angular.json +16 -0
  93. package/assets/.appweaver/stack-profiles/blazor-wasm.json +17 -0
  94. package/assets/.appweaver/stack-profiles/dotnet-webapi.json +15 -0
  95. package/assets/.appweaver/stack-profiles/go-chi.json +14 -0
  96. package/assets/.appweaver/stack-profiles/java-spring.json +16 -0
  97. package/assets/.appweaver/stack-profiles/nextjs.json +16 -0
  98. package/assets/.appweaver/stack-profiles/node-express.json +15 -0
  99. package/assets/.appweaver/stack-profiles/python-fastapi.json +16 -0
  100. package/assets/.appweaver/stack-profiles/react-vite.json +17 -0
  101. package/assets/.appweaver/stack-profiles/sveltekit.json +16 -0
  102. package/assets/.appweaver/stack-profiles/vue-vite.json +17 -0
  103. package/assets/.appweaver/stacks.json +3 -0
  104. package/assets/.appweaver/templates/constitution-domain-template.md +116 -0
  105. package/assets/.appweaver/templates/constitution-technical-template.md +108 -0
  106. package/assets/.appweaver/templates/constitution-ui-template.md +116 -0
  107. package/assets/.appweaver/templates/delta-design-template.md +69 -0
  108. package/assets/.appweaver/templates/delta-spec-template.md +63 -0
  109. package/assets/.appweaver/templates/design-template.md +383 -0
  110. package/assets/.appweaver/templates/okf-concept-template.md +114 -0
  111. package/assets/.appweaver/templates/parity-manifest-template.json +49 -0
  112. package/assets/.appweaver/templates/source-map-template.md +85 -0
  113. package/assets/.appweaver/templates/spec-template.md +309 -0
  114. package/assets/.appweaver/templates/ui-design-template.md +273 -0
  115. package/assets/foundations/dotnet/ModularMonolith/ModularMonolith.Reference.pack.txt +25248 -0
  116. package/assets/foundations/dotnet/ModularMonolith/ModularMonolith.pack.txt +5726 -0
  117. package/assets/foundations/dotnet/ModularMonolith/pack-foundation.ps1 +145 -0
  118. package/assets/foundations/dotnet/ModularMonolith/pack-foundation.sh +196 -0
  119. package/assets/foundations/dotnet/ModularMonolith/pack-reference-foundation.ps1 +157 -0
  120. package/assets/foundations/dotnet/ModularMonolith/pack-reference-foundation.sh +209 -0
  121. package/assets/foundations/dotnet/ModularMonolith/unpack-foundation.ps1 +126 -0
  122. package/assets/foundations/dotnet/ModularMonolith/unpack-foundation.sh +217 -0
  123. package/assets/foundations/dotnet/ModularMonolith/unpack-reference-foundation.ps1 +129 -0
  124. package/assets/foundations/dotnet/ModularMonolith/unpack-reference-foundation.sh +218 -0
  125. package/assets/foundations/dotnet/VerticalSlice/VerticalSlice.Reference.pack.txt +19318 -0
  126. package/assets/foundations/dotnet/VerticalSlice/VerticalSlice.pack.txt +2833 -0
  127. package/assets/foundations/dotnet/VerticalSlice/pack-foundation.ps1 +145 -0
  128. package/assets/foundations/dotnet/VerticalSlice/pack-foundation.sh +196 -0
  129. package/assets/foundations/dotnet/VerticalSlice/pack-reference-foundation.ps1 +157 -0
  130. package/assets/foundations/dotnet/VerticalSlice/pack-reference-foundation.sh +209 -0
  131. package/assets/foundations/dotnet/VerticalSlice/unpack-foundation.ps1 +126 -0
  132. package/assets/foundations/dotnet/VerticalSlice/unpack-foundation.sh +217 -0
  133. package/assets/foundations/dotnet/VerticalSlice/unpack-reference-foundation.ps1 +129 -0
  134. package/assets/foundations/dotnet/VerticalSlice/unpack-reference-foundation.sh +218 -0
  135. package/assets/foundations/dotnet/components/Email/README.md +119 -0
  136. package/assets/foundations/dotnet/components/Email/ReferenceEndpoints/SendEmailEndpoint.cs +84 -0
  137. package/assets/foundations/dotnet/components/Email/integration.md +300 -0
  138. package/assets/foundations/dotnet/components/Jobs/README.md +113 -0
  139. package/assets/foundations/dotnet/components/Jobs/integration.md +259 -0
  140. package/assets/foundations/dotnet/components/QrGenerator/README.md +85 -0
  141. package/assets/foundations/dotnet/components/QrGenerator/ReferenceEndpoints/GenerateQrEndpoint.cs +57 -0
  142. package/assets/foundations/dotnet/components/QrGenerator/integration.md +230 -0
  143. package/assets/foundations/dotnet/components/README.md +74 -0
  144. package/assets/guardrails/README.md +222 -0
  145. package/assets/guardrails/domain/healthcare/ai-rules.domain.md +34 -0
  146. package/assets/guardrails/domain/healthcare/api-versioning.domain.md +17 -0
  147. package/assets/guardrails/domain/healthcare/auditing.domain.md +97 -0
  148. package/assets/guardrails/domain/healthcare/authorization.domain.md +26 -0
  149. package/assets/guardrails/domain/healthcare/clinical-terms.md +20 -0
  150. package/assets/guardrails/domain/healthcare/coding-standards.domain.md +26 -0
  151. package/assets/guardrails/domain/healthcare/consent.md +19 -0
  152. package/assets/guardrails/domain/healthcare/cqrs.domain.md +12 -0
  153. package/assets/guardrails/domain/healthcare/data-classification.domain.md +28 -0
  154. package/assets/guardrails/domain/healthcare/dependency-policy.domain.md +11 -0
  155. package/assets/guardrails/domain/healthcare/dicom.md +15 -0
  156. package/assets/guardrails/domain/healthcare/domain-constitution.md +119 -0
  157. package/assets/guardrails/domain/healthcare/domain-driven-design.domain.md +28 -0
  158. package/assets/guardrails/domain/healthcare/eventing.domain.md +18 -0
  159. package/assets/guardrails/domain/healthcare/fhir.md +36 -0
  160. package/assets/guardrails/domain/healthcare/folder-structure.domain.md +25 -0
  161. package/assets/guardrails/domain/healthcare/hipaa.md +34 -0
  162. package/assets/guardrails/domain/healthcare/hl7.md +15 -0
  163. package/assets/guardrails/domain/healthcare/ihe-conformance.md +31 -0
  164. package/assets/guardrails/domain/healthcare/integration-terms.md +21 -0
  165. package/assets/guardrails/domain/healthcare/persistence.domain.md +20 -0
  166. package/assets/guardrails/domain/healthcare/terminology.md +30 -0
  167. package/assets/guardrails/domain/healthcare/testing.domain.md +15 -0
  168. package/assets/guardrails/domain/healthcare/ux/accessibility-standards.md +36 -0
  169. package/assets/guardrails/domain/healthcare/ux/content-design.md +32 -0
  170. package/assets/guardrails/domain/healthcare/ux/interaction-states.md +44 -0
  171. package/assets/guardrails/domain/healthcare/ux/journey-mapping.md +40 -0
  172. package/assets/guardrails/domain/healthcare/vertical-slices.domain.md +18 -0
  173. package/assets/guardrails/domain/healthcare/zero-trust.domain.md +12 -0
  174. package/assets/guardrails/domain/pharma/ai-rules.domain.md +32 -0
  175. package/assets/guardrails/domain/pharma/api-versioning.domain.md +20 -0
  176. package/assets/guardrails/domain/pharma/atc.md +22 -0
  177. package/assets/guardrails/domain/pharma/auditing.domain.md +90 -0
  178. package/assets/guardrails/domain/pharma/authorization.domain.md +25 -0
  179. package/assets/guardrails/domain/pharma/coding-standards.domain.md +28 -0
  180. package/assets/guardrails/domain/pharma/cqrs.domain.md +16 -0
  181. package/assets/guardrails/domain/pharma/data-classification.domain.md +24 -0
  182. package/assets/guardrails/domain/pharma/data-provenance.md +21 -0
  183. package/assets/guardrails/domain/pharma/dependency-policy.domain.md +11 -0
  184. package/assets/guardrails/domain/pharma/domain-constitution.md +113 -0
  185. package/assets/guardrails/domain/pharma/domain-driven-design.domain.md +36 -0
  186. package/assets/guardrails/domain/pharma/domain-requirements.sample.md +103 -0
  187. package/assets/guardrails/domain/pharma/eventing.domain.md +18 -0
  188. package/assets/guardrails/domain/pharma/fhir.md +31 -0
  189. package/assets/guardrails/domain/pharma/folder-structure.domain.md +26 -0
  190. package/assets/guardrails/domain/pharma/hl7.md +17 -0
  191. package/assets/guardrails/domain/pharma/idmp.md +26 -0
  192. package/assets/guardrails/domain/pharma/integration-terms.md +21 -0
  193. package/assets/guardrails/domain/pharma/ndc.md +28 -0
  194. package/assets/guardrails/domain/pharma/persistence.domain.md +23 -0
  195. package/assets/guardrails/domain/pharma/pharma-terms.md +27 -0
  196. package/assets/guardrails/domain/pharma/product-lifecycle.domain.md +30 -0
  197. package/assets/guardrails/domain/pharma/regulatory-compliance.md +19 -0
  198. package/assets/guardrails/domain/pharma/terminology.md +32 -0
  199. package/assets/guardrails/domain/pharma/testing.domain.md +19 -0
  200. package/assets/guardrails/domain/pharma/vertical-slices.domain.md +17 -0
  201. package/assets/guardrails/domain/pharma/zero-trust.domain.md +12 -0
  202. package/assets/guardrails/projects/dotnet-default-project/domain/domain-requirements.md +58 -0
  203. package/assets/guardrails/projects/dotnet-default-project/domain-rule-bindings.md +113 -0
  204. package/assets/guardrails/projects/dotnet-default-project/frontend/ui-requirements.md +43 -0
  205. package/assets/guardrails/projects/dotnet-default-project/service/technical-requirements.md +40 -0
  206. package/assets/guardrails/projects/dotnet-default-project/tech-rule-bindings.md +263 -0
  207. package/assets/guardrails/requirement-spec.txt +27 -0
  208. package/assets/guardrails/technology/dotnet-webapi/PACKAGING.md +184 -0
  209. package/assets/guardrails/technology/dotnet-webapi/api-versioning.md +44 -0
  210. package/assets/guardrails/technology/dotnet-webapi/auditing.md +96 -0
  211. package/assets/guardrails/technology/dotnet-webapi/authorization-matrix.md +14 -0
  212. package/assets/guardrails/technology/dotnet-webapi/authorization.md +39 -0
  213. package/assets/guardrails/technology/dotnet-webapi/clean-architecture.md +54 -0
  214. package/assets/guardrails/technology/dotnet-webapi/coding-standards.md +87 -0
  215. package/assets/guardrails/technology/dotnet-webapi/cqrs.md +63 -0
  216. package/assets/guardrails/technology/dotnet-webapi/data-classification.md +38 -0
  217. package/assets/guardrails/technology/dotnet-webapi/dependency-policy.md +40 -0
  218. package/assets/guardrails/technology/dotnet-webapi/domain-driven-design.md +91 -0
  219. package/assets/guardrails/technology/dotnet-webapi/eventing.md +57 -0
  220. package/assets/guardrails/technology/dotnet-webapi/examples/api-versioning.md +75 -0
  221. package/assets/guardrails/technology/dotnet-webapi/examples/auditing.md +84 -0
  222. package/assets/guardrails/technology/dotnet-webapi/examples/authorization.md +68 -0
  223. package/assets/guardrails/technology/dotnet-webapi/examples/clean-architecture.md +37 -0
  224. package/assets/guardrails/technology/dotnet-webapi/examples/cqrs.md +97 -0
  225. package/assets/guardrails/technology/dotnet-webapi/examples/domain-driven-design.md +141 -0
  226. package/assets/guardrails/technology/dotnet-webapi/examples/eventing.md +46 -0
  227. package/assets/guardrails/technology/dotnet-webapi/examples/persistence.md +207 -0
  228. package/assets/guardrails/technology/dotnet-webapi/examples/vertical-slices.md +151 -0
  229. package/assets/guardrails/technology/dotnet-webapi/examples/zero-trust.md +48 -0
  230. package/assets/guardrails/technology/dotnet-webapi/folder-structure.md +61 -0
  231. package/assets/guardrails/technology/dotnet-webapi/modular-monolith.md +47 -0
  232. package/assets/guardrails/technology/dotnet-webapi/persistence.md +82 -0
  233. package/assets/guardrails/technology/dotnet-webapi/technology-constitution.md +162 -0
  234. package/assets/guardrails/technology/dotnet-webapi/testing.md +55 -0
  235. package/assets/guardrails/technology/dotnet-webapi/vertical-slices.md +70 -0
  236. package/assets/guardrails/technology/dotnet-webapi/zero-trust.md +48 -0
  237. package/assets/guardrails/technology/java-spring/README.md +62 -0
  238. package/assets/guardrails/technology/nextjs/accessibility-implementation.md +56 -0
  239. package/assets/guardrails/technology/nextjs/api-client.md +56 -0
  240. package/assets/guardrails/technology/nextjs/api-integration.dotnet-webapi.md +174 -0
  241. package/assets/guardrails/technology/nextjs/api-integration.java-spring.md +203 -0
  242. package/assets/guardrails/technology/nextjs/auth-session.md +68 -0
  243. package/assets/guardrails/technology/nextjs/client-security.md +69 -0
  244. package/assets/guardrails/technology/nextjs/component-architecture.md +60 -0
  245. package/assets/guardrails/technology/nextjs/component-conventions.md +58 -0
  246. package/assets/guardrails/technology/nextjs/design-system.md +60 -0
  247. package/assets/guardrails/technology/nextjs/error-handling.md +72 -0
  248. package/assets/guardrails/technology/nextjs/forms-and-validation.md +75 -0
  249. package/assets/guardrails/technology/nextjs/frontend-testing.md +94 -0
  250. package/assets/guardrails/technology/nextjs/i18n.md +57 -0
  251. package/assets/guardrails/technology/nextjs/observability.md +67 -0
  252. package/assets/guardrails/technology/nextjs/performance-budgets.md +66 -0
  253. package/assets/guardrails/technology/nextjs/routing-navigation.md +52 -0
  254. package/assets/guardrails/technology/nextjs/state-management.md +70 -0
  255. package/assets/guardrails/technology/nextjs/ui-constitution.md +166 -0
  256. package/package.json +1 -1
  257. package/assets/docs/pharma-constitution.my-ref.md +0 -86
@@ -0,0 +1,462 @@
1
+ # =============================================================================
2
+ # aw-spec-finalize-delta (orchestrator) — MERGE the delta into the master docs
3
+ #
4
+ # The fourth of the five CR stages. Fold the open change's delta docs into the feature's
5
+ # masters (doc-first merge) and refresh the cross-slice edges from the now-merged design.
6
+ # After this the master docs describe the shipped-plus-change state — but THE CHANGE
7
+ # REMAINS OPEN.
8
+ #
9
+ # HOW MANY MASTERS. Two always — spec.md + design.md. THREE where the feature holds a UI
10
+ # half (design.ui.md). This stage is the ONLY writer of the masters, so every document the
11
+ # change can move has to move here: a UI delta left in the change dir is lost the moment
12
+ # close-delta archives it, and a UX- merged into the spec that reaches no design is a
13
+ # standard nothing implements.
14
+ #
15
+ # THE UI LANE HAS ITS OWN COMMANDS — ⌛ design-ui / delta-design-ui author design.ui.md and
16
+ # delta-design.ui.md, exactly as design / delta-design author the service pair. This stage
17
+ # does not author either one; it MERGES whichever of them the feature has. The two UI paths
18
+ # it must handle are therefore different, and both are normal:
19
+ # • MASTER + DELTA — the change has an experience half. Merge it, then append the row.
20
+ # • MASTER, NO DELTA — the change never reached the UI, or ⌛ delta-design-ui has not run.
21
+ # Append the Change History row and touch nothing else. The row is not bookkeeping
22
+ # for its own sake: close-delta stamps design.ui.md to the new version alongside its
23
+ # siblings (version-stamp covers all three), so a header carrying a version that no
24
+ # row explains is indistinguishable from a merge that silently dropped one.
25
+ # A feature with no design.ui.md at all has no UI half and merges two documents, unchanged.
26
+ #
27
+ # specify → design → analyze-delta-design → implement-delta → build
28
+ # → finalize-delta ← you are here
29
+ # → analyze-slice → close-delta
30
+ #
31
+ # MERGE HERE, CLOSE LATER. Archiving the change + bumping the version used to happen in
32
+ # this stage; both moved to close-delta, which runs AFTER analyze-slice. The split buys
33
+ # two things:
34
+ # 1. analyze-slice reads a master spec.md that ALREADY carries the change, so its fix
35
+ # loops repair code against the true current requirements — no delta-awareness, no
36
+ # risk of "fixing" the change's new tests back toward pre-change behaviour.
37
+ # 2. A red analyze-slice still lands on an OPEN change, so the remedy is "fix and
38
+ # re-run" rather than a NEW change to repair the one already shipped.
39
+ # The downstream fence below still guards the MERGE (a change that breaks a dependent
40
+ # must not reach the master docs); close-delta guards nothing — it is the bookkeeping.
41
+ #
42
+ # Prereqs: run /appweaver implement-delta then build first (the delta's code is
43
+ # generated and compiles), so after the merge the master docs and the code agree.
44
+ # finalize-delta edits ONLY the master docs; it does not generate code.
45
+ #
46
+ # Launch: /appweaver finalize-delta [strategy]
47
+ # Prereq: an OPEN change whose delta was implemented.
48
+ # =============================================================================
49
+
50
+ name: aw-spec-finalize-delta
51
+ description: Merge the open change's delta-spec into spec.md, delta-design into design.md and — where the feature has a UI half — delta-design.ui.md into design.ui.md (doc-first), append the Change History to each in lockstep, and refresh the cross-slice edges from the merged design. Gated first by a SCOPED downstream fence over the transitive blast radius (fence_green), which writes a triage report and asks Abort/Override on red. Leaves the change OPEN — analyze-slice runs next against the merged master, and close-delta archives the change and bumps the version.
52
+ version: 1.3.0
53
+ agent_agnostic: true
54
+ dialect: aw-spec.orchestrator/v1
55
+
56
+ scripts:
57
+ actions:
58
+ sh: .appweaver/scripts/bash/aw-spec-actions.sh
59
+ ps1: .appweaver/scripts/powershell/aw-spec-actions.ps1
60
+ xref:
61
+ sh: .appweaver/scripts/bash/aw-xref.sh
62
+ ps1: .appweaver/scripts/powershell/aw-xref.ps1
63
+
64
+ standards:
65
+ - { path: .appweaver/ai-rules.md } # kit-resident: the universal operating rules, every flow
66
+
67
+ vars:
68
+ active_change: ""
69
+ has_change: "false"
70
+ version: "" # the CURRENT version — unchanged by this stage
71
+ next_version: "" # what close-delta will bump to; the number the Change History rows carry
72
+ downstream_count: "0" # transitive + placeholder-filtered dependents (blast radius); drives the gate
73
+ downstream_csv: "" # the blast-radius names, fed to the scoped fence's --also and shown to the human
74
+ fence_ok: "true" # default green so the gate is a no-op when nothing downstream
75
+ gate_decision: "clean" # audit: 'clean' unless a RED fence was deliberately overridden
76
+ ui_design_exists: "false" # the feature holds a design.ui.md master ⇒ this merge has a THIRD target.
77
+ # feature_paths runs on_error:continue, so this default is what a failed
78
+ # readback falls back to: the two-master merge, unchanged.
79
+ ui_design_doc: "" # specs/<Feature>/design.ui.md — the UI merge target
80
+
81
+ workflow:
82
+
83
+ # 1. Resolve the current feature + its spec; require the spec (a merge target).
84
+ - id: feature_paths
85
+ action: execute_script
86
+ on_error: continue # never crash raw on 'no feature set' — the gate below explains it
87
+ script: { ref: actions }
88
+ subcommand: feature-paths
89
+ outputs:
90
+ - { name: feature_dir, from: "$.feature_dir" }
91
+ - { name: spec_file, from: "$.spec_file" }
92
+ - { name: spec_exists, from: "$.spec_exists" }
93
+ - { name: ui_design_exists, from: "$.ui_design_exists" } # ⇒ a third master to merge into
94
+ - { name: ui_design_doc, from: "$.ui_design_file" }
95
+
96
+ - id: require_feature
97
+ action: verify_context
98
+ require_non_empty: feature_dir
99
+ on_empty: stop
100
+ on_empty_message: "No active feature. Run /appweaver select-feature first (pick or create the aggregate, e.g. Order), then re-run finalize-delta."
101
+
102
+ - id: verify_spec
103
+ action: verify_context
104
+ require_true: spec_exists
105
+ on_false: stop
106
+ on_false_message: "No spec.md for the current feature. Run /appweaver specify + design first."
107
+
108
+ # 1b. Read the OPEN change (opened by cr). finalize-delta needs a change to close.
109
+ - id: read_change
110
+ action: execute_script
111
+ script: { ref: actions }
112
+ subcommand: version-read
113
+ args: ["--feature-dir", "{{feature_dir}}"]
114
+ outputs:
115
+ - { name: active_change, from: "$.active_change" }
116
+ - { name: has_change, from: "$.has_change" }
117
+ - { name: version, from: "$.version" }
118
+ - { name: next_version, from: "$.next_version" }
119
+
120
+ - id: require_change
121
+ action: verify_context
122
+ require_true: has_change
123
+ on_false: stop
124
+ on_false_message: "No open change on this feature — nothing to finalize. Run /appweaver specify → design → analyze-delta-design → implement-delta first."
125
+
126
+ # 1c. DOWNSTREAM GATE (hard, with a REVIEWED override). Who depends on this aggregate —
127
+ # its OKF Cross-References, TRANSITIVELY (C→B→A all count) and placeholder-filtered
128
+ # (the "_(none observed)_" row is NOT a dependent) = the real blast radius. If any
129
+ # slice does, this change could ripple into it, so run a SCOPED regression fence over
130
+ # this feature + its downstream closure (--scope slice --also <closure>) BEFORE the
131
+ # doc merge, so a block leaves the repo untouched. The fence binds fence_GREEN (ran
132
+ # AND matched >=1), not raw ok, so an empty / zero-match run is RED, never a vacuous
133
+ # pass. If RED we do NOT hard-stop blindly: we WRITE a triage report, then surface the
134
+ # failing log + dependent slices and ASK the developer — Abort (a real downstream
135
+ # break: fix it first) or, having reviewed the log (pre-existing / flaky / unrelated),
136
+ # deliberately Override and close anyway. Non-interactive / CI runs take the FIRST
137
+ # option (Abort), so automation never silently overrides. Skipped when nothing depends
138
+ # on this slice (count 0) or the fence is green.
139
+ - id: xref_impact
140
+ action: execute_script
141
+ on_error: continue
142
+ script: { ref: xref }
143
+ subcommand: list
144
+ args: ["--feature-dir", "{{feature_dir}}"]
145
+ outputs:
146
+ - { name: downstream_count, from: "$.referrer_closure_count" } # transitive + placeholder-filtered
147
+ - { name: downstream_csv, from: "$.referrer_closure_csv" } # blast-radius names → --also + display
148
+
149
+ - id: run_downstream_fence
150
+ condition: "{{downstream_count}} != 0"
151
+ action: execute_script
152
+ on_error: continue
153
+ script: { ref: actions }
154
+ subcommand: test-run
155
+ args: ["--feature-dir", "{{feature_dir}}", "--scope", "slice", "--also", "{{downstream_csv}}"]
156
+ outputs:
157
+ - { name: fence_ok, from: "$.fence_green" }
158
+ - { name: fence_tool, from: "$.tool" }
159
+ - { name: fence_log, from: "$.log_tail" }
160
+
161
+ # Whenever the fence RAN (there are dependents), write a durable report BEFORE asking /
162
+ # stopping — written green OR red, mirroring characterize's drifted-tests.md, so a later green
163
+ # close never archives a STALE red report. On red it is the triage a developer reads while
164
+ # deciding Abort vs Override and, if Overridden, is ARCHIVED with the change as the "closed over
165
+ # red" record; on green it is a short all-clear that overwrites any prior red report. Skipped
166
+ # only when nothing depends on this slice (no fence ran, nothing to report).
167
+ - id: ctx_broken_downstream
168
+ action: build_context
169
+ condition: "{{downstream_count}} != 0"
170
+ vars:
171
+ active_change: "{{active_change}}"
172
+ downstream_count: "{{downstream_count}}"
173
+ downstream_csv: "{{downstream_csv}}"
174
+ fence_ok: "{{fence_ok}}"
175
+ fence_log: "{{fence_log}}"
176
+ context:
177
+ - { path: "{{spec_file}}" }
178
+ - { path: "{{feature_dir}}/changes/{{active_change}}/delta-design.md" }
179
+ - id: write_broken_downstream
180
+ action: agent_author
181
+ condition: "{{downstream_count}} != 0"
182
+ include_standards: false # a triage report, not generated code
183
+ output_target: { type: file, path: "{{feature_dir}}/changes/{{active_change}}/broken-downstream.md" }
184
+ task: |
185
+ Author the DOWNSTREAM report for change {{active_change}}: the result of re-running this
186
+ change against the aggregates that DEPEND ON this feature. finalize-delta does NOT fix a
187
+ downstream slice (that is the downstream slice's own job). Downstream blast radius
188
+ ({{downstream_count}}): {{downstream_csv}}. The fence result was fence_green={{fence_ok}}
189
+ (true = every downstream test passed; false = at least one failed). Test log:
190
+ {{fence_log}}
191
+ Always write the file (it is regenerated on every finalize-delta run so a green close never
192
+ leaves a stale red report standing). Stamp when it was generated in both cases.
193
+
194
+ IF fence_green is TRUE (all passed): write a SHORT all-clear — the heading
195
+ `# Broken Downstream — change {{active_change}}`, then a few lines stating that the
196
+ {{downstream_count}} slice(s) that use this feature ({{downstream_csv}}) were re-run against
197
+ this change and all passed, so nothing downstream broke. No per-slice sections; invent nothing.
198
+
199
+ IF fence_green is FALSE (something failed): write the triage record —
200
+ - `# Broken Downstream — change {{active_change}}` and a one-line statement: aggregates that
201
+ USE this feature and whose tests went red when this change was run against them, found by
202
+ finalize-delta's downstream gate. Note it is the record a human reads while deciding Abort vs
203
+ Override, and if the change is Overridden it is archived with the change as the record of
204
+ what was knowingly closed over.
205
+ - A SUMMARY line: total downstream slices in the blast radius, and how many have a failing test.
206
+ - One `##` section per DOWNSTREAM slice that has a failing test — attribute a failure to a
207
+ slice by matching the failing test names in the log to the slice's name. Under it, on their
208
+ own labelled lines: the downstream aggregate, the failing test(s) named in the log, what
209
+ broke (as far as the log shows), and a RESOLUTION line — either this change broke the
210
+ downstream slice's expected contract (fix it in the downstream slice's OWN CR, or re-baseline
211
+ its golden-master) or the failure is pre-existing / flaky / unrelated (a candidate for a
212
+ reviewed Override). Recommend one; do not claim certainty the log does not support.
213
+ - A closing `## How to use this file`: if you Abort, resolve each finding in the downstream
214
+ slice (or re-baseline its golden-master via a CR) then re-run /appweaver finalize-delta; if
215
+ you Override, this is the archived record of what was knowingly closed over. Do not edit in place.
216
+ Attribute only what the log supports; invent no failures. Do NOT propose an edit to THIS
217
+ feature's code or docs to silence a downstream failure — that would hide a real contract break.
218
+ outputs:
219
+ - { name: broken_downstream_file, from: "$.files" }
220
+
221
+ # Fires ONLY when the fence is RED — a failed test-run binds fence_ok=false, which renders
222
+ # as the string 'false' (json.dumps), so this condition is exactly "the fence is red".
223
+ # A green fence or no downstream users leaves fence_ok truthy and skips both this and the
224
+ # gate. The FIRST option is the safe default (non-interactive / CI → Abort). The chosen
225
+ # label is bound to gate_decision and later written into the OKF log for an audit trail.
226
+ - id: ask_override
227
+ condition: "{{fence_ok}} == false"
228
+ action: ask
229
+ prompt: |
230
+ DOWNSTREAM REGRESSION FENCE RED after change {{active_change}}.
231
+ {{downstream_count}} slice(s) depend on this aggregate: {{downstream_csv}}
232
+ Triage report: {{feature_dir}}/changes/{{active_change}}/broken-downstream.md
233
+ -- last test log ------------------------------------------------------------
234
+ {{fence_log}}
235
+ -----------------------------------------------------------------------------
236
+ Review the failing test(s) and the triage report. Is this break caused by THIS
237
+ change, or is it unrelated (a pre-existing / flaky / different-slice failure)?
238
+ - Abort = a real downstream break: stop, fix the downstream slice (or open
239
+ a CR on it to re-baseline its golden-master), then re-run finalize-delta.
240
+ - Override = you have reviewed the log and are DELIBERATELY closing X anyway.
241
+ options:
242
+ - "Abort (fix downstream first)"
243
+ - "Override (reviewed; close X anyway)"
244
+ answer_var: gate_decision
245
+
246
+ - id: downstream_gate
247
+ condition: "{{fence_ok}} == false"
248
+ action: verify_context
249
+ require_value: gate_decision
250
+ equals: "Override (reviewed; close X anyway)"
251
+ on_mismatch: stop
252
+ on_mismatch_message: "finalize-delta ABORTED — downstream fence RED after change {{active_change}} and the override was declined. {{downstream_count}} slice(s) depend on this aggregate ({{downstream_csv}}): the change would break a slice that USES this one. Triage: {{feature_dir}}/changes/{{active_change}}/broken-downstream.md. Fix the downstream break; or, if the behaviour change is intended, open a CR on the affected slice to re-baseline its golden-master. Then re-run /appweaver finalize-delta. Last log: {{fence_log}}"
253
+
254
+ # 2. Ensure the master design.md exists (idempotent) — the second merge target.
255
+ - id: design_scaffold
256
+ action: execute_script
257
+ script: { ref: actions }
258
+ subcommand: design-scaffold
259
+ args: ["--feature-dir", "{{feature_dir}}"]
260
+ outputs:
261
+ - { name: design_doc, from: "$.design_doc" }
262
+
263
+ # 3. Pre-execution hooks.
264
+ - id: resolve_pre_hooks
265
+ action: execute_script
266
+ script: { ref: actions }
267
+ subcommand: resolve-hooks
268
+ args: ["--phase", "before_finalize_cr"]
269
+ outputs:
270
+ - { name: before_hooks, from: "$.hooks" }
271
+ - id: dispatch_pre_hooks
272
+ action: dispatch_hooks
273
+ hooks_from_variable: before_hooks
274
+
275
+ # 4. DOC-FIRST merge: fold the two delta docs into the two master docs in place.
276
+ # Context is fed via build_context — agent_generate reads the ENVELOPE, not a
277
+ # step-level context: key (unlike agent_author/agent_query which read both).
278
+ - id: ctx_merge
279
+ action: build_context
280
+ context:
281
+ - { path: "{{feature_dir}}/changes/{{active_change}}/delta-spec.md" }
282
+ - { path: "{{feature_dir}}/changes/{{active_change}}/delta-design.md" }
283
+ - { path: "{{spec_file}}" }
284
+ - { path: "{{design_doc}}" }
285
+ # THE UI LANE's pair, INDEPENDENTLY optional — the merge task reads which of them
286
+ # arrived as its instruction. Neither: a backend-only feature, and a two-master
287
+ # merge is the complete outcome. Master only: the change did not reach the UI, or
288
+ # ⌛ delta-design-ui has not run — Change History row only. Both: a full third merge.
289
+ # Optional rather than gated because a missing UI document is an ordinary state
290
+ # here, not a misconfiguration worth stopping the merge over.
291
+ - { path: "{{ui_design_doc}}", optional: true }
292
+ - { path: "{{feature_dir}}/changes/{{active_change}}/delta-design.ui.md", optional: true }
293
+ - id: merge_delta
294
+ action: agent_generate
295
+ tools: "Read,Write,Edit"
296
+ permission_mode: acceptEdits
297
+ task: |
298
+ Merge the open change {{active_change}} into this feature's MASTER docs (all in
299
+ context), DOC-FIRST. The delta docs (in context) are the source of the change;
300
+ apply them and change nothing else.
301
+ HOW MANY MASTERS: spec.md and design.md always. design.ui.md — the FRONTEND lane's
302
+ master — only where it is in context (ui_design_exists={{ui_design_exists}}); its
303
+ delta, delta-design.ui.md, may or may not be there beside it. Absent both, the
304
+ feature has no UI half and merging two documents is the COMPLETE outcome, not a
305
+ step you skipped.
306
+ To spec.md:
307
+ - Add each ADDED user story as a US-n tagged `Added: {{active_change}}`, and fold
308
+ the ADDED / MODIFIED / REMOVED FR / BR / CN- / DC- / IC- / UX- items into their
309
+ sections using the master's vocabulary (EARS FR, BR invariants, etc.). Every class
310
+ the delta authored is merged, including UX- into Experience Standards: that section
311
+ is the UI lane's only carrier, so a UX- item left behind reaches no UI phase.
312
+ - Where a lift section (Constraints & NFRs, Data Classification, Integration
313
+ Contracts, Experience Standards) still reads "None", its first merged item REPLACES
314
+ that placeholder; a section the delta does not touch keeps its "None" verbatim.
315
+ - Apply every MODIFIED item as an in-place edit of the existing item; apply every
316
+ REMOVED item by removing it. Keep the rest of spec.md VERBATIM.
317
+ - Append a Change History row for {{active_change}} (date + one-line summary).
318
+ Its Version cell is {{next_version}} — the version this change ships as.
319
+ To design.md:
320
+ - ADD each new design element in its own structural section; apply each MODIFIED
321
+ element as an in-place edit of the existing element; remove each REMOVED element.
322
+ - Fold the delta's new DA-n / WA-n into the design's two deferral ledgers, and keep
323
+ the Traceability section in sync — every new FR / BR / CN- / DC- / IC- / US- / SC-
324
+ gets a design home. UX- is NOT among them: the service design realises no
325
+ experience standard, so a Traceability row for one is a fabrication. Keep the rest
326
+ of design.md VERBATIM.
327
+ - Append a Change History row for {{active_change}} (date + one-line summary),
328
+ Version cell {{next_version}}, in lockstep with the spec's row.
329
+ To design.ui.md — ONLY where it is in context. TWO CASES, decided by whether
330
+ delta-design.ui.md came with it:
331
+ - NO delta-design.ui.md in context (or one whose Change summary reads "No UI
332
+ consequence", its ADDED / MODIFIED / REMOVED sections all None): merge NOTHING
333
+ into the body. The change was server-side, or the UI lane's own delta command
334
+ has not run for it. Append ONLY a Change History row for {{active_change}} (date,
335
+ Version cell {{next_version}}, summary stating the change carried no UI content)
336
+ and change nothing else — close-delta stamps this document to {{next_version}} alongside
337
+ its siblings, so a header carrying a version that no row explains is
338
+ indistinguishable from a merge that dropped one. Do NOT invent UI content to
339
+ justify the row, and do NOT infer the experience change from the service delta:
340
+ design.md is not this document's source.
341
+ With delta-design.ui.md in context:
342
+ - ADD each new screen, component, state, interaction or contract binding into the
343
+ master's OWN section — the delta's "Section (§ in design.ui.md)" column names it.
344
+ Apply each MODIFIED element as an in-place edit of that element and remove each
345
+ REMOVED one. A shared component or shared state container is edited ONCE, where
346
+ the master defines it, never duplicated into a second place.
347
+ - Fold the delta's interaction states into the states the master already records
348
+ for those interactions, and its new DA-n / WA-n into the master's two ledgers.
349
+ - Keep the Traceability section — the lane's spine — in sync: every UX- the delta
350
+ realises and every new US- it serves gets a row naming its UI home. UX- BELONGS
351
+ HERE AND ONLY HERE: design.md must never carry a UX- row (the service design
352
+ realises no experience standard) and design.ui.md is the sole document that
353
+ does, so a UX- merged into the spec and into neither design has been dropped.
354
+ - Where a mandatory ledger still reads "None (as of vX.Y)", its first merged item
355
+ REPLACES that placeholder; a ledger the delta does not touch keeps it verbatim.
356
+ - Append a Change History row for {{active_change}} (date + one-line summary),
357
+ Version cell {{next_version}}, in lockstep with the other two.
358
+ Leave the `**Version**:` HEADER of EVERY document in context exactly as it is — it
359
+ still reads {{version}} and does not move here. close-delta stamps the headers to
360
+ {{next_version}} at the moment it bumps active_version.json, so every carrier of
361
+ the number changes in one step by one mechanism. Do not invent a version anywhere.
362
+ Preserve every unrelated section of EVERY doc byte-for-byte. Do NOT touch the
363
+ delta docs (close-delta archives them later) and do NOT touch any source code.
364
+ Report the files you changed.
365
+ outputs:
366
+ - { name: merged_docs, from: "$.files" }
367
+
368
+ - id: verify_merged
369
+ action: verify_context
370
+ require_non_empty: merged_docs
371
+ on_empty: stop
372
+ on_empty_message: "The merge produced no changes — expected edits to spec.md and design.md (and design.ui.md where the feature has a UI half). Ensure the delta docs are filled (not the empty template) and re-run."
373
+
374
+ # 4b. Refresh the cross-slice EDGES from the NOW-MERGED master design.md — the delta's
375
+ # added / removed references have just landed, so this is the first point they are
376
+ # authoritative. Reconcile-on-write: new deps appear in the used slices'
377
+ # Cross-References, dropped deps are pruned. `--origin auto` keeps the slice's
378
+ # provenance (greenfield vs reverse-engineered) from its design.md, so this works
379
+ # identically for a greenfield CR and a brownfield CR. Best-effort (never blocks close).
380
+ - id: xref_record
381
+ action: execute_script
382
+ on_error: continue
383
+ script: { ref: xref }
384
+ subcommand: record
385
+ args: ["--feature-dir", "{{feature_dir}}", "--design", "{{design_doc}}", "--origin", "auto"]
386
+ outputs:
387
+ - { name: xref_edge_count, from: "$.edge_count" }
388
+ - { name: xref_origin, from: "$.origin" }
389
+
390
+ # 4b-ii. Re-author the concept's Overview from the NOW-MERGED master design.md — the
391
+ # change may have moved the aggregate's boundary or invariants, and this is the
392
+ # first point the master states them. Section-scoped splice (the Cross-References
393
+ # rows other slices own are untouched). Best-effort; an empty answer is a no-op.
394
+ - id: okf_overview
395
+ action: agent_query
396
+ context: ["{{design_doc}}"]
397
+ include_standards: false
398
+ schema: { overview: "<2-4 sentences of prose>" }
399
+ mock: { overview: "" }
400
+ task: |
401
+ Write the OKF knowledge-concept Overview for the aggregate that the merged
402
+ design.md (in context) describes. 2-4 sentences of PROSE, distilled from §1
403
+ Domain Model: name the aggregate ROOT and what the aggregate IS; state the
404
+ INVARIANTS it guards; state its TRANSACTION BOUNDARY — what it OWNS inside the
405
+ boundary vs what it only REFERENCES by id. Plain prose only: no headings, no
406
+ bullets, no code fences, no file paths, and no restating of the dependency edges
407
+ (those live in the Depends-On / Cross-References tables). Describe only what the
408
+ design states — invent nothing.
409
+ outputs:
410
+ - { name: okf_overview, from: "$.overview" }
411
+
412
+ - id: okf_overview_write
413
+ action: execute_script
414
+ on_error: continue
415
+ script: { ref: xref }
416
+ subcommand: concept-overview
417
+ args: ["--feature-dir", "{{feature_dir}}", "--text", "{{okf_overview}}"]
418
+
419
+ # 4c. Anchor the OKF bundle's freshness journal to the current commit (log.md, OKF §7).
420
+ # Best-effort + git-aware: a no-op when there is no bundle or no commit, so it never
421
+ # writes a non-conformant block. Records that this CR refreshed the cross-references.
422
+ - id: xref_log
423
+ action: execute_script
424
+ on_error: continue
425
+ script: { ref: xref }
426
+ subcommand: log
427
+ args: ["--note", "CR {{active_change}} merged (downstream gate: {{gate_decision}}) — OKF cross-references refreshed"]
428
+ outputs:
429
+ - { name: xref_log, from: "$.log" }
430
+
431
+ # 5. NO ARCHIVE, NO VERSION BUMP HERE. Both moved to close-delta, which runs after
432
+ # analyze-slice — see the header. The change stays OPEN past this stage on purpose:
433
+ # it is what keeps a red analyze-slice recoverable ("fix and re-run") instead of
434
+ # landing on an already-shipped version. The delta docs therefore remain in
435
+ # changes/{{active_change}}/ even though their content is now merged; close-delta
436
+ # moves them to changes/archive/.
437
+
438
+ # 6. Post-execution hooks.
439
+ - id: resolve_post_hooks
440
+ action: execute_script
441
+ script: { ref: actions }
442
+ subcommand: resolve-hooks
443
+ args: ["--phase", "after_finalize_cr"]
444
+ outputs:
445
+ - { name: after_hooks, from: "$.hooks" }
446
+ - id: dispatch_post_hooks
447
+ action: dispatch_hooks
448
+ hooks_from_variable: after_hooks
449
+
450
+ outputs:
451
+ feature_dir: "{{feature_dir}}"
452
+ cr_id: "{{active_change}}"
453
+ merged_docs: "{{merged_docs}}"
454
+ version: "{{version}}"
455
+ downstream_count: "{{downstream_count}}"
456
+ gate_decision: "{{gate_decision}}"
457
+ xref_edge_count: "{{xref_edge_count}}"
458
+ ui_design_updated: "{{ui_design_exists}}" # true ⇒ design.ui.md was a target of this stage. It reports
459
+ # the MASTER's presence, not how much moved: a change with no
460
+ # UI delta still takes its Change History row, because
461
+ # close-delta stamps the header either way.
462
+ next: "Delta MERGED into spec.md + design.md, and into design.ui.md where the feature has a UI half (ui_design_updated={{ui_design_exists}} — with a UI delta present that is a full merge, without one it is the Change History row that keeps the header close-delta stamps explainable); OKF edges refreshed ({{xref_edge_count}} dep(s)), {{downstream_count}} downstream slice(s) fenced (gate: {{gate_decision}}). Change {{active_change}} is STILL OPEN and the version is still {{version}}. Next: /appweaver analyze-slice — it now reads a master spec that carries this change, and a red result is still recoverable because nothing has been archived. Then /appweaver close-delta archives the change and bumps the version."