aw-spec-cli 0.1.5 → 0.1.7

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 (205) hide show
  1. package/assets/.agents/agent.json +1 -1
  2. package/assets/.agents/skills/{aw-spec-orch → appweaver}/SKILL.md +10 -10
  3. package/assets/.agents/skills/{aw-spec-orch-demo → appweaver-demo}/SKILL.md +9 -9
  4. package/assets/.claude/agent.json +1 -1
  5. package/assets/.claude/skills/{aw-spec-orch → appweaver}/SKILL.md +10 -10
  6. package/assets/.claude/skills/{aw-spec-orch-demo → appweaver-demo}/SKILL.md +9 -9
  7. package/assets/.kilocode/agent.json +1 -1
  8. package/assets/.kilocode/workflows/{aw-spec-orch-demo.md → appweaver-demo.md} +9 -9
  9. package/assets/.kilocode/workflows/{aw-spec-orch.md → appweaver.md} +10 -10
  10. package/assets/docs/pharma-constitution.my-ref.md +86 -0
  11. package/dist/utils/paths.js +1 -1
  12. package/dist/utils/paths.js.map +1 -1
  13. package/package.json +1 -1
  14. package/assets/.aw-spec/DESIGN-FORMAT.md +0 -151
  15. package/assets/.aw-spec/ORCH-DIALECT.md +0 -156
  16. package/assets/.aw-spec/RULE-PARTITION.md +0 -126
  17. package/assets/.aw-spec/domain.json +0 -3
  18. package/assets/.aw-spec/extensions/.registry +0 -19
  19. package/assets/.aw-spec/extensions/agent-context/README.md +0 -57
  20. package/assets/.aw-spec/extensions/agent-context/agent-context-config.yml +0 -4
  21. package/assets/.aw-spec/extensions/agent-context/commands/aw-spec.agent-context.update.md +0 -26
  22. package/assets/.aw-spec/extensions/agent-context/extension.yml +0 -37
  23. package/assets/.aw-spec/extensions/agent-context/scripts/bash/update-agent-context.sh +0 -201
  24. package/assets/.aw-spec/extensions/agent-context/scripts/powershell/update-agent-context.ps1 +0 -237
  25. package/assets/.aw-spec/extensions.yml +0 -16
  26. package/assets/.aw-spec/feature.json +0 -3
  27. package/assets/.aw-spec/init-options.json +0 -9
  28. package/assets/.aw-spec/integration.json +0 -15
  29. package/assets/.aw-spec/integrations/aw-spec.manifest.json +0 -9
  30. package/assets/.aw-spec/interpreter/run-skill.py +0 -1158
  31. package/assets/.aw-spec/memory/constitution.md +0 -50
  32. package/assets/.aw-spec/orchestrator/AGENT-PROFILE.md +0 -94
  33. package/assets/.aw-spec/orchestrator/README.md +0 -300
  34. package/assets/.aw-spec/orchestrator/adapters/claude_agent_sdk.py +0 -74
  35. package/assets/.aw-spec/orchestrator/adapters/google_antigravity.py +0 -74
  36. package/assets/.aw-spec/orchestrator/modules/delta-design.orch.yaml +0 -105
  37. package/assets/.aw-spec/orchestrator/modules/delta-spec.orch.yaml +0 -79
  38. package/assets/.aw-spec/orchestrator/modules/domain-select.orch.yaml +0 -81
  39. package/assets/.aw-spec/orchestrator/modules/tech-select.orch.yaml +0 -75
  40. package/assets/.aw-spec/orchestrator/orchestrator.py +0 -1721
  41. package/assets/.aw-spec/orchestrator/rev-templates/ai-rules.reference.md +0 -40
  42. package/assets/.aw-spec/orchestrator/rev-templates/comandrulemap.skeleton.md +0 -59
  43. package/assets/.aw-spec/orchestrator/rev-templates/commandtechrulemap.skeleton.md +0 -97
  44. package/assets/.aw-spec/orchestrator/rev-templates/domain-constitution.skeleton.md +0 -61
  45. package/assets/.aw-spec/orchestrator/rev-templates/domain-requirements.skeleton.md +0 -48
  46. package/assets/.aw-spec/orchestrator/rev-templates/domain-rule-file.skeleton.md +0 -39
  47. package/assets/.aw-spec/orchestrator/rev-templates/technical-constitution.skeleton.md +0 -106
  48. package/assets/.aw-spec/orchestrator/rev-templates/technical-rule-file.skeleton.md +0 -54
  49. package/assets/.aw-spec/orchestrator/workflows/_smoke.orch.yaml +0 -160
  50. package/assets/.aw-spec/orchestrator/workflows/aw-spec-add-component.orch.yaml +0 -244
  51. package/assets/.aw-spec/orchestrator/workflows/aw-spec-adopt.orch.yaml +0 -775
  52. package/assets/.aw-spec/orchestrator/workflows/aw-spec-analyze-delta-design.orch.yaml +0 -248
  53. package/assets/.aw-spec/orchestrator/workflows/aw-spec-analyze-design.orch.yaml +0 -261
  54. package/assets/.aw-spec/orchestrator/workflows/aw-spec-analyze-slice.orch.yaml +0 -425
  55. package/assets/.aw-spec/orchestrator/workflows/aw-spec-build.orch.yaml +0 -188
  56. package/assets/.aw-spec/orchestrator/workflows/aw-spec-characterize.orch.yaml +0 -474
  57. package/assets/.aw-spec/orchestrator/workflows/aw-spec-close-delta.orch.yaml +0 -181
  58. package/assets/.aw-spec/orchestrator/workflows/aw-spec-constitution.orch.yaml +0 -284
  59. package/assets/.aw-spec/orchestrator/workflows/aw-spec-demo.orch.yaml +0 -103
  60. package/assets/.aw-spec/orchestrator/workflows/aw-spec-dependency-tree.orch.yaml +0 -69
  61. package/assets/.aw-spec/orchestrator/workflows/aw-spec-deploy.orch.yaml +0 -85
  62. package/assets/.aw-spec/orchestrator/workflows/aw-spec-design.orch.yaml +0 -382
  63. package/assets/.aw-spec/orchestrator/workflows/aw-spec-finalize-delta.orch.yaml +0 -382
  64. package/assets/.aw-spec/orchestrator/workflows/aw-spec-foundation.orch.yaml +0 -246
  65. package/assets/.aw-spec/orchestrator/workflows/aw-spec-implement-delta.orch.yaml +0 -231
  66. package/assets/.aw-spec/orchestrator/workflows/aw-spec-implement.orch.yaml +0 -258
  67. package/assets/.aw-spec/orchestrator/workflows/aw-spec-inventory.orch.yaml +0 -236
  68. package/assets/.aw-spec/orchestrator/workflows/aw-spec-onboard.orch.yaml +0 -949
  69. package/assets/.aw-spec/orchestrator/workflows/aw-spec-parity.orch.yaml +0 -293
  70. package/assets/.aw-spec/orchestrator/workflows/aw-spec-run.orch.yaml +0 -177
  71. package/assets/.aw-spec/orchestrator/workflows/aw-spec-select-domain.orch.yaml +0 -79
  72. package/assets/.aw-spec/orchestrator/workflows/aw-spec-select-feature.orch.yaml +0 -128
  73. package/assets/.aw-spec/orchestrator/workflows/aw-spec-specify.orch.yaml +0 -412
  74. package/assets/.aw-spec/scripts/bash/aw-inventory.sh +0 -14
  75. package/assets/.aw-spec/scripts/bash/aw-parity.sh +0 -13
  76. package/assets/.aw-spec/scripts/bash/aw-rev-constitution.sh +0 -13
  77. package/assets/.aw-spec/scripts/bash/aw-spec-actions.sh +0 -1899
  78. package/assets/.aw-spec/scripts/bash/aw-xref.sh +0 -15
  79. package/assets/.aw-spec/scripts/bash/common.sh +0 -533
  80. package/assets/.aw-spec/scripts/powershell/aw-inventory.ps1 +0 -14
  81. package/assets/.aw-spec/scripts/powershell/aw-parity.ps1 +0 -13
  82. package/assets/.aw-spec/scripts/powershell/aw-rev-constitution.ps1 +0 -13
  83. package/assets/.aw-spec/scripts/powershell/aw-spec-actions.ps1 +0 -1563
  84. package/assets/.aw-spec/scripts/powershell/aw-xref.ps1 +0 -15
  85. package/assets/.aw-spec/scripts/python/aw-inventory.py +0 -683
  86. package/assets/.aw-spec/scripts/python/aw-parity.py +0 -380
  87. package/assets/.aw-spec/scripts/python/aw-rev-constitution.py +0 -312
  88. package/assets/.aw-spec/scripts/python/aw-xref.py +0 -1330
  89. package/assets/.aw-spec/scripts/python/validate_okf.py +0 -349
  90. package/assets/.aw-spec/templates/constitution-domain-template.md +0 -75
  91. package/assets/.aw-spec/templates/constitution-technical-template.md +0 -70
  92. package/assets/.aw-spec/templates/delta-design-template.md +0 -69
  93. package/assets/.aw-spec/templates/delta-spec-template.md +0 -60
  94. package/assets/.aw-spec/templates/design-template.md +0 -383
  95. package/assets/.aw-spec/templates/okf-concept-template.md +0 -103
  96. package/assets/.aw-spec/templates/parity-manifest-template.json +0 -49
  97. package/assets/.aw-spec/templates/source-map-template.md +0 -85
  98. package/assets/.aw-spec/templates/spec-template.md +0 -252
  99. package/assets/docs/ModularMonolith/ModularMonolith.Reference.pack.txt +0 -25248
  100. package/assets/docs/ModularMonolith/ModularMonolith.pack.txt +0 -5726
  101. package/assets/docs/ModularMonolith/pack-foundation.ps1 +0 -145
  102. package/assets/docs/ModularMonolith/pack-foundation.sh +0 -196
  103. package/assets/docs/ModularMonolith/pack-reference-foundation.ps1 +0 -157
  104. package/assets/docs/ModularMonolith/pack-reference-foundation.sh +0 -209
  105. package/assets/docs/ModularMonolith/unpack-foundation.ps1 +0 -126
  106. package/assets/docs/ModularMonolith/unpack-foundation.sh +0 -217
  107. package/assets/docs/ModularMonolith/unpack-reference-foundation.ps1 +0 -129
  108. package/assets/docs/ModularMonolith/unpack-reference-foundation.sh +0 -218
  109. package/assets/docs/README.md +0 -106
  110. package/assets/docs/VerticalSlice/PACKAGING.md +0 -185
  111. package/assets/docs/VerticalSlice/VerticalSlice.Reference.pack.txt +0 -19318
  112. package/assets/docs/VerticalSlice/VerticalSlice.pack.txt +0 -2833
  113. package/assets/docs/VerticalSlice/pack-foundation.ps1 +0 -145
  114. package/assets/docs/VerticalSlice/pack-foundation.sh +0 -196
  115. package/assets/docs/VerticalSlice/pack-reference-foundation.ps1 +0 -157
  116. package/assets/docs/VerticalSlice/pack-reference-foundation.sh +0 -209
  117. package/assets/docs/VerticalSlice/unpack-foundation.ps1 +0 -126
  118. package/assets/docs/VerticalSlice/unpack-foundation.sh +0 -217
  119. package/assets/docs/VerticalSlice/unpack-reference-foundation.ps1 +0 -129
  120. package/assets/docs/VerticalSlice/unpack-reference-foundation.sh +0 -218
  121. package/assets/docs/architecture/clean-architecture.md +0 -71
  122. package/assets/docs/architecture/cqrs.md +0 -141
  123. package/assets/docs/architecture/eventing.md +0 -83
  124. package/assets/docs/architecture/folder-structure.md +0 -61
  125. package/assets/docs/architecture/modular-monolith.md +0 -47
  126. package/assets/docs/architecture/persistence.md +0 -269
  127. package/assets/docs/architecture/testing.md +0 -55
  128. package/assets/docs/architecture/vertical-slices.md +0 -201
  129. package/assets/docs/components/Email/README.md +0 -119
  130. package/assets/docs/components/Email/ReferenceEndpoints/SendEmailEndpoint.cs +0 -84
  131. package/assets/docs/components/Email/integration.md +0 -300
  132. package/assets/docs/components/Jobs/README.md +0 -113
  133. package/assets/docs/components/Jobs/integration.md +0 -259
  134. package/assets/docs/components/QrGenerator/README.md +0 -85
  135. package/assets/docs/components/QrGenerator/ReferenceEndpoints/GenerateQrEndpoint.cs +0 -57
  136. package/assets/docs/components/QrGenerator/integration.md +0 -230
  137. package/assets/docs/components/README.md +0 -74
  138. package/assets/docs/domain/domain-driven-design.md +0 -212
  139. package/assets/docs/domainspecs/healthcare/ai-rules.domain.md +0 -34
  140. package/assets/docs/domainspecs/healthcare/api-versioning.domain.md +0 -17
  141. package/assets/docs/domainspecs/healthcare/auditing.domain.md +0 -97
  142. package/assets/docs/domainspecs/healthcare/authorization.domain.md +0 -26
  143. package/assets/docs/domainspecs/healthcare/clinical-terms.md +0 -20
  144. package/assets/docs/domainspecs/healthcare/coding-standards.domain.md +0 -26
  145. package/assets/docs/domainspecs/healthcare/comandrulemap.md +0 -100
  146. package/assets/docs/domainspecs/healthcare/commandtechrulemap.md +0 -119
  147. package/assets/docs/domainspecs/healthcare/consent.md +0 -19
  148. package/assets/docs/domainspecs/healthcare/cqrs.domain.md +0 -12
  149. package/assets/docs/domainspecs/healthcare/data-classification.domain.md +0 -28
  150. package/assets/docs/domainspecs/healthcare/dependency-policy.domain.md +0 -11
  151. package/assets/docs/domainspecs/healthcare/dicom.md +0 -15
  152. package/assets/docs/domainspecs/healthcare/domain-driven-design.domain.md +0 -28
  153. package/assets/docs/domainspecs/healthcare/domain-requirements.md +0 -55
  154. package/assets/docs/domainspecs/healthcare/eventing.domain.md +0 -18
  155. package/assets/docs/domainspecs/healthcare/fhir.md +0 -36
  156. package/assets/docs/domainspecs/healthcare/folder-structure.domain.md +0 -23
  157. package/assets/docs/domainspecs/healthcare/hipaa.md +0 -34
  158. package/assets/docs/domainspecs/healthcare/hl7.md +0 -15
  159. package/assets/docs/domainspecs/healthcare/integration-terms.md +0 -21
  160. package/assets/docs/domainspecs/healthcare/persistence.domain.md +0 -20
  161. package/assets/docs/domainspecs/healthcare/terminology.md +0 -30
  162. package/assets/docs/domainspecs/healthcare/testing.domain.md +0 -15
  163. package/assets/docs/domainspecs/healthcare/vertical-slices.domain.md +0 -18
  164. package/assets/docs/domainspecs/healthcare/zero-trust.domain.md +0 -12
  165. package/assets/docs/domainspecs/pharma/ai-rules.domain.md +0 -32
  166. package/assets/docs/domainspecs/pharma/api-versioning.domain.md +0 -20
  167. package/assets/docs/domainspecs/pharma/atc.md +0 -22
  168. package/assets/docs/domainspecs/pharma/auditing.domain.md +0 -90
  169. package/assets/docs/domainspecs/pharma/authorization.domain.md +0 -25
  170. package/assets/docs/domainspecs/pharma/coding-standards.domain.md +0 -28
  171. package/assets/docs/domainspecs/pharma/comandrulemap.md +0 -108
  172. package/assets/docs/domainspecs/pharma/commandtechrulemap.md +0 -119
  173. package/assets/docs/domainspecs/pharma/cqrs.domain.md +0 -16
  174. package/assets/docs/domainspecs/pharma/data-classification.domain.md +0 -24
  175. package/assets/docs/domainspecs/pharma/data-provenance.md +0 -21
  176. package/assets/docs/domainspecs/pharma/dependency-policy.domain.md +0 -11
  177. package/assets/docs/domainspecs/pharma/domain-driven-design.domain.md +0 -36
  178. package/assets/docs/domainspecs/pharma/domain-requirements.md +0 -99
  179. package/assets/docs/domainspecs/pharma/eventing.domain.md +0 -18
  180. package/assets/docs/domainspecs/pharma/fhir.md +0 -31
  181. package/assets/docs/domainspecs/pharma/folder-structure.domain.md +0 -24
  182. package/assets/docs/domainspecs/pharma/hl7.md +0 -17
  183. package/assets/docs/domainspecs/pharma/idmp.md +0 -26
  184. package/assets/docs/domainspecs/pharma/integration-terms.md +0 -21
  185. package/assets/docs/domainspecs/pharma/ndc.md +0 -28
  186. package/assets/docs/domainspecs/pharma/persistence.domain.md +0 -23
  187. package/assets/docs/domainspecs/pharma/pharma-terms.md +0 -27
  188. package/assets/docs/domainspecs/pharma/product-lifecycle.domain.md +0 -30
  189. package/assets/docs/domainspecs/pharma/regulatory-compliance.md +0 -19
  190. package/assets/docs/domainspecs/pharma/terminology.md +0 -32
  191. package/assets/docs/domainspecs/pharma/testing.domain.md +0 -19
  192. package/assets/docs/domainspecs/pharma/vertical-slices.domain.md +0 -17
  193. package/assets/docs/domainspecs/pharma/zero-trust.domain.md +0 -12
  194. package/assets/docs/glossary/ai-rules.md +0 -59
  195. package/assets/docs/governance/api-versioning.md +0 -99
  196. package/assets/docs/governance/coding-standards.md +0 -87
  197. package/assets/docs/governance/dependency-policy.md +0 -40
  198. package/assets/docs/interop/ihe-conformance.md +0 -31
  199. package/assets/docs/requirement-spec.txt +0 -27
  200. package/assets/docs/security/auditing.md +0 -160
  201. package/assets/docs/security/authorization-matrix.md +0 -14
  202. package/assets/docs/security/authorization.md +0 -87
  203. package/assets/docs/security/data-classification.md +0 -38
  204. package/assets/docs/security/zero-trust.md +0 -76
  205. package/assets/docs/technology-constitution.md +0 -172
@@ -1,474 +0,0 @@
1
- # =============================================================================
2
- # aw-spec-characterize (orchestrator) — B2 of the Brownfield Pipeline
3
- #
4
- # The REGRESSION FENCE. After a slice is adopted (spec.md + design.md +
5
- # source-map.md), pin what the legacy code CURRENTLY DOES as golden-master /
6
- # characterization tests — observed behaviour asserted AS-IS, bugs and quirks
7
- # included. These are NOT correctness claims; they are the missing behaviour
8
- # ORACLE that lets the slice be changed under a net.
9
- #
10
- # inventory → adopt → CHARACTERIZE → [ forward pipeline / parity → cutover ] ← you are here
11
- #
12
- # Characterize is to brownfield what analyze-slice is to greenfield: greenfield verifies
13
- # against ACs it authored; brownfield verifies against behaviour it OBSERVED. The
14
- # key inversion vs. analyze-slice: here the CODE is the oracle — if a characterization
15
- # test disagrees with the running code, the TEST is wrong (fix the assertion to
16
- # the observed output), never the production code. When a golden-master later
17
- # MUST change, that is a deliberate, reviewed decision recorded as a MODIFIED spec
18
- # item via the CR delta loop — never a silent drift.
19
- #
20
- # Characterize GENERATES tests only; it does NOT modify production code and does
21
- # NOT change spec.md / design.md.
22
- #
23
- # EXISTING TESTS. A legacy repo usually already has some. They are not a fence — they
24
- # assert INTENDED behaviour, which is exactly what brownfield cannot assume. So before
25
- # authoring, characterize scans for overlap and asks the operator how to resolve it
26
- # (keep both / keep existing / override), defaulting to the additive choice. Overlap only
27
- # counts when the behaviour AND the seam match and the existing test agrees with the code;
28
- # an existing test that DISAGREES is a drift finding routed to a CR, never deduped.
29
- #
30
- # DRIFT REPORT. Those disagreements are the most valuable thing a brownfield adoption
31
- # surfaces — intent (what a past author asserted) vs. as-built (what the code does) — so
32
- # they are not left in a run log: characterize writes them to `drifted-tests.md` beside the
33
- # slice's spec, one triaged finding per existing test, as the CR queue. It is rewritten on
34
- # every run (never appended), so it always reflects the CURRENT scan and can never go stale.
35
- #
36
- # Launch: /aw-spec-orch characterize [strategy] [focus/guidance]
37
- # Prereq: /aw-spec-orch adopt <Aggregate> (spec.md + design.md + source-map.md),
38
- # and a scaffolded project (/aw-spec-orch foundation) to host + run tests.
39
- # =============================================================================
40
-
41
- name: aw-spec-characterize
42
- description: Generate golden-master / characterization tests that pin the adopted slice's CURRENT observed behaviour as-is (quirks included), reconciling them against the legacy project's existing tests under an operator-chosen dedup policy, reporting intent-vs-as-built drift to drifted-tests.md, then run them green against the legacy code — the brownfield regression fence. The code is the oracle (fix the test, never the code); does not modify production code or the spec/design.
43
- version: 1.2.0
44
- agent_agnostic: true
45
- dialect: aw-spec.orchestrator/v1
46
-
47
- inputs:
48
- user_input:
49
- description: Optional focus / guidance (an area to prioritize, extra input cases to cover).
50
- required: false
51
- bind: USER_INPUT
52
-
53
- scripts:
54
- actions:
55
- sh: .aw-spec/scripts/bash/aw-spec-actions.sh
56
- ps1: .aw-spec/scripts/powershell/aw-spec-actions.ps1
57
-
58
- # Sticky standards seed = the UNIVERSAL always-on rule only (ai-rules). The FRAMEWORK /
59
- # test-generation set (same as implement/analyze-slice — HOW to write + place tests) is no
60
- # longer hardcoded here — it is now CONFIGURATION, loaded per-command from
61
- # docs/domainspecs/<domain>/commandtechrulemap.md under "## /aw-spec-characterize" by the
62
- # tech-select module (see the tech_select step below). No domain files: the behaviour to
63
- # fence comes from the CODE + the adopted spec/design/source-map (constitution.technical.md
64
- # is referred to directly as context), not from domain rules — the tech map lists only
65
- # technical files. (missing files skipped at assembly time)
66
- standards:
67
- - { path: docs/glossary/ai-rules.md, optional: true }
68
-
69
- vars:
70
- test_ok: "false"
71
- # Dedup-pass defaults, so the outputs stay readable when the scan finds nothing
72
- # (a repo with no pre-existing tests skips the question entirely).
73
- dup_count: "0"
74
- duplicates: ""
75
- drift_count: "0"
76
- drift: ""
77
- dedup_policy: "Keep both (add the golden-master alongside the existing test)"
78
-
79
- workflow:
80
-
81
- # 0. TECHNICAL rule files → sticky standards (configuration, not hardcoded). tech-select
82
- # reads docs/domainspecs/<domain>/commandtechrulemap.md under "## /aw-spec-characterize"
83
- # and loads that test-generation set into the sticky standards the agent_generate steps
84
- # ALWAYS prepend. No domain rule file is loaded here — the tech map lists only technical
85
- # files. No blocking gate: an unconfigured project soft-continues (the golden-master is
86
- # still fenced from the CODE + adopted spec/design/source-map + constitution.technical.md).
87
- - id: tech_select
88
- action: include
89
- module: .aw-spec/orchestrator/modules/tech-select.orch.yaml
90
- with: { command: aw-spec-characterize }
91
-
92
- # 1. Resolve the current feature + its adopted artifacts.
93
- - id: feature_paths
94
- action: execute_script
95
- on_error: continue # never crash raw on 'no feature set' — the gate below explains it
96
- script: { ref: actions }
97
- subcommand: feature-paths
98
- outputs:
99
- - { name: feature_dir, from: "$.feature_dir" }
100
- - { name: spec_file, from: "$.spec_file" }
101
- - { name: design_file, from: "$.design_file" }
102
- - { name: spec_exists, from: "$.spec_exists" }
103
- - { name: design_exists, from: "$.design_exists" }
104
-
105
- - id: require_feature
106
- action: verify_context
107
- require_non_empty: feature_dir
108
- on_empty: stop
109
- on_empty_message: "No active feature. Run /aw-spec-orch select-feature first (pick or create the aggregate, e.g. Order), then re-run characterize."
110
-
111
- - id: verify_spec
112
- action: verify_context
113
- require_true: spec_exists
114
- on_false: stop
115
- on_false_message: "No spec.md for the current feature. Adopt the slice first: /aw-spec-orch adopt <Aggregate>."
116
-
117
- - id: verify_design
118
- action: verify_context
119
- require_true: design_exists
120
- on_false: stop
121
- on_false_message: "No design.md for the current feature. Run /aw-spec-orch adopt <Aggregate> (or /aw-spec-orch design) first."
122
-
123
- # 1b. Require the ADOPT source-map sidecar — characterize fences an ADOPTED
124
- # legacy slice (its as-built quirks + owned source files live here).
125
- - id: set_source_map
126
- action: set
127
- vars:
128
- source_map: "{{feature_dir}}/source-map.md"
129
- # The drift report lives BESIDE the slice's spec (like source-map.md) — it is a
130
- # per-slice adoption artifact, not a run log, and is rewritten on every run.
131
- drift_report: "{{feature_dir}}/drifted-tests.md"
132
- # required_files raises a fixed Stop that NAMES the missing file (it does not
133
- # take a custom message) — "required file not in context: specs/<Agg>/source-map.md"
134
- # → run /aw-spec-orch adopt first (it writes source-map.md with files + quirks).
135
- - id: require_source_map
136
- action: verify_context
137
- required_files: ["{{source_map}}"]
138
-
139
- # 1c. Require the FOUNDATION — a compiling project — to host + run the tests.
140
- - id: detect_foundation
141
- action: execute_script
142
- script: { ref: actions }
143
- subcommand: detect-project
144
- outputs:
145
- - { name: foundation_present, from: "$.scaffolded" }
146
-
147
- - id: foundation_gate
148
- action: verify_context
149
- require_true: foundation_present
150
- on_false: stop
151
- on_false_message: "No scaffolded project found — run /aw-spec-orch foundation <FoundationName> <AppName> first. characterize writes tests INTO the project's test tree and RUNS them; there is nowhere to place/run them without it."
152
-
153
- # 2. Pre-execution hooks.
154
- - id: resolve_pre_hooks
155
- action: execute_script
156
- script: { ref: actions }
157
- subcommand: resolve-hooks
158
- args: ["--phase", "before_characterize"]
159
- outputs:
160
- - { name: before_hooks, from: "$.hooks" }
161
- - id: dispatch_pre_hooks
162
- action: dispatch_hooks
163
- hooks_from_variable: before_hooks
164
-
165
- # ═══════ 3. DEDUP PASS — reconcile against the legacy project's EXISTING tests ═══════
166
- # A brownfield repo usually ALREADY has unit tests. They are not a fence: they assert
167
- # INTENDED behaviour (and may be stale, skipped, or aspirational), whereas a golden-master
168
- # asserts OBSERVED behaviour as-is. So they neither substitute for the fence nor are they
169
- # disposable — the operator decides. Scan first (read-only), then ask ONLY if the scan
170
- # found real overlap, so a repo with no tests is never interrupted.
171
- #
172
- # Two rules keep this honest, and both live in the scan schema rather than the question:
173
- # • SAME BEHAVIOUR + DIFFERENT SEAM is NOT a duplicate. An existing test that mocks the
174
- # repository and asserts a domain method is COMPLEMENTARY to a golden-master asserting
175
- # the endpoint response; deduping them would punch a hole in the fence, which is
176
- # deliberately pinned at the outermost seam so it survives an internal refactor.
177
- # • DISAGREEMENT IS NOT DUPLICATION. An existing test asserting behaviour the code does
178
- # NOT exhibit is a DRIFT FINDING (intent vs. as-built) — the most valuable thing a
179
- # brownfield adoption surfaces. It is reported, never resolved by the dedup policy:
180
- # overriding it would delete the bug report, and keeping it leaves a red test the
181
- # capture loop cannot reach (that loop only sees char_files). Route it to a CR.
182
- - id: ctx_dup_scan
183
- action: build_context
184
- context:
185
- - { path: "{{source_map}}" }
186
- - { path: "{{spec_file}}" }
187
- - { path: "{{design_file}}" }
188
- - id: scan_existing_tests
189
- action: agent_query
190
- include_standards: false
191
- schema:
192
- duplicates: [ { behaviour: "<observable behaviour>", spec_id: "<US-/FR-/BR- id>", existing_test: "<file:test-name>", seam: "<endpoint|handler|domain|persistence>", source_file: "<production file it covers>" } ]
193
- drift: [ { existing_test: "<file:test-name>", asserts: "<what the test expects>", code_actually: "<what the code does>", source_file: "<production file it covers>", spec_id: "<US-/FR-/BR- id, or ->", test_state: "<failing|ignored|inconclusive>" } ]
194
- dup_count: 0
195
- drift_count: 0
196
- mock: { duplicates: [], drift: [], dup_count: 0, drift_count: 0 }
197
- task: |
198
- Before any characterization tests are written, survey the project's EXISTING
199
- tests for this slice and report where they would OVERLAP the golden-masters
200
- about to be generated. Read the slice's production files (listed in
201
- source-map.md, in context) and locate the existing test project(s) covering
202
- them (glob the test tree; match by class/namespace/file under test).
203
- Report, for each observable behaviour of this slice:
204
- - `duplicates` — an existing test that pins the SAME behaviour at the SAME (or
205
- equivalent) seam AND currently AGREES with what the code does. ONLY these are
206
- duplicates. A test at a DIFFERENT seam (e.g. a mocked domain-level unit test vs.
207
- an endpoint/persisted-state assertion) is COMPLEMENTARY, not a duplicate — do NOT
208
- list it. A skipped/ignored test is NOT a duplicate (it pins nothing) — do not list it.
209
- - `drift` — an existing test whose EXPECTATION differs from what the code actually
210
- does right now (including tests that are currently failing, or that assert an
211
- intended-but-absent behaviour). These are NOT duplicates: they are intent-vs-as-built
212
- findings. List them separately; they are reported, never deduped. For each, set
213
- `test_state`: `failing` (it runs and is red today — it will also redden the
214
- characterize suite run), `ignored` (skipped/commented-out/[Ignore]d, so it is
215
- DORMANT intent and blocks nothing), or `inconclusive` (you cannot tell from
216
- reading alone — say so rather than guessing). Quote the assertion in `asserts`
217
- and the observed behaviour in `code_actually` precisely enough that a reviewer
218
- can act without re-reading both files.
219
- Set dup_count / drift_count to the list lengths. If the project has no existing
220
- tests for this slice, return empty lists and zero counts. Do not modify any file.
221
- outputs:
222
- - { name: duplicates, from: "$.duplicates" }
223
- - { name: dup_count, from: "$.dup_count" }
224
- - { name: drift, from: "$.drift" }
225
- - { name: drift_count, from: "$.drift_count" }
226
-
227
- # ── DRIFT REPORT ── the scan's second list is the valuable one, so it becomes a durable
228
- # per-slice artifact rather than a line in a run log. Written BEFORE the dedup question so
229
- # the operator can open it while answering, and UNCONDITIONALLY — a report that is only
230
- # written when drift exists would leave a stale file from an earlier run standing after the
231
- # drift was resolved, which is worse than no file. A zero-drift run rewrites it to say so.
232
- - id: ctx_drift_report
233
- action: build_context
234
- vars:
235
- drift: "{{drift}}"
236
- drift_count: "{{drift_count}}"
237
- context:
238
- - { path: "{{source_map}}" } # source files + as-built quirks
239
- - { path: "{{spec_file}}" } # for the US-/FR-/BR- ids to cite
240
- - id: write_drift_report
241
- action: agent_author
242
- include_standards: false # a report, not generated code
243
- output_target: { type: file, path: "{{drift_report}}" }
244
- task: |
245
- Author the INTENT-VS-AS-BUILT DRIFT REPORT for this slice: the pre-existing tests
246
- whose expectations disagree with what the legacy code actually does. This is the
247
- CR queue for the adoption — each finding is a decision someone must make, NOT a
248
- thing characterize may fix. {{drift_count}} finding(s) from the scan:
249
- {{drift}}
250
- Write markdown, in this order:
251
- - `# Drifted Tests — <slice>` and a one-line statement of what this file is:
252
- pre-existing tests that assert behaviour the code does not exhibit, found while
253
- building the regression fence. Note that characterize did NOT change them.
254
- - A SUMMARY line: total findings, split by test_state (failing / ignored /
255
- inconclusive). Say plainly that `failing` findings are red in the suite TODAY
256
- (they will also show in the characterize test run and are not the golden-masters'
257
- fault), while `ignored` ones are dormant intent that blocks nothing.
258
- - One `##` section per finding, titled with the test. Under it state, each on its
259
- own labelled line: the production file it covers, the spec id it maps to (or `—`),
260
- its state, what the TEST asserts, what the CODE ACTUALLY does, and a RESOLUTION
261
- line offering the reviewer the real choice — either the code is wrong (a defect:
262
- open a CR to change the code, and the golden-master pinning today's behaviour
263
- must then change with it as a reviewed MODIFIED spec item) or the TEST is wrong /
264
- obsolete (delete or correct it in a CR). Recommend one and say why; do not
265
- pretend to certainty you do not have — for `inconclusive`, say what must be run
266
- or read to decide.
267
- - A closing `## How to use this file` noting it is REGENERATED on every
268
- `/aw-spec-orch characterize` run (do not edit it in place — resolve findings via
269
- CRs and re-run), and that the golden-masters deliberately pin the code's CURRENT
270
- behaviour, drift included.
271
- If there are no findings, still write the file: the heading, and a short statement
272
- that the scan found no pre-existing test disagreeing with the as-built code —
273
- keep it to a few lines, invent nothing, and add no empty sections.
274
- Do NOT propose edits to production code or to any test in this file.
275
- outputs:
276
- - { name: drift_report_file, from: "$.files" }
277
-
278
- # The question fires ONLY when the scan found true duplicates, and it shows them, so the
279
- # policy is chosen against evidence rather than blind. Option order is load-bearing:
280
- # act_ask takes options[0] under --non-interactive, so the ADDITIVE, non-destructive
281
- # choice MUST be first — a headless/CI run must never silently delete a hand-written test.
282
- # Pin it deterministically in CI with: --answer dedup_policy="<exact option text>".
283
- - id: ask_dedup
284
- condition: "{{dup_count}} != 0"
285
- action: ask
286
- answer_key: dedup_policy
287
- prompt: |
288
- EXISTING TESTS OVERLAP THIS SLICE'S GOLDEN-MASTERS.
289
- {{dup_count}} existing test(s) already pin the same behaviour at the same seam
290
- AND agree with the current code:
291
- {{duplicates}}
292
- How should characterize handle them?
293
- - Keep both = additive and safest. The golden-master is written anyway. The
294
- existing test keeps its INTENT claim; the golden-master adds the
295
- as-is claim at the outer seam. Costs some redundancy.
296
- - Keep existing = skip the golden-master; the existing test IS the fence for that
297
- behaviour. Leanest suite, but the fence then depends on a test
298
- written against intent, and char_files will not list that
299
- behaviour — coverage moves off the recorded fence.
300
- - Override = replace the duplicated existing test with the golden-master.
301
- DESTRUCTIVE: a hand-written test can encode knowledge (why a
302
- boundary is what it is) that is not recoverable from the code.
303
- Only the named duplicates are touched; recover via git.
304
- options:
305
- - "Keep both (add the golden-master alongside the existing test)"
306
- - "Keep existing (skip the golden-master; the existing test is the fence)"
307
- - "Override (replace the existing test with the golden-master)"
308
- answer_var: dedup_policy
309
-
310
- # 4. GENERATE the characterization / golden-master tests from the OBSERVED
311
- # behaviour of the legacy code. The adopted artifacts frame the surface;
312
- # the CODE is the source of truth (the agent reads it).
313
- - id: ctx_characterize
314
- action: build_context
315
- context:
316
- - { path: "{{source_map}}" } # owned source files + seam + AS-BUILT QUIRKS
317
- - { path: "{{spec_file}}" } # the observable surface (US / FR / endpoints)
318
- - { path: "{{design_file}}" } # structure (handlers, events, ports)
319
- - { path: .aw-spec/memory/constitution.technical.md, optional: true } # stack + test framework
320
- - id: generate
321
- action: agent_generate
322
- tools: "Read,Write,Edit"
323
- permission_mode: acceptEdits
324
- task: |
325
- Generate CHARACTERIZATION / golden-master tests for this adopted slice that
326
- pin what the legacy code CURRENTLY DOES — the regression fence. READ the
327
- slice's PRODUCTION code (the files listed in source-map.md, in context) and
328
- OBSERVE its actual behaviour; the spec.md + design.md (in context) frame the
329
- observable surface. Guidance: {{USER_INPUT}}
330
- Rules:
331
- - ASSERT OBSERVED BEHAVIOUR, AS-IS. Capture what the code returns/emits/persists
332
- for representative inputs RIGHT NOW — bugs and quirks INCLUDED. Do NOT assert
333
- ideal/intended behaviour, and do NOT "correct" anything. Every "as-built quirk"
334
- recorded in source-map.md MUST get a test that pins that quirk explicitly (name
335
- it so a reader knows it is a captured quirk, not a desired outcome).
336
- - These are a REGRESSION FENCE, not correctness claims. Mark each test as a
337
- characterization/golden-master (class/file name + a header comment stating
338
- "captures CURRENT behaviour as-is; a change here is a reviewed CR decision").
339
- Cite the source file and the spec id (US-/FR-/BR-) it pins, and the quirk id
340
- where relevant.
341
- - COVERAGE: one test per observable behaviour — each command / query / endpoint
342
- / handler path, each domain invariant, each emitted event and resulting state.
343
- Choose representative inputs: the happy path, boundaries, and the quirk cases.
344
- Prefer the OUTERMOST observable seam (endpoint / handler response, emitted
345
- event, persisted state) over private internals, so the fence survives an
346
- internal refactor.
347
- - BIND THE STACK + test framework from the constitution + the project's EXISTING
348
- test project conventions; place files in the test tree per folder-structure and
349
- match the surrounding test style. Reuse existing fixtures/builders.
350
- - Do NOT modify any PRODUCTION code — tests only. Do NOT edit spec.md / design.md.
351
- If a behaviour is genuinely non-deterministic (time, random, external I/O),
352
- pin it via the seam the code already exposes (clock/port) or assert the stable
353
- shape; note it in the test rather than asserting a flaky value.
354
- - DEDUP — the operator chose: {{dedup_policy}}
355
- It applies ONLY to these already-identified duplicates (same behaviour, same seam,
356
- agreeing with the code). Every OTHER behaviour still gets its golden-master, and no
357
- test outside this list may be edited or deleted for any reason:
358
- {{duplicates}}
359
- • "Keep both" → write the golden-master anyway; leave the existing test
360
- untouched. In the golden-master's header comment, name the
361
- existing test it doubles, so a reader knows the redundancy is
362
- deliberate (as-is claim vs. the existing intent claim).
363
- • "Keep existing" → do NOT write a golden-master for that behaviour. Instead add a
364
- header comment IN THIS SLICE'S golden-master file recording the
365
- delegation ("FR-x fenced by <file:test-name> — no golden-master
366
- by operator decision"), so the fence stays auditable even though
367
- char_files will not list that behaviour.
368
- • "Override" → write the golden-master, then remove ONLY the specific duplicated
369
- test METHOD/case named above — never a whole file wholesale, never
370
- a neighbouring test. State in the golden-master's header which
371
- test it supersedes and why.
372
- - DRIFT — do NOT act on these. {{drift_count}} existing test(s) disagree with what the
373
- code actually does; they are intent-vs-as-built findings, not duplicates. Leave them
374
- exactly as they are (do not fix, delete, or "align" them) and pin the code's ACTUAL
375
- behaviour in your golden-master as usual. They are already reported in
376
- {{drift_report}}; resolving them is a reviewed CR decision:
377
- {{drift}}
378
- outputs:
379
- - { name: char_files, from: "$.files" }
380
-
381
- - id: verify_generated
382
- action: verify_context
383
- require_non_empty: char_files
384
- on_empty: stop
385
- on_empty_message: "No characterization tests were generated. Ensure source-map.md lists the slice's source files (from /aw-spec-orch adopt) and re-run."
386
-
387
- # 5. GREEN-RUN the fence: the golden-masters MUST pass against the CURRENT code
388
- # (a capture that fails the live code is a wrong capture). The CODE is the
389
- # ORACLE — on failure, fix the TEST to match observed behaviour, NEVER the
390
- # production code. Bounded (3×).
391
- - id: capture_loop
392
- action: loop
393
- while: "{{test_ok}} != true"
394
- max_iterations: 3
395
- steps:
396
- - id: run_tests
397
- action: execute_script
398
- on_error: continue
399
- script: { ref: actions }
400
- subcommand: test-run
401
- args: ["--feature-dir", "{{feature_dir}}"]
402
- outputs:
403
- - { name: test_ok, from: "$.ok" }
404
- - { name: test_tool, from: "$.tool" }
405
- - { name: test_log, from: "$.log_tail" }
406
- - id: green_break
407
- action: break
408
- condition: "{{test_ok}} == true"
409
- - id: ctx_fix
410
- action: build_context
411
- vars:
412
- test_log: "{{test_log}}"
413
- context:
414
- - { path: "{{source_map}}" }
415
- context_from: char_files # the generated golden-master tests
416
- - id: fix
417
- action: agent_generate
418
- tools: "Read,Write,Edit,Bash"
419
- permission_mode: acceptEdits
420
- task: |
421
- A characterization test failed. In characterize the legacy CODE is the
422
- ORACLE — its current behaviour is correct BY DEFINITION here. So make the
423
- fence green by fixing the TESTS (in context), NOT the production code:
424
- - If an assertion's EXPECTED value differs from what the code actually
425
- returns/emits/persists, correct the expected value to the OBSERVED output
426
- (read the code / run it to confirm) — that is the whole point of a
427
- golden-master.
428
- - If a generated test has a COMPILE or setup error, fix the test code.
429
- - If a test encodes an INTENDED-but-absent behaviour (the code does not do
430
- it), DELETE that test — desired behaviour belongs in a CR/spec MODIFIED
431
- item, not a golden-master of current behaviour.
432
- NEVER modify production code to make a characterization test pass — that
433
- would alter the very behaviour you are fencing.
434
- SCOPE: fix ONLY the golden-master files in context. The suite also contains the
435
- legacy project's PRE-EXISTING tests; a failure in one of those is NOT yours to
436
- fix — it is an intent-vs-as-built finding for a CR, and the ones already known
437
- are listed in {{drift_report}}. Do not edit, delete, or skip a pre-existing test
438
- to make the run green. Test log:
439
- {{test_log}}
440
- outputs:
441
- - { name: fixed_files, from: "$.files" }
442
-
443
- - id: characterize_gate
444
- action: verify_context
445
- require_true: test_ok
446
- on_false: stop
447
- on_false_message: "The characterization fence is not green after 3 attempts (last log: {{test_log}}). Either the captured behaviour still mismatches the code (fix the TEST assertions to the observed output) or the project does not build. The code is the oracle — never change production code to pass a golden-master."
448
-
449
- # 6. Post-execution hooks.
450
- - id: resolve_post_hooks
451
- action: execute_script
452
- script: { ref: actions }
453
- subcommand: resolve-hooks
454
- args: ["--phase", "after_characterize"]
455
- outputs:
456
- - { name: after_hooks, from: "$.hooks" }
457
- - id: dispatch_post_hooks
458
- action: dispatch_hooks
459
- hooks_from_variable: after_hooks
460
-
461
- outputs:
462
- feature_dir: "{{feature_dir}}"
463
- spec_file: "{{spec_file}}"
464
- source_map: "{{source_map}}"
465
- characterization_tests: "{{char_files}}"
466
- test_tool: "{{test_tool}}"
467
- # Dedup audit trail: what overlapped, how it was resolved, and what drifted. `drift` is
468
- # the CR queue — existing tests whose intent disagrees with the as-built code.
469
- existing_test_duplicates: "{{dup_count}}"
470
- dedup_policy: "{{dedup_policy}}"
471
- intent_drift_count: "{{drift_count}}"
472
- intent_drift: "{{drift}}"
473
- drift_report: "{{drift_report}}"
474
- next: "Regression fence is GREEN against the legacy code. The slice can now be changed under a net: refine/re-implement via the forward loop + CR delta (a golden-master that MUST change = a MODIFIED spec item, reviewed — never a silent drift). If intent_drift_count is non-zero, READ {{drift_report}} and open a CR per finding — those pre-existing tests assert behaviour the code does not have, and each one is either a defect in the code or an obsolete test. Next brownfield gate: /aw-spec-orch parity (legacy vs. new, per slice) before cutover."
@@ -1,181 +0,0 @@
1
- # =============================================================================
2
- # aw-spec-close-delta (orchestrator) — ARCHIVE the change + bump the version
3
- #
4
- # The last of the five CR stages, and the counterpart of finalize-delta:
5
- # finalize-delta MERGES the delta into the master docs (the change stays OPEN)
6
- # close-delta ARCHIVES the change + bumps the version (the change is CLOSED)
7
- #
8
- # specify → design → analyze-delta-design → implement-delta → build
9
- # → finalize-delta → analyze-slice → close-delta ← you are here
10
- #
11
- # WHY THE SPLIT. finalize-delta used to do both. Merging first lets analyze-slice run
12
- # against a master spec.md/design.md that ALREADY carries the change — so its fix loops
13
- # repair code against the true, current requirements with no delta-awareness needed. But
14
- # if the close travelled with the merge, a red analyze-slice would land on a change that
15
- # was already archived and version-bumped: the only remedy would be a NEW change to
16
- # repair the one just shipped. Deferring the close to here keeps the change OPEN across
17
- # analyze-slice, so a red gate is still "fix and re-run", and the version is stamped only
18
- # once the slice is green, domain-conformant and has not broken a referrer.
19
- #
20
- # This stage AUTHORS nothing and generates NO code — no model is invoked. It moves
21
- # changes/<id>/ into changes/archive/, bumps the minor version, clears active_change,
22
- # and STAMPS that version into the `**Version**:` header of spec.md + design.md — the
23
- # single irreversible act of the CR loop, deliberately isolated in a stage of its own.
24
- #
25
- # THE VERSION SPINE LIVES HERE, AND ONLY HERE. The number has three carriers — spec.md's
26
- # header, design.md's header, active_version.json — and all three move in this one step
27
- # by one deterministic mechanism. Before, design.md's header was bumped by the MODEL at
28
- # finalize-delta (a stage early, and guessing the target since the number was never
29
- # passed into the merge prompt) while spec.md's header was bumped by nobody at all,
30
- # leaving the "living truth" document permanently at v1.0. finalize-delta now writes the
31
- # Change History rows using version-read's `next_version` — the same bump() authority
32
- # this stage applies — and touches neither header.
33
- #
34
- # NOTE: nothing MECHANICALLY proves analyze-slice ran green before this point — the
35
- # stage boundary is operator-driven, as everywhere else in this pipeline. What IS
36
- # enforced is the reverse: while a change is open, `specify` refuses to open another on
37
- # the same feature (_active_version's open-guard), so a forgotten close-delta blocks the
38
- # next change rather than passing silently.
39
- #
40
- # Launch: /aw-spec-orch close-delta [strategy]
41
- # Prereq: an OPEN change whose delta was merged by finalize-delta and whose slice
42
- # passed /aw-spec-orch analyze-slice.
43
- # =============================================================================
44
-
45
- name: aw-spec-close-delta
46
- description: Close the open change — archive changes/<id>/ into changes/archive/, bump the minor version, clear active_change, and stamp that version into spec.md's and design.md's headers, then anchor the close in the OKF freshness log. The final CR stage, run after finalize-delta merged the delta and analyze-slice verified the slice. The sole owner of the version spine; invokes no model and generates no code.
47
- version: 1.1.0
48
- agent_agnostic: true
49
- dialect: aw-spec.orchestrator/v1
50
-
51
- scripts:
52
- actions:
53
- sh: .aw-spec/scripts/bash/aw-spec-actions.sh
54
- ps1: .aw-spec/scripts/powershell/aw-spec-actions.ps1
55
- xref:
56
- sh: .aw-spec/scripts/bash/aw-xref.sh
57
- ps1: .aw-spec/scripts/powershell/aw-xref.ps1
58
-
59
- # No standards seed and no domain/tech rule selection: this stage authors nothing, so it
60
- # has no prompt to govern. It is pure bookkeeping over active_version.json + changes/ +
61
- # the two version headers.
62
- standards: []
63
-
64
- vars:
65
- active_change: ""
66
- has_change: "false"
67
- version: ""
68
- stamped_docs: "" # which master headers version-stamp actually rewrote
69
- stamped_count: "0"
70
-
71
- workflow:
72
-
73
- # 1. Resolve the active feature.
74
- - id: feature_paths
75
- action: execute_script
76
- on_error: continue # never crash raw on 'no feature set' — the gate below explains it
77
- script: { ref: actions }
78
- subcommand: feature-paths
79
- outputs:
80
- - { name: feature_dir, from: "$.feature_dir" }
81
- - { name: spec_file, from: "$.spec_file" }
82
-
83
- - id: require_feature
84
- action: verify_context
85
- require_non_empty: feature_dir
86
- on_empty: stop
87
- on_empty_message: "No active feature. Run /aw-spec-orch select-feature first (pick or create the aggregate, e.g. Order), then re-run close-delta."
88
-
89
- # 2. There must be a change to close. On the BOOTSTRAP path (implement → build →
90
- # analyze-slice) there is none and this stage does not apply at all.
91
- - id: read_change
92
- action: execute_script
93
- script: { ref: actions }
94
- subcommand: version-read
95
- args: ["--feature-dir", "{{feature_dir}}"]
96
- outputs:
97
- - { name: active_change, from: "$.active_change" }
98
- - { name: has_change, from: "$.has_change" }
99
- - { name: version, from: "$.version" }
100
-
101
- - id: require_change
102
- action: verify_context
103
- require_true: has_change
104
- on_false: stop
105
- on_false_message: "No open change on this feature — nothing to close. A change is opened by /aw-spec-orch specify (or design) and merged by /aw-spec-orch finalize-delta before it can be closed here. If you have not merged yet, run /aw-spec-orch finalize-delta → analyze-slice first."
106
-
107
- # 3. Pre-execution hooks.
108
- - id: resolve_pre_hooks
109
- action: execute_script
110
- script: { ref: actions }
111
- subcommand: resolve-hooks
112
- args: ["--phase", "before_close_cr"]
113
- outputs:
114
- - { name: before_hooks, from: "$.hooks" }
115
- - id: dispatch_pre_hooks
116
- action: dispatch_hooks
117
- hooks_from_variable: before_hooks
118
-
119
- # 4. THE CLOSE. Moves changes/{{active_change}}/ to changes/archive/, bumps the minor
120
- # version in active_version.json and clears active_change. Idempotent on the
121
- # directory (an already-moved change leaves archived_dir empty) but NOT on the
122
- # version — the bump fires whenever a change was open, which the gate above
123
- # guarantees. This is the irreversible step of the CR loop.
124
- - id: archive
125
- action: execute_script
126
- script: { ref: actions }
127
- subcommand: cr-archive
128
- args: ["--feature-dir", "{{feature_dir}}", "--cr-id", "{{active_change}}"]
129
- outputs:
130
- - { name: version, from: "$.version" }
131
- - { name: previous_version, from: "$.previous" }
132
- - { name: archived_dir, from: "$.archived_dir" }
133
-
134
- # 4b. STAMP the number just computed into the two master headers, so spec.md,
135
- # design.md and active_version.json all carry it from the same instant by the
136
- # same mechanism. Previously design.md's header was bumped by the MODEL back at
137
- # finalize-delta (guessing the target — the number was never passed to it) and
138
- # spec.md's header was bumped by nobody, so it sat at v1.0 for the life of the
139
- # feature. Deterministic and idempotent; only the header value moves.
140
- - id: stamp_version
141
- action: execute_script
142
- script: { ref: actions }
143
- subcommand: version-stamp
144
- args: ["--feature-dir", "{{feature_dir}}", "--version", "{{version}}"]
145
- outputs:
146
- - { name: stamped_docs, from: "$.stamped" }
147
- - { name: stamped_count, from: "$.count" }
148
-
149
- # 5. Anchor the CLOSE in the OKF bundle's freshness journal (log.md, OKF §7).
150
- # finalize-delta logs the MERGE; this logs the SHIP — the version bump is the event
151
- # a reader of the journal is looking for. Best-effort + git-aware: a no-op when there
152
- # is no bundle or no commit, so it never writes a non-conformant block.
153
- - id: xref_log
154
- action: execute_script
155
- on_error: continue
156
- script: { ref: xref }
157
- subcommand: log
158
- args: ["--note", "CR {{active_change}} closed — archived, version {{previous_version}} -> {{version}}"]
159
- outputs:
160
- - { name: xref_log, from: "$.log" }
161
-
162
- # 6. Post-execution hooks.
163
- - id: resolve_post_hooks
164
- action: execute_script
165
- script: { ref: actions }
166
- subcommand: resolve-hooks
167
- args: ["--phase", "after_close_cr"]
168
- outputs:
169
- - { name: after_hooks, from: "$.hooks" }
170
- - id: dispatch_post_hooks
171
- action: dispatch_hooks
172
- hooks_from_variable: after_hooks
173
-
174
- outputs:
175
- feature_dir: "{{feature_dir}}"
176
- cr_id: "{{active_change}}"
177
- version: "{{version}}"
178
- previous_version: "{{previous_version}}"
179
- archived_dir: "{{archived_dir}}"
180
- stamped_docs: "{{stamped_docs}}"
181
- next: "Change {{active_change}} CLOSED — archived to {{archived_dir}}, version {{previous_version}} -> {{version}}, stamped into {{stamped_count}} master header(s) ({{stamped_docs}}). spec.md, design.md and active_version.json now all read {{version}}; the masters describe the shipped state and the feature is free to take a new change. Next: /aw-spec-orch run → deploy, or start the next change with /aw-spec-orch specify."