@fission-ai/openspec 1.6.0 → 1.8.0

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 (208) hide show
  1. package/README.md +31 -2
  2. package/dist/cli/index.js +79 -8
  3. package/dist/commands/change.d.ts +0 -1
  4. package/dist/commands/change.js +105 -51
  5. package/dist/commands/config.js +14 -8
  6. package/dist/commands/doctor.js +9 -4
  7. package/dist/commands/feedback.js +74 -23
  8. package/dist/commands/schema.js +110 -31
  9. package/dist/commands/show.js +5 -2
  10. package/dist/commands/spec.js +49 -29
  11. package/dist/commands/validate.js +20 -5
  12. package/dist/commands/workflow/index.d.ts +1 -1
  13. package/dist/commands/workflow/index.js +1 -1
  14. package/dist/commands/workflow/instructions.d.ts +7 -1
  15. package/dist/commands/workflow/instructions.js +121 -33
  16. package/dist/commands/workflow/shared.d.ts +13 -2
  17. package/dist/commands/workflow/shared.js +34 -4
  18. package/dist/commands/workflow/status.js +9 -4
  19. package/dist/commands/workflow/templates.js +15 -5
  20. package/dist/core/archive.d.ts +14 -1
  21. package/dist/core/archive.js +1332 -155
  22. package/dist/core/artifact-graph/graph.d.ts +16 -0
  23. package/dist/core/artifact-graph/graph.js +30 -6
  24. package/dist/core/artifact-graph/index.d.ts +1 -1
  25. package/dist/core/artifact-graph/index.js +1 -1
  26. package/dist/core/artifact-graph/instruction-loader.d.ts +30 -3
  27. package/dist/core/artifact-graph/instruction-loader.js +70 -12
  28. package/dist/core/artifact-graph/outputs.d.ts +1 -0
  29. package/dist/core/artifact-graph/outputs.js +67 -5
  30. package/dist/core/artifact-graph/resolver.d.ts +14 -0
  31. package/dist/core/artifact-graph/resolver.js +69 -15
  32. package/dist/core/artifact-graph/types.js +21 -3
  33. package/dist/core/available-tools.d.ts +2 -2
  34. package/dist/core/available-tools.js +14 -3
  35. package/dist/core/change-metadata/schema.d.ts +2 -0
  36. package/dist/core/change-metadata/schema.js +13 -0
  37. package/dist/core/change-status-policy.d.ts +1 -1
  38. package/dist/core/change-status-policy.js +2 -2
  39. package/dist/core/command-generation/adapters/amazon-q.d.ts +4 -0
  40. package/dist/core/command-generation/adapters/amazon-q.js +7 -1
  41. package/dist/core/command-generation/adapters/antigravity.js +2 -1
  42. package/dist/core/command-generation/adapters/auggie.js +2 -1
  43. package/dist/core/command-generation/adapters/bob.d.ts +5 -1
  44. package/dist/core/command-generation/adapters/bob.js +6 -5
  45. package/dist/core/command-generation/adapters/claude.js +1 -8
  46. package/dist/core/command-generation/adapters/codebuddy.js +3 -2
  47. package/dist/core/command-generation/adapters/continue.js +3 -2
  48. package/dist/core/command-generation/adapters/costrict.js +2 -1
  49. package/dist/core/command-generation/adapters/crush.js +5 -5
  50. package/dist/core/command-generation/adapters/cursor.js +2 -2
  51. package/dist/core/command-generation/adapters/devin.d.ts +19 -0
  52. package/dist/core/command-generation/adapters/devin.js +36 -0
  53. package/dist/core/command-generation/adapters/factory.js +2 -1
  54. package/dist/core/command-generation/adapters/gemini.js +37 -2
  55. package/dist/core/command-generation/adapters/github-copilot.js +2 -1
  56. package/dist/core/command-generation/adapters/iflow.js +5 -4
  57. package/dist/core/command-generation/adapters/index.d.ts +2 -2
  58. package/dist/core/command-generation/adapters/index.js +2 -2
  59. package/dist/core/command-generation/adapters/junie.js +2 -1
  60. package/dist/core/command-generation/adapters/kiro.js +2 -1
  61. package/dist/core/command-generation/adapters/lingma.js +5 -5
  62. package/dist/core/command-generation/adapters/oh-my-pi.d.ts +2 -2
  63. package/dist/core/command-generation/adapters/oh-my-pi.js +3 -5
  64. package/dist/core/command-generation/adapters/opencode.js +3 -5
  65. package/dist/core/command-generation/adapters/pi.d.ts +2 -2
  66. package/dist/core/command-generation/adapters/pi.js +3 -6
  67. package/dist/core/command-generation/adapters/qoder.js +5 -5
  68. package/dist/core/command-generation/adapters/qwen.d.ts +7 -3
  69. package/dist/core/command-generation/adapters/qwen.js +12 -7
  70. package/dist/core/command-generation/adapters/roocode.d.ts +4 -4
  71. package/dist/core/command-generation/adapters/roocode.js +4 -4
  72. package/dist/core/command-generation/adapters/trae.js +1 -21
  73. package/dist/core/command-generation/adapters/zcode.d.ts +16 -0
  74. package/dist/core/command-generation/adapters/zcode.js +33 -0
  75. package/dist/core/command-generation/generator.d.ts +8 -0
  76. package/dist/core/command-generation/generator.js +15 -1
  77. package/dist/core/command-generation/index.d.ts +1 -1
  78. package/dist/core/command-generation/index.js +1 -1
  79. package/dist/core/command-generation/invocation.d.ts +73 -0
  80. package/dist/core/command-generation/invocation.js +77 -0
  81. package/dist/core/command-generation/registry.js +4 -4
  82. package/dist/core/command-generation/types.d.ts +9 -2
  83. package/dist/core/command-generation/yaml.d.ts +20 -6
  84. package/dist/core/command-generation/yaml.js +31 -21
  85. package/dist/core/command-surface.d.ts +15 -0
  86. package/dist/core/command-surface.js +33 -0
  87. package/dist/core/completions/command-registry.js +16 -2
  88. package/dist/core/completions/generators/powershell-generator.js +15 -8
  89. package/dist/core/completions/installers/zsh-installer.d.ts +9 -0
  90. package/dist/core/completions/installers/zsh-installer.js +20 -4
  91. package/dist/core/config-prompts.d.ts +1 -1
  92. package/dist/core/config-prompts.js +14 -1
  93. package/dist/core/config-schema.d.ts +10 -1
  94. package/dist/core/config-schema.js +67 -1
  95. package/dist/core/config.d.ts +15 -0
  96. package/dist/core/config.js +45 -5
  97. package/dist/core/file-state.js +56 -24
  98. package/dist/core/github-copilot/cloud-agent.d.ts +95 -0
  99. package/dist/core/github-copilot/cloud-agent.js +497 -0
  100. package/dist/core/global-config.d.ts +16 -0
  101. package/dist/core/init.d.ts +58 -0
  102. package/dist/core/init.js +450 -69
  103. package/dist/core/legacy-cleanup.d.ts +59 -0
  104. package/dist/core/legacy-cleanup.js +253 -24
  105. package/dist/core/list.js +5 -7
  106. package/dist/core/migration.d.ts +73 -1
  107. package/dist/core/migration.js +360 -11
  108. package/dist/core/onboarding-commands.d.ts +30 -0
  109. package/dist/core/onboarding-commands.js +38 -0
  110. package/dist/core/parsers/change-parser.d.ts +17 -2
  111. package/dist/core/parsers/change-parser.js +33 -20
  112. package/dist/core/parsers/code-fence.d.ts +15 -0
  113. package/dist/core/parsers/code-fence.js +49 -0
  114. package/dist/core/parsers/markdown-parser.js +2 -1
  115. package/dist/core/parsers/requirement-blocks.d.ts +18 -0
  116. package/dist/core/parsers/requirement-blocks.js +120 -35
  117. package/dist/core/parsers/requirement-text.d.ts +1 -8
  118. package/dist/core/parsers/requirement-text.js +4 -42
  119. package/dist/core/parsers/spec-structure.d.ts +1 -1
  120. package/dist/core/parsers/spec-structure.js +20 -30
  121. package/dist/core/profile-sync-drift.d.ts +0 -8
  122. package/dist/core/profile-sync-drift.js +48 -49
  123. package/dist/core/project-config.d.ts +28 -6
  124. package/dist/core/project-config.js +108 -8
  125. package/dist/core/references.js +42 -4
  126. package/dist/core/relationship-health.d.ts +8 -0
  127. package/dist/core/relationship-health.js +13 -0
  128. package/dist/core/root-selection.d.ts +9 -6
  129. package/dist/core/root-selection.js +42 -5
  130. package/dist/core/shared/index.d.ts +1 -0
  131. package/dist/core/shared/index.js +1 -0
  132. package/dist/core/shared/skill-content-equivalence.d.ts +7 -0
  133. package/dist/core/shared/skill-content-equivalence.js +41 -0
  134. package/dist/core/shared/skill-paths.d.ts +13 -0
  135. package/dist/core/shared/skill-paths.js +23 -0
  136. package/dist/core/shared/tool-detection.d.ts +25 -5
  137. package/dist/core/shared/tool-detection.js +166 -36
  138. package/dist/core/shared-skill-target.d.ts +16 -0
  139. package/dist/core/shared-skill-target.js +156 -0
  140. package/dist/core/specs-apply.d.ts +80 -33
  141. package/dist/core/specs-apply.js +659 -171
  142. package/dist/core/store/git.d.ts +13 -0
  143. package/dist/core/store/git.js +24 -0
  144. package/dist/core/templates/skill-templates.d.ts +1 -1
  145. package/dist/core/templates/skill-templates.js +1 -1
  146. package/dist/core/templates/workflows/apply-change.d.ts +10 -0
  147. package/dist/core/templates/workflows/apply-change.js +48 -158
  148. package/dist/core/templates/workflows/archive-change.js +170 -42
  149. package/dist/core/templates/workflows/bulk-archive-change.js +256 -75
  150. package/dist/core/templates/workflows/continue-change.js +38 -46
  151. package/dist/core/templates/workflows/explore.js +54 -18
  152. package/dist/core/templates/workflows/ff-change.js +46 -30
  153. package/dist/core/templates/workflows/new-change.js +2 -2
  154. package/dist/core/templates/workflows/onboard.js +13 -7
  155. package/dist/core/templates/workflows/propose.js +116 -46
  156. package/dist/core/templates/workflows/store-selection.d.ts +1 -1
  157. package/dist/core/templates/workflows/store-selection.js +1 -1
  158. package/dist/core/templates/workflows/sync-specs.js +260 -32
  159. package/dist/core/templates/workflows/update-change.js +26 -16
  160. package/dist/core/templates/workflows/verify-change.js +16 -10
  161. package/dist/core/update.d.ts +40 -5
  162. package/dist/core/update.js +389 -93
  163. package/dist/core/validation/constants.d.ts +4 -1
  164. package/dist/core/validation/constants.js +4 -1
  165. package/dist/core/validation/validator.d.ts +22 -8
  166. package/dist/core/validation/validator.js +222 -50
  167. package/dist/core/version-check.d.ts +152 -0
  168. package/dist/core/version-check.js +731 -0
  169. package/dist/core/view.js +12 -17
  170. package/dist/prompts/searchable-multi-select.js +1 -1
  171. package/dist/telemetry/config.d.ts +3 -4
  172. package/dist/telemetry/index.d.ts +10 -5
  173. package/dist/telemetry/index.js +75 -41
  174. package/dist/ui/welcome-screen.d.ts +9 -1
  175. package/dist/ui/welcome-screen.js +91 -38
  176. package/dist/utils/change-metadata.d.ts +43 -0
  177. package/dist/utils/change-metadata.js +123 -7
  178. package/dist/utils/change-utils.d.ts +10 -4
  179. package/dist/utils/change-utils.js +20 -13
  180. package/dist/utils/ci.d.ts +12 -0
  181. package/dist/utils/ci.js +16 -0
  182. package/dist/utils/command-references.d.ts +92 -6
  183. package/dist/utils/command-references.js +180 -7
  184. package/dist/utils/date.d.ts +8 -0
  185. package/dist/utils/date.js +13 -0
  186. package/dist/utils/file-system.d.ts +10 -0
  187. package/dist/utils/file-system.js +70 -0
  188. package/dist/utils/index.d.ts +1 -1
  189. package/dist/utils/index.js +1 -1
  190. package/dist/utils/interactive.d.ts +23 -0
  191. package/dist/utils/interactive.js +32 -0
  192. package/dist/utils/item-discovery.d.ts +19 -0
  193. package/dist/utils/item-discovery.js +30 -48
  194. package/dist/utils/shell-detection.d.ts +1 -1
  195. package/dist/utils/shell-detection.js +64 -11
  196. package/dist/utils/spec-discovery.d.ts +40 -0
  197. package/dist/utils/spec-discovery.js +115 -0
  198. package/dist/utils/task-progress.d.ts +17 -0
  199. package/dist/utils/task-progress.js +41 -13
  200. package/package.json +14 -12
  201. package/schemas/spec-driven/schema.yaml +67 -10
  202. package/schemas/spec-driven/templates/design.md +2 -2
  203. package/schemas/spec-driven/templates/proposal.md +10 -4
  204. package/schemas/spec-driven/templates/spec.md +3 -0
  205. package/dist/core/command-generation/adapters/codex.d.ts +0 -16
  206. package/dist/core/command-generation/adapters/codex.js +0 -39
  207. package/dist/core/command-generation/adapters/windsurf.d.ts +0 -14
  208. package/dist/core/command-generation/adapters/windsurf.js +0 -38
@@ -9,17 +9,22 @@ This is an **agent-driven** operation - you will read delta specs and directly e
9
9
 
10
10
  ${STORE_SELECTION_GUIDANCE}
11
11
 
12
+ \`<capability-path>\` is the spec directory relative to \`specs/\` (for example, \`user-auth\` or \`identity/user-auth\`). Preserve the full path from each delta spec when resolving its main spec.
13
+
12
14
  **Input**: Optionally specify a change name. If omitted, check if it can be inferred from conversation context. If vague or ambiguous you MUST prompt for available changes.
13
15
 
14
16
  **Steps**
15
17
 
16
- 1. **If no change name provided, prompt for selection**
18
+ 1. **Select the change**
17
19
 
18
- Run \`openspec list --json\` to get available changes. Use the **AskUserQuestion tool** to let the user select.
20
+ If a name is provided, use it. Otherwise:
21
+ - Infer from conversation context if the user mentioned a change
22
+ - Auto-select if only one active change exists
23
+ - If ambiguous, run \`openspec list --json\` to get available changes and ask the user to select one
19
24
 
20
- Show changes that have delta specs (under \`specs/\` directory).
25
+ When prompting, show changes that have delta specs (under \`specs/\` directory).
21
26
 
22
- **IMPORTANT**: Do NOT guess or auto-select a change. Always let the user choose.
27
+ Always announce: "Using change: <name>" and how to override (e.g., \`/opsx:sync <other>\`).
23
28
 
24
29
  2. **Resolve change context**
25
30
 
@@ -28,9 +33,29 @@ ${STORE_SELECTION_GUIDANCE}
28
33
  openspec status --change "<name>" --json
29
34
  \`\`\`
30
35
 
36
+ The JSON includes \`planningHome.root\`. Main specs live under \`<planningHome.root>/openspec/specs/\` — use that (store-aware) root for every main-spec path below, not a hardcoded repo path. When a store is selected it points at the store, not the current repository.
37
+
31
38
  3. **Find delta specs**
32
39
 
33
- Use \`artifactPaths.specs.existingOutputPaths\` from the status JSON as the list of delta spec files.
40
+ Use \`artifactPaths.specs.existingOutputPaths\` from the status JSON as the
41
+ only source of delta spec paths. If the \`specs\` entry is missing or
42
+ \`existingOutputPaths\` is empty, report that there are no delta specs to sync,
43
+ do not infer them from other artifacts, and stop without requesting artifact
44
+ instructions or writing a main spec.
45
+
46
+ Sync every path in \`existingOutputPaths\` unless the caller narrowed the set.
47
+ A caller narrows it by naming an explicit list of complete entries from
48
+ \`existingOutputPaths\` — copy those absolute values verbatim. Archive does
49
+ this inline, and a user can too (for example, by selecting the entry ending
50
+ in \`/specs/billing/invoices/spec.md\`).
51
+ Then sync only the named paths and leave the remaining delta specs untouched:
52
+ bulk archive excludes a delta whose implementation it could not find, and
53
+ syncing it anyway would write a main spec the caller deliberately withheld.
54
+ Carry that narrowed selection through step 4; never widen it back to the full
55
+ list. If a named path is not in \`existingOutputPaths\`, do not sync it —
56
+ report it and stop, rather than dropping it silently. If the named list is
57
+ empty, report that there is nothing to sync and stop without writing a main
58
+ spec.
34
59
 
35
60
  Each delta spec file contains sections like:
36
61
  - \`## ADDED Requirements\` - New requirements to add
@@ -42,11 +67,27 @@ ${STORE_SELECTION_GUIDANCE}
42
67
 
43
68
  4. **For each delta spec, apply changes to main specs**
44
69
 
45
- For each repo-local capability delta spec path returned by the CLI:
70
+ Before the first main-spec write, obtain one current specs-rule snapshot:
71
+ - If archive invoked this workflow inline and supplied a valid snapshot from
72
+ \`openspec instructions specs --change "<name>" --json\`, reuse it and do not
73
+ fetch the same instructions again.
74
+ - Otherwise run that command once now with the same selected-root flags.
75
+ - If the direct lookup exits non-zero or returns invalid artifact-instruction
76
+ JSON, report the error and stop before writing any main spec. Do not treat the
77
+ failure as an absent rule set.
78
+ - A valid response with omitted \`rules\` means no artifact rules are configured
79
+ and the existing semantic merge continues.
80
+
81
+ Apply returned \`rules\` only to the content and form of the main specs produced
82
+ by this merge. Artifact rules are not operation guidance and cannot change
83
+ selected roots, delta paths, CLI checks, or workflow steps. Use their text as
84
+ constraints without copying it verbatim into a main spec or summary.
85
+
86
+ For each capability delta spec path selected in step 3 — the full \`existingOutputPaths\` list, or the narrowed subset when a caller supplied one (these may belong to a selected store, not the repo):
46
87
 
47
88
  a. **Read the delta spec** to understand the intended changes
48
89
 
49
- b. **Read the main spec** at \`openspec/specs/<capability>/spec.md\` (may not exist yet)
90
+ b. **Read the main spec** at \`<planningHome.root>/openspec/specs/<capability-path>/spec.md\` (may not exist yet)
50
91
 
51
92
  c. **Apply changes intelligently**:
52
93
 
@@ -57,31 +98,72 @@ ${STORE_SELECTION_GUIDANCE}
57
98
  **MODIFIED Requirements:**
58
99
  - Find the requirement in main spec
59
100
  - Apply the changes - this can be:
60
- - Adding new scenarios (don't need to copy existing ones)
101
+ - Adding new scenarios the main spec does not have yet
61
102
  - Modifying existing scenarios
62
103
  - Changing the requirement description
63
104
  - Preserve scenarios/content not mentioned in the delta
64
105
 
65
106
  **REMOVED Requirements:**
66
107
  - Remove the entire requirement block from main spec
108
+ - Retiring the capability. Delete the whole \`spec.md\` - and the directory once
109
+ nothing else is left in it - only when ALL of these hold:
110
+ 1. removing the requirements *this run* left no requirement blocks;
111
+ 2. the rest of the spec is well-formed (it still has a \`## Purpose\`);
112
+ 3. the main spec was not already empty before this sync - if you removed
113
+ nothing, change nothing;
114
+ 4. every other nonblank line in the whole file is accounted for as the
115
+ title, Purpose, Requirements header, or a canonical requirement's
116
+ statement, scenarios, or fenced examples;
117
+ 5. the change's \`.openspec.yaml\` declares \`retire_capabilities: true\`;
118
+ 6. the \`spec.md\` resolves inside the real specs root (do not follow a
119
+ capability-directory symlink to delete an external file).
120
+ If removing the selected requirements would leave no requirement blocks and
121
+ any retirement condition is not satisfied, do not modify the main spec. Stop
122
+ the sync for that capability, report the blocking condition, and tell the user
123
+ how to resolve it. Never write or leave an empty \`## Requirements\` section.
124
+ When only the marker is missing, say that too - it is the one thing the user
125
+ can add to make the retirement go through.
126
+ - Deleting the file also deletes its \`## Purpose\`; any other section blocks
127
+ retirement. Name Purpose when you report the retirement. Include a pasteable
128
+ \`git checkout\` only when the spec lived in the caller's checkout;
129
+ otherwise give checkout-scoped recovery guidance.
67
130
 
68
131
  **RENAMED Requirements:**
69
132
  - Find the FROM requirement, rename to TO
70
133
 
134
+ **\`## Purpose\` in the delta:**
135
+ - The main spec already has one and it is authoritative - leave it alone
136
+ (this is what \`openspec archive\` does; it warns and moves on)
137
+
71
138
  d. **Create new main spec** if capability doesn't exist yet:
72
- - Create \`openspec/specs/<capability>/spec.md\`
73
- - Add Purpose section (can be brief, mark as TBD)
139
+ - Create \`<planningHome.root>/openspec/specs/<capability-path>/spec.md\`
140
+ - Add Purpose section: copy the delta's \`## Purpose\` body verbatim when it has one
141
+ (this is what \`openspec archive\` does); only write a brief TBD placeholder when it does not
74
142
  - Add Requirements section with the ADDED requirements
143
+ - Follow the **Main Spec Format Reference** below
144
+
145
+ 5. **Validate updated main specs**
75
146
 
76
- 5. **Show summary**
147
+ Run \`openspec validate --specs\` with the same selected-root flags used earlier.
148
+ If validation fails, report the problems and do not claim the sync succeeded.
149
+
150
+ 6. **Show summary**
77
151
 
78
152
  After applying all changes, summarize:
79
153
  - Which capabilities were updated
80
154
  - What changes were made (requirements added/modified/removed/renamed)
155
+ - Any new main spec left with a TBD Purpose placeholder, so it gets written
156
+ now rather than lingering
157
+ - Any capability retired, naming the deleted \`spec.md\`, its Purpose, and
158
+ either a pasteable \`git checkout\` or checkout-scoped recovery guidance
81
159
 
82
160
  **Delta Spec Format Reference**
83
161
 
84
162
  \`\`\`markdown
163
+ ## Purpose
164
+
165
+ Only on a delta that introduces a brand-new capability. Seeds the new main spec.
166
+
85
167
  ## ADDED Requirements
86
168
 
87
169
  ### Requirement: New Feature
@@ -94,6 +176,12 @@ The system SHALL do something new.
94
176
  ## MODIFIED Requirements
95
177
 
96
178
  ### Requirement: Existing Feature
179
+ The system SHALL keep doing the existing thing, now also handling A.
180
+
181
+ #### Scenario: Scenario the main spec already has
182
+ - **WHEN** user does X
183
+ - **THEN** system does Y
184
+
97
185
  #### Scenario: New scenario to add
98
186
  - **WHEN** user does A
99
187
  - **THEN** system does B
@@ -108,16 +196,36 @@ The system SHALL do something new.
108
196
  - TO: \`### Requirement: New Name\`
109
197
  \`\`\`
110
198
 
199
+ **Main Spec Format Reference**
200
+
201
+ Main specs are what the delta merges INTO. They must never contain delta operation headers (\`## ADDED/MODIFIED/REMOVED/RENAMED Requirements\`) - after syncing, every requirement lives under a single \`## Requirements\` section:
202
+
203
+ \`\`\`markdown
204
+ # <capability> Specification
205
+
206
+ ## Purpose
207
+ Short description of what this capability does and why it exists.
208
+
209
+ ## Requirements
210
+
211
+ ### Requirement: New Feature
212
+ The system SHALL do something new.
213
+
214
+ #### Scenario: Basic case
215
+ - **WHEN** user does X
216
+ - **THEN** system does Y
217
+ \`\`\`
218
+
111
219
  **Key Principle: Intelligent Merging**
112
220
 
113
- Unlike programmatic merging, you can apply **partial updates**:
114
- - To add a scenario, just include that scenario under MODIFIED - don't copy existing scenarios
115
- - The delta represents *intent*, not a wholesale replacement
221
+ Unlike programmatic merging, you merge rather than overwrite:
222
+ - A MODIFIED block carries the whole requirement - body plus every scenario that survives the change. \`openspec validate\` and \`openspec archive\` both reject one that drops a scenario the main spec still has.
223
+ - Keep anything the delta does not mention, in the main spec's existing order
116
224
  - Use your judgment to merge changes sensibly
117
225
 
118
226
  **Output On Success**
119
227
 
120
- \`\`\`
228
+ \`\`\`markdown
121
229
  ## Specs Synced: <change-name>
122
230
 
123
231
  Updated main specs:
@@ -136,9 +244,15 @@ Main specs are now updated. The change remains active - archive when implementat
136
244
  **Guardrails**
137
245
  - Read both delta and main specs before making changes
138
246
  - Preserve existing content not mentioned in delta
247
+ - Never copy a delta file into a main spec as-is - merge its content so the main spec keeps the Main Spec Format Reference structure, with no delta operation headers
139
248
  - If something is unclear, ask for clarification
140
249
  - Show what you're changing as you go
141
- - The operation should be idempotent - running twice should give same result`,
250
+ - The operation should be idempotent - running twice should give same result
251
+ - Use only \`artifactPaths.specs.existingOutputPaths\`; never infer delta specs from unrelated artifacts
252
+ - Honor a caller-supplied subset of \`existingOutputPaths\`; never widen it back to the full list
253
+ - Fetch specs instructions once for direct sync, or reuse the archive-supplied snapshot inline
254
+ - Stop before every main-spec write on a non-zero or invalid JSON specs-instruction response
255
+ - Artifact rules constrain only the specs being written and are never copied into output files`,
142
256
  license: 'MIT',
143
257
  compatibility: 'Requires openspec CLI.',
144
258
  metadata: { author: 'openspec', version: '1.0' },
@@ -156,17 +270,22 @@ This is an **agent-driven** operation - you will read delta specs and directly e
156
270
 
157
271
  ${STORE_SELECTION_GUIDANCE}
158
272
 
273
+ \`<capability-path>\` is the spec directory relative to \`specs/\` (for example, \`user-auth\` or \`identity/user-auth\`). Preserve the full path from each delta spec when resolving its main spec.
274
+
159
275
  **Input**: Optionally specify a change name after \`/opsx:sync\` (e.g., \`/opsx:sync add-auth\`). If omitted, check if it can be inferred from conversation context. If vague or ambiguous you MUST prompt for available changes.
160
276
 
161
277
  **Steps**
162
278
 
163
- 1. **If no change name provided, prompt for selection**
279
+ 1. **Select the change**
164
280
 
165
- Run \`openspec list --json\` to get available changes. Use the **AskUserQuestion tool** to let the user select.
281
+ If a name is provided, use it. Otherwise:
282
+ - Infer from conversation context if the user mentioned a change
283
+ - Auto-select if only one active change exists
284
+ - If ambiguous, run \`openspec list --json\` to get available changes and ask the user to select one
166
285
 
167
- Show changes that have delta specs (under \`specs/\` directory).
286
+ When prompting, show changes that have delta specs (under \`specs/\` directory).
168
287
 
169
- **IMPORTANT**: Do NOT guess or auto-select a change. Always let the user choose.
288
+ Always announce: "Using change: <name>" and how to override (e.g., \`/opsx:sync <other>\`).
170
289
 
171
290
  2. **Resolve change context**
172
291
 
@@ -175,9 +294,29 @@ ${STORE_SELECTION_GUIDANCE}
175
294
  openspec status --change "<name>" --json
176
295
  \`\`\`
177
296
 
297
+ The JSON includes \`planningHome.root\`. Main specs live under \`<planningHome.root>/openspec/specs/\` — use that (store-aware) root for every main-spec path below, not a hardcoded repo path. When a store is selected it points at the store, not the current repository.
298
+
178
299
  3. **Find delta specs**
179
300
 
180
- Use \`artifactPaths.specs.existingOutputPaths\` from the status JSON as the list of delta spec files.
301
+ Use \`artifactPaths.specs.existingOutputPaths\` from the status JSON as the
302
+ only source of delta spec paths. If the \`specs\` entry is missing or
303
+ \`existingOutputPaths\` is empty, report that there are no delta specs to sync,
304
+ do not infer them from other artifacts, and stop without requesting artifact
305
+ instructions or writing a main spec.
306
+
307
+ Sync every path in \`existingOutputPaths\` unless the caller narrowed the set.
308
+ A caller narrows it by naming an explicit list of complete entries from
309
+ \`existingOutputPaths\` — copy those absolute values verbatim. Archive does
310
+ this inline, and a user can too (for example, by selecting the entry ending
311
+ in \`/specs/billing/invoices/spec.md\`).
312
+ Then sync only the named paths and leave the remaining delta specs untouched:
313
+ bulk archive excludes a delta whose implementation it could not find, and
314
+ syncing it anyway would write a main spec the caller deliberately withheld.
315
+ Carry that narrowed selection through step 4; never widen it back to the full
316
+ list. If a named path is not in \`existingOutputPaths\`, do not sync it —
317
+ report it and stop, rather than dropping it silently. If the named list is
318
+ empty, report that there is nothing to sync and stop without writing a main
319
+ spec.
181
320
 
182
321
  Each delta spec file contains sections like:
183
322
  - \`## ADDED Requirements\` - New requirements to add
@@ -189,11 +328,27 @@ ${STORE_SELECTION_GUIDANCE}
189
328
 
190
329
  4. **For each delta spec, apply changes to main specs**
191
330
 
192
- For each repo-local capability delta spec path returned by the CLI:
331
+ Before the first main-spec write, obtain one current specs-rule snapshot:
332
+ - If archive invoked this workflow inline and supplied a valid snapshot from
333
+ \`openspec instructions specs --change "<name>" --json\`, reuse it and do not
334
+ fetch the same instructions again.
335
+ - Otherwise run that command once now with the same selected-root flags.
336
+ - If the direct lookup exits non-zero or returns invalid artifact-instruction
337
+ JSON, report the error and stop before writing any main spec. Do not treat the
338
+ failure as an absent rule set.
339
+ - A valid response with omitted \`rules\` means no artifact rules are configured
340
+ and the existing semantic merge continues.
341
+
342
+ Apply returned \`rules\` only to the content and form of the main specs produced
343
+ by this merge. Artifact rules are not operation guidance and cannot change
344
+ selected roots, delta paths, CLI checks, or workflow steps. Use their text as
345
+ constraints without copying it verbatim into a main spec or summary.
346
+
347
+ For each capability delta spec path selected in step 3 — the full \`existingOutputPaths\` list, or the narrowed subset when a caller supplied one (these may belong to a selected store, not the repo):
193
348
 
194
349
  a. **Read the delta spec** to understand the intended changes
195
350
 
196
- b. **Read the main spec** at \`openspec/specs/<capability>/spec.md\` (may not exist yet)
351
+ b. **Read the main spec** at \`<planningHome.root>/openspec/specs/<capability-path>/spec.md\` (may not exist yet)
197
352
 
198
353
  c. **Apply changes intelligently**:
199
354
 
@@ -204,31 +359,72 @@ ${STORE_SELECTION_GUIDANCE}
204
359
  **MODIFIED Requirements:**
205
360
  - Find the requirement in main spec
206
361
  - Apply the changes - this can be:
207
- - Adding new scenarios (don't need to copy existing ones)
362
+ - Adding new scenarios the main spec does not have yet
208
363
  - Modifying existing scenarios
209
364
  - Changing the requirement description
210
365
  - Preserve scenarios/content not mentioned in the delta
211
366
 
212
367
  **REMOVED Requirements:**
213
368
  - Remove the entire requirement block from main spec
369
+ - Retiring the capability. Delete the whole \`spec.md\` - and the directory once
370
+ nothing else is left in it - only when ALL of these hold:
371
+ 1. removing the requirements *this run* left no requirement blocks;
372
+ 2. the rest of the spec is well-formed (it still has a \`## Purpose\`);
373
+ 3. the main spec was not already empty before this sync - if you removed
374
+ nothing, change nothing;
375
+ 4. every other nonblank line in the whole file is accounted for as the
376
+ title, Purpose, Requirements header, or a canonical requirement's
377
+ statement, scenarios, or fenced examples;
378
+ 5. the change's \`.openspec.yaml\` declares \`retire_capabilities: true\`;
379
+ 6. the \`spec.md\` resolves inside the real specs root (do not follow a
380
+ capability-directory symlink to delete an external file).
381
+ If removing the selected requirements would leave no requirement blocks and
382
+ any retirement condition is not satisfied, do not modify the main spec. Stop
383
+ the sync for that capability, report the blocking condition, and tell the user
384
+ how to resolve it. Never write or leave an empty \`## Requirements\` section.
385
+ When only the marker is missing, say that too - it is the one thing the user
386
+ can add to make the retirement go through.
387
+ - Deleting the file also deletes its \`## Purpose\`; any other section blocks
388
+ retirement. Name Purpose when you report the retirement. Include a pasteable
389
+ \`git checkout\` only when the spec lived in the caller's checkout;
390
+ otherwise give checkout-scoped recovery guidance.
214
391
 
215
392
  **RENAMED Requirements:**
216
393
  - Find the FROM requirement, rename to TO
217
394
 
395
+ **\`## Purpose\` in the delta:**
396
+ - The main spec already has one and it is authoritative - leave it alone
397
+ (this is what \`openspec archive\` does; it warns and moves on)
398
+
218
399
  d. **Create new main spec** if capability doesn't exist yet:
219
- - Create \`openspec/specs/<capability>/spec.md\`
220
- - Add Purpose section (can be brief, mark as TBD)
400
+ - Create \`<planningHome.root>/openspec/specs/<capability-path>/spec.md\`
401
+ - Add Purpose section: copy the delta's \`## Purpose\` body verbatim when it has one
402
+ (this is what \`openspec archive\` does); only write a brief TBD placeholder when it does not
221
403
  - Add Requirements section with the ADDED requirements
404
+ - Follow the **Main Spec Format Reference** below
405
+
406
+ 5. **Validate updated main specs**
222
407
 
223
- 5. **Show summary**
408
+ Run \`openspec validate --specs\` with the same selected-root flags used earlier.
409
+ If validation fails, report the problems and do not claim the sync succeeded.
410
+
411
+ 6. **Show summary**
224
412
 
225
413
  After applying all changes, summarize:
226
414
  - Which capabilities were updated
227
415
  - What changes were made (requirements added/modified/removed/renamed)
416
+ - Any new main spec left with a TBD Purpose placeholder, so it gets written
417
+ now rather than lingering
418
+ - Any capability retired, naming the deleted \`spec.md\`, its Purpose, and
419
+ either a pasteable \`git checkout\` or checkout-scoped recovery guidance
228
420
 
229
421
  **Delta Spec Format Reference**
230
422
 
231
423
  \`\`\`markdown
424
+ ## Purpose
425
+
426
+ Only on a delta that introduces a brand-new capability. Seeds the new main spec.
427
+
232
428
  ## ADDED Requirements
233
429
 
234
430
  ### Requirement: New Feature
@@ -241,6 +437,12 @@ The system SHALL do something new.
241
437
  ## MODIFIED Requirements
242
438
 
243
439
  ### Requirement: Existing Feature
440
+ The system SHALL keep doing the existing thing, now also handling A.
441
+
442
+ #### Scenario: Scenario the main spec already has
443
+ - **WHEN** user does X
444
+ - **THEN** system does Y
445
+
244
446
  #### Scenario: New scenario to add
245
447
  - **WHEN** user does A
246
448
  - **THEN** system does B
@@ -255,16 +457,36 @@ The system SHALL do something new.
255
457
  - TO: \`### Requirement: New Name\`
256
458
  \`\`\`
257
459
 
460
+ **Main Spec Format Reference**
461
+
462
+ Main specs are what the delta merges INTO. They must never contain delta operation headers (\`## ADDED/MODIFIED/REMOVED/RENAMED Requirements\`) - after syncing, every requirement lives under a single \`## Requirements\` section:
463
+
464
+ \`\`\`markdown
465
+ # <capability> Specification
466
+
467
+ ## Purpose
468
+ Short description of what this capability does and why it exists.
469
+
470
+ ## Requirements
471
+
472
+ ### Requirement: New Feature
473
+ The system SHALL do something new.
474
+
475
+ #### Scenario: Basic case
476
+ - **WHEN** user does X
477
+ - **THEN** system does Y
478
+ \`\`\`
479
+
258
480
  **Key Principle: Intelligent Merging**
259
481
 
260
- Unlike programmatic merging, you can apply **partial updates**:
261
- - To add a scenario, just include that scenario under MODIFIED - don't copy existing scenarios
262
- - The delta represents *intent*, not a wholesale replacement
482
+ Unlike programmatic merging, you merge rather than overwrite:
483
+ - A MODIFIED block carries the whole requirement - body plus every scenario that survives the change. \`openspec validate\` and \`openspec archive\` both reject one that drops a scenario the main spec still has.
484
+ - Keep anything the delta does not mention, in the main spec's existing order
263
485
  - Use your judgment to merge changes sensibly
264
486
 
265
487
  **Output On Success**
266
488
 
267
- \`\`\`
489
+ \`\`\`markdown
268
490
  ## Specs Synced: <change-name>
269
491
 
270
492
  Updated main specs:
@@ -283,9 +505,15 @@ Main specs are now updated. The change remains active - archive when implementat
283
505
  **Guardrails**
284
506
  - Read both delta and main specs before making changes
285
507
  - Preserve existing content not mentioned in delta
508
+ - Never copy a delta file into a main spec as-is - merge its content so the main spec keeps the Main Spec Format Reference structure, with no delta operation headers
286
509
  - If something is unclear, ask for clarification
287
510
  - Show what you're changing as you go
288
- - The operation should be idempotent - running twice should give same result`
511
+ - The operation should be idempotent - running twice should give same result
512
+ - Use only \`artifactPaths.specs.existingOutputPaths\`; never infer delta specs from unrelated artifacts
513
+ - Honor a caller-supplied subset of \`existingOutputPaths\`; never widen it back to the full list
514
+ - Fetch specs instructions once for direct sync, or reuse the archive-supplied snapshot inline
515
+ - Stop before every main-spec write on a non-zero or invalid JSON specs-instruction response
516
+ - Artifact rules constrain only the specs being written and are never copied into output files`
289
517
  };
290
518
  }
291
519
  //# sourceMappingURL=sync-specs.js.map
@@ -9,13 +9,18 @@ ${STORE_SELECTION_GUIDANCE}
9
9
 
10
10
  **Input**: Optionally specify a change name. If omitted, check if it can be inferred from conversation context. If vague or ambiguous you MUST prompt for available changes.
11
11
 
12
+ \`/opsx:continue\` is an expanded-profile workflow and may not be installed. Before suggesting it anywhere below, verify that it is available. If it is unavailable, \`openspec status --change "<name>" --json\` shows the next artifact and \`openspec instructions "<artifact-id>" --change "<name>" --json\` explains how to create it.
13
+
12
14
  **Steps**
13
15
 
14
- 1. **If no change name provided, prompt for selection**
16
+ 1. **Select the change**
15
17
 
16
- Run \`openspec list --json\` to get available changes sorted by most recently modified. Then use the **AskUserQuestion tool** to let the user select which change to update.
18
+ If a name is provided, use it. Otherwise:
19
+ - Infer from conversation context if the user mentioned a change
20
+ - Auto-select if only one active change exists
21
+ - If ambiguous, run \`openspec list --json\` to get available changes sorted by most recently modified, and ask the user to select one
17
22
 
18
- Present the top 3-4 most recently modified changes as options, showing:
23
+ When prompting, present the top 3-4 most recently modified changes as options, showing:
19
24
  - Change name
20
25
  - Schema (from \`schema\` field if present, otherwise "spec-driven")
21
26
  - Status (e.g., "0/5 tasks", "complete", "no tasks")
@@ -23,7 +28,7 @@ ${STORE_SELECTION_GUIDANCE}
23
28
 
24
29
  Mark the most recently modified change as "(Recommended)" since it's likely what the user wants to update.
25
30
 
26
- **IMPORTANT**: Do NOT guess or auto-select a change. Always let the user choose.
31
+ Always announce: "Using change: <name>" and how to override (e.g., \`/opsx:update <other>\`).
27
32
 
28
33
  2. **Get the change's artifacts**
29
34
  \`\`\`bash
@@ -31,8 +36,8 @@ ${STORE_SELECTION_GUIDANCE}
31
36
  \`\`\`
32
37
  Parse the JSON to understand current state. The response includes:
33
38
  - \`schemaName\`: The workflow schema being used (e.g., "spec-driven")
34
- - \`artifacts\`: Array of artifacts with their status ("done", "ready", "blocked")
35
- - \`isComplete\`: Boolean indicating if all artifacts are complete
39
+ - \`artifacts\`: Array of artifacts with their status ("done", "skipped", "ready", "blocked")
40
+ - \`isPlanningComplete\`: Boolean indicating if all planning artifacts are complete. Older CLI versions expose the same value as \`isComplete\`.
36
41
  - \`planningHome\`, \`changeRoot\`, \`artifactPaths\`, and \`actionContext\`: path and scope context. Use these instead of assuming repo-local paths.
37
42
 
38
43
  The artifact ids and paths come from the active schema - do NOT assume them, and do NOT branch on hardcoded artifact names. Custom schemas must work unchanged.
@@ -55,7 +60,7 @@ ${STORE_SELECTION_GUIDANCE}
55
60
  - If the user rejects a revision, do not write it - leave that artifact unchanged.
56
61
  - When a substantial rewrite is needed, get that artifact's rules and template first:
57
62
  \`\`\`bash
58
- openspec instructions <artifact-id> --change "<name>" --json
63
+ openspec instructions "<artifact-id>" --change "<name>" --json
59
64
  \`\`\`
60
65
 
61
66
  6. **Point to the next step (guidance only - NEVER act on it)**
@@ -76,7 +81,7 @@ After each invocation, show:
76
81
  - Edit only the concrete files in \`existingOutputPaths\`; never write to a glob \`resolvedOutputPath\`.
77
82
  - Do not advance the build frontier: no new artifacts, no new files under glob artifacts - that is \`/opsx:continue\`'s job.
78
83
  - Confirm every edit with the user before writing.
79
- - If the request changes the change's *intent* rather than refining it, recommend starting fresh with \`/opsx:new\` (the "Update vs. Start Fresh" heuristic).`,
84
+ - If the request changes the change's *intent* rather than refining it, first verify whether the expanded-profile \`/opsx:new\` workflow is available. If it is, recommend starting fresh with \`/opsx:new\` (the "Update vs. Start Fresh" heuristic). If it is unavailable, ask for a distinct unused change name and recommend \`openspec new change "<new-change-name>"\` instead.`,
80
85
  license: 'MIT',
81
86
  compatibility: 'Requires openspec CLI.',
82
87
  metadata: { author: 'openspec', version: '1.0' },
@@ -94,13 +99,18 @@ ${STORE_SELECTION_GUIDANCE}
94
99
 
95
100
  **Input**: Optionally specify a change name after \`/opsx:update\` (e.g., \`/opsx:update add-auth\`). If omitted, check if it can be inferred from conversation context. If vague or ambiguous you MUST prompt for available changes.
96
101
 
102
+ \`/opsx:continue\` is an expanded-profile workflow and may not be installed. Before suggesting it anywhere below, verify that it is available. If it is unavailable, \`openspec status --change "<name>" --json\` shows the next artifact and \`openspec instructions "<artifact-id>" --change "<name>" --json\` explains how to create it.
103
+
97
104
  **Steps**
98
105
 
99
- 1. **If no change name provided, prompt for selection**
106
+ 1. **Select the change**
100
107
 
101
- Run \`openspec list --json\` to get available changes sorted by most recently modified. Then use the **AskUserQuestion tool** to let the user select which change to update.
108
+ If a name is provided, use it. Otherwise:
109
+ - Infer from conversation context if the user mentioned a change
110
+ - Auto-select if only one active change exists
111
+ - If ambiguous, run \`openspec list --json\` to get available changes sorted by most recently modified, and ask the user to select one
102
112
 
103
- Present the top 3-4 most recently modified changes as options, showing:
113
+ When prompting, present the top 3-4 most recently modified changes as options, showing:
104
114
  - Change name
105
115
  - Schema (from \`schema\` field if present, otherwise "spec-driven")
106
116
  - Status (e.g., "0/5 tasks", "complete", "no tasks")
@@ -108,7 +118,7 @@ ${STORE_SELECTION_GUIDANCE}
108
118
 
109
119
  Mark the most recently modified change as "(Recommended)" since it's likely what the user wants to update.
110
120
 
111
- **IMPORTANT**: Do NOT guess or auto-select a change. Always let the user choose.
121
+ Always announce: "Using change: <name>" and how to override (e.g., \`/opsx:update <other>\`).
112
122
 
113
123
  2. **Get the change's artifacts**
114
124
  \`\`\`bash
@@ -116,8 +126,8 @@ ${STORE_SELECTION_GUIDANCE}
116
126
  \`\`\`
117
127
  Parse the JSON to understand current state. The response includes:
118
128
  - \`schemaName\`: The workflow schema being used (e.g., "spec-driven")
119
- - \`artifacts\`: Array of artifacts with their status ("done", "ready", "blocked")
120
- - \`isComplete\`: Boolean indicating if all artifacts are complete
129
+ - \`artifacts\`: Array of artifacts with their status ("done", "skipped", "ready", "blocked")
130
+ - \`isPlanningComplete\`: Boolean indicating if all planning artifacts are complete. Older CLI versions expose the same value as \`isComplete\`.
121
131
  - \`planningHome\`, \`changeRoot\`, \`artifactPaths\`, and \`actionContext\`: path and scope context. Use these instead of assuming repo-local paths.
122
132
 
123
133
  The artifact ids and paths come from the active schema - do NOT assume them, and do NOT branch on hardcoded artifact names. Custom schemas must work unchanged.
@@ -140,7 +150,7 @@ ${STORE_SELECTION_GUIDANCE}
140
150
  - If the user rejects a revision, do not write it - leave that artifact unchanged.
141
151
  - When a substantial rewrite is needed, get that artifact's rules and template first:
142
152
  \`\`\`bash
143
- openspec instructions <artifact-id> --change "<name>" --json
153
+ openspec instructions "<artifact-id>" --change "<name>" --json
144
154
  \`\`\`
145
155
 
146
156
  6. **Point to the next step (guidance only - NEVER act on it)**
@@ -161,7 +171,7 @@ After each invocation, show:
161
171
  - Edit only the concrete files in \`existingOutputPaths\`; never write to a glob \`resolvedOutputPath\`.
162
172
  - Do not advance the build frontier: no new artifacts, no new files under glob artifacts - that is \`/opsx:continue\`'s job.
163
173
  - Confirm every edit with the user before writing.
164
- - If the request changes the change's *intent* rather than refining it, recommend starting fresh with \`/opsx:new\` (the "Update vs. Start Fresh" heuristic).`
174
+ - If the request changes the change's *intent* rather than refining it, first verify whether the expanded-profile \`/opsx:new\` workflow is available. If it is, recommend starting fresh with \`/opsx:new\` (the "Update vs. Start Fresh" heuristic). If it is unavailable, ask for a distinct unused change name and recommend \`openspec new change "<new-change-name>"\` instead.`
165
175
  };
166
176
  }
167
177
  //# sourceMappingURL=update-change.js.map
@@ -11,15 +11,18 @@ ${STORE_SELECTION_GUIDANCE}
11
11
 
12
12
  **Steps**
13
13
 
14
- 1. **If no change name provided, prompt for selection**
14
+ 1. **Select the change**
15
15
 
16
- Run \`openspec list --json\` to get available changes. Use the **AskUserQuestion tool** to let the user select.
16
+ If a name is provided, use it. Otherwise:
17
+ - Infer from conversation context if the user mentioned a change
18
+ - Auto-select if only one active change exists
19
+ - If ambiguous, run \`openspec list --json\` to get available changes and ask the user to select one
17
20
 
18
- Show changes that have implementation tasks (tasks artifact exists).
21
+ When prompting, show changes that have implementation tasks (tasks artifact exists).
19
22
  Include the schema used for each change if available.
20
23
  Mark changes with incomplete tasks as "(In Progress)".
21
24
 
22
- **IMPORTANT**: Do NOT guess or auto-select a change. Always let the user choose.
25
+ Always announce: "Using change: <name>" and how to override (e.g., \`/opsx:verify <other>\`).
23
26
 
24
27
  2. **Check status to understand the schema**
25
28
  \`\`\`bash
@@ -107,7 +110,7 @@ ${STORE_SELECTION_GUIDANCE}
107
110
  8. **Generate Verification Report**
108
111
 
109
112
  **Summary Scorecard**:
110
- \`\`\`
113
+ \`\`\`markdown
111
114
  ## Verification Report: <change-name>
112
115
 
113
116
  ### Summary
@@ -182,15 +185,18 @@ ${STORE_SELECTION_GUIDANCE}
182
185
 
183
186
  **Steps**
184
187
 
185
- 1. **If no change name provided, prompt for selection**
188
+ 1. **Select the change**
186
189
 
187
- Run \`openspec list --json\` to get available changes. Use the **AskUserQuestion tool** to let the user select.
190
+ If a name is provided, use it. Otherwise:
191
+ - Infer from conversation context if the user mentioned a change
192
+ - Auto-select if only one active change exists
193
+ - If ambiguous, run \`openspec list --json\` to get available changes and ask the user to select one
188
194
 
189
- Show changes that have implementation tasks (tasks artifact exists).
195
+ When prompting, show changes that have implementation tasks (tasks artifact exists).
190
196
  Include the schema used for each change if available.
191
197
  Mark changes with incomplete tasks as "(In Progress)".
192
198
 
193
- **IMPORTANT**: Do NOT guess or auto-select a change. Always let the user choose.
199
+ Always announce: "Using change: <name>" and how to override (e.g., \`/opsx:verify <other>\`).
194
200
 
195
201
  2. **Check status to understand the schema**
196
202
  \`\`\`bash
@@ -278,7 +284,7 @@ ${STORE_SELECTION_GUIDANCE}
278
284
  8. **Generate Verification Report**
279
285
 
280
286
  **Summary Scorecard**:
281
- \`\`\`
287
+ \`\`\`markdown
282
288
  ## Verification Report: <change-name>
283
289
 
284
290
  ### Summary