@seanmars/tospec 0.19.0-beta.7 → 0.19.0-beta.8

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 (194) hide show
  1. package/CHANGELOG.md +80 -1
  2. package/assets/dashboard/app.js +3 -3
  3. package/assets/rules/tospec/decision.md +3 -0
  4. package/dist/cli/index.d.ts.map +1 -1
  5. package/dist/cli/index.js +191 -33
  6. package/dist/cli/index.js.map +1 -1
  7. package/dist/commands/config.d.ts.map +1 -1
  8. package/dist/commands/config.js +135 -24
  9. package/dist/commands/config.js.map +1 -1
  10. package/dist/commands/dashboard.d.ts +2 -2
  11. package/dist/commands/dashboard.d.ts.map +1 -1
  12. package/dist/commands/dashboard.js +75 -10
  13. package/dist/commands/dashboard.js.map +1 -1
  14. package/dist/commands/decision.d.ts +11 -0
  15. package/dist/commands/decision.d.ts.map +1 -1
  16. package/dist/commands/decision.js +164 -26
  17. package/dist/commands/decision.js.map +1 -1
  18. package/dist/commands/shared-output.d.ts +12 -0
  19. package/dist/commands/shared-output.d.ts.map +1 -1
  20. package/dist/commands/shared-output.js +50 -1
  21. package/dist/commands/shared-output.js.map +1 -1
  22. package/dist/commands/show.d.ts +10 -0
  23. package/dist/commands/show.d.ts.map +1 -1
  24. package/dist/commands/show.js +13 -3
  25. package/dist/commands/show.js.map +1 -1
  26. package/dist/commands/validate.d.ts +23 -1
  27. package/dist/commands/validate.d.ts.map +1 -1
  28. package/dist/commands/validate.js +61 -12
  29. package/dist/commands/validate.js.map +1 -1
  30. package/dist/commands/workflow/index.d.ts +5 -5
  31. package/dist/commands/workflow/index.d.ts.map +1 -1
  32. package/dist/commands/workflow/index.js +5 -5
  33. package/dist/commands/workflow/index.js.map +1 -1
  34. package/dist/commands/workflow/instructions.d.ts +23 -0
  35. package/dist/commands/workflow/instructions.d.ts.map +1 -1
  36. package/dist/commands/workflow/instructions.js +84 -16
  37. package/dist/commands/workflow/instructions.js.map +1 -1
  38. package/dist/commands/workflow/new-change.d.ts +2 -0
  39. package/dist/commands/workflow/new-change.d.ts.map +1 -1
  40. package/dist/commands/workflow/new-change.js +32 -4
  41. package/dist/commands/workflow/new-change.js.map +1 -1
  42. package/dist/commands/workflow/schemas.d.ts +2 -0
  43. package/dist/commands/workflow/schemas.d.ts.map +1 -1
  44. package/dist/commands/workflow/schemas.js +38 -1
  45. package/dist/commands/workflow/schemas.js.map +1 -1
  46. package/dist/commands/workflow/shared.d.ts +34 -2
  47. package/dist/commands/workflow/shared.d.ts.map +1 -1
  48. package/dist/commands/workflow/shared.js +37 -3
  49. package/dist/commands/workflow/shared.js.map +1 -1
  50. package/dist/commands/workflow/status.d.ts +14 -0
  51. package/dist/commands/workflow/status.d.ts.map +1 -1
  52. package/dist/commands/workflow/status.js +62 -8
  53. package/dist/commands/workflow/status.js.map +1 -1
  54. package/dist/commands/workflow/templates.d.ts +7 -0
  55. package/dist/commands/workflow/templates.d.ts.map +1 -1
  56. package/dist/commands/workflow/templates.js +13 -0
  57. package/dist/commands/workflow/templates.js.map +1 -1
  58. package/dist/core/archive.d.ts +14 -0
  59. package/dist/core/archive.d.ts.map +1 -1
  60. package/dist/core/archive.js +151 -21
  61. package/dist/core/archive.js.map +1 -1
  62. package/dist/core/artifact-graph/index.d.ts +1 -1
  63. package/dist/core/artifact-graph/index.d.ts.map +1 -1
  64. package/dist/core/artifact-graph/index.js +1 -1
  65. package/dist/core/artifact-graph/index.js.map +1 -1
  66. package/dist/core/artifact-graph/instruction-loader.d.ts +63 -3
  67. package/dist/core/artifact-graph/instruction-loader.d.ts.map +1 -1
  68. package/dist/core/artifact-graph/instruction-loader.js +35 -26
  69. package/dist/core/artifact-graph/instruction-loader.js.map +1 -1
  70. package/dist/core/artifact-graph/resolver.d.ts +26 -0
  71. package/dist/core/artifact-graph/resolver.d.ts.map +1 -1
  72. package/dist/core/artifact-graph/resolver.js +44 -4
  73. package/dist/core/artifact-graph/resolver.js.map +1 -1
  74. package/dist/core/artifact-graph/stub-detection.d.ts +20 -0
  75. package/dist/core/artifact-graph/stub-detection.d.ts.map +1 -0
  76. package/dist/core/artifact-graph/stub-detection.js +42 -0
  77. package/dist/core/artifact-graph/stub-detection.js.map +1 -0
  78. package/dist/core/change-presenter.d.ts +16 -0
  79. package/dist/core/change-presenter.d.ts.map +1 -1
  80. package/dist/core/change-presenter.js +68 -9
  81. package/dist/core/change-presenter.js.map +1 -1
  82. package/dist/core/change-status-policy.d.ts +12 -1
  83. package/dist/core/change-status-policy.d.ts.map +1 -1
  84. package/dist/core/change-status-policy.js +33 -1
  85. package/dist/core/change-status-policy.js.map +1 -1
  86. package/dist/core/codex-residue.js +1 -1
  87. package/dist/core/config-schema.d.ts +1 -12
  88. package/dist/core/config-schema.d.ts.map +1 -1
  89. package/dist/core/config-schema.js +27 -1
  90. package/dist/core/config-schema.js.map +1 -1
  91. package/dist/core/config.d.ts +37 -0
  92. package/dist/core/config.d.ts.map +1 -1
  93. package/dist/core/config.js +37 -0
  94. package/dist/core/config.js.map +1 -1
  95. package/dist/core/dashboard-activity.js +2 -2
  96. package/dist/core/dashboard-activity.js.map +1 -1
  97. package/dist/core/dashboard-data.d.ts +5 -0
  98. package/dist/core/dashboard-data.d.ts.map +1 -1
  99. package/dist/core/dashboard-data.js +15 -8
  100. package/dist/core/dashboard-data.js.map +1 -1
  101. package/dist/core/init.d.ts +22 -0
  102. package/dist/core/init.d.ts.map +1 -1
  103. package/dist/core/init.js +107 -42
  104. package/dist/core/init.js.map +1 -1
  105. package/dist/core/list.d.ts +1 -1
  106. package/dist/core/list.d.ts.map +1 -1
  107. package/dist/core/list.js +68 -17
  108. package/dist/core/list.js.map +1 -1
  109. package/dist/core/markdown-render.d.ts +33 -0
  110. package/dist/core/markdown-render.d.ts.map +1 -0
  111. package/dist/core/markdown-render.js +103 -0
  112. package/dist/core/markdown-render.js.map +1 -0
  113. package/dist/core/migrate.d.ts +17 -5
  114. package/dist/core/migrate.d.ts.map +1 -1
  115. package/dist/core/migrate.js +48 -2
  116. package/dist/core/migrate.js.map +1 -1
  117. package/dist/core/parsers/change-parser.js +1 -1
  118. package/dist/core/parsers/change-parser.js.map +1 -1
  119. package/dist/core/parsers/markdown-parser.d.ts.map +1 -1
  120. package/dist/core/parsers/markdown-parser.js +16 -0
  121. package/dist/core/parsers/markdown-parser.js.map +1 -1
  122. package/dist/core/root-selection.d.ts +11 -1
  123. package/dist/core/root-selection.d.ts.map +1 -1
  124. package/dist/core/root-selection.js +4 -2
  125. package/dist/core/root-selection.js.map +1 -1
  126. package/dist/core/rules.d.ts +6 -1
  127. package/dist/core/rules.d.ts.map +1 -1
  128. package/dist/core/rules.js +24 -2
  129. package/dist/core/rules.js.map +1 -1
  130. package/dist/core/schemas/base.schema.d.ts +3 -0
  131. package/dist/core/schemas/base.schema.d.ts.map +1 -1
  132. package/dist/core/schemas/base.schema.js +22 -0
  133. package/dist/core/schemas/base.schema.js.map +1 -1
  134. package/dist/core/schemas/change.schema.d.ts +8 -0
  135. package/dist/core/schemas/change.schema.d.ts.map +1 -1
  136. package/dist/core/schemas/spec.schema.d.ts +2 -0
  137. package/dist/core/schemas/spec.schema.d.ts.map +1 -1
  138. package/dist/core/shared/index.d.ts +1 -1
  139. package/dist/core/shared/index.d.ts.map +1 -1
  140. package/dist/core/shared/index.js +1 -1
  141. package/dist/core/shared/index.js.map +1 -1
  142. package/dist/core/shared/rules-generation.d.ts +27 -6
  143. package/dist/core/shared/rules-generation.d.ts.map +1 -1
  144. package/dist/core/shared/rules-generation.js +115 -44
  145. package/dist/core/shared/rules-generation.js.map +1 -1
  146. package/dist/core/shared/tool-detection.d.ts +19 -0
  147. package/dist/core/shared/tool-detection.d.ts.map +1 -1
  148. package/dist/core/shared/tool-detection.js +30 -2
  149. package/dist/core/shared/tool-detection.js.map +1 -1
  150. package/dist/core/spec-presenter.d.ts.map +1 -1
  151. package/dist/core/spec-presenter.js +5 -0
  152. package/dist/core/spec-presenter.js.map +1 -1
  153. package/dist/core/specs-apply.d.ts +15 -1
  154. package/dist/core/specs-apply.d.ts.map +1 -1
  155. package/dist/core/specs-apply.js +33 -11
  156. package/dist/core/specs-apply.js.map +1 -1
  157. package/dist/core/templates/workflows/apply.js +1 -1
  158. package/dist/core/templates/workflows/apply.js.map +1 -1
  159. package/dist/core/templates/workflows/archive.d.ts.map +1 -1
  160. package/dist/core/templates/workflows/archive.js +4 -2
  161. package/dist/core/templates/workflows/archive.js.map +1 -1
  162. package/dist/core/templates/workflows/decision.js +1 -1
  163. package/dist/core/update.d.ts +26 -0
  164. package/dist/core/update.d.ts.map +1 -1
  165. package/dist/core/update.js +111 -23
  166. package/dist/core/update.js.map +1 -1
  167. package/dist/core/validation/constants.d.ts +1 -1
  168. package/dist/core/validation/constants.d.ts.map +1 -1
  169. package/dist/core/validation/constants.js +6 -1
  170. package/dist/core/validation/constants.js.map +1 -1
  171. package/dist/core/validation/section-validator.d.ts.map +1 -1
  172. package/dist/core/validation/section-validator.js +21 -3
  173. package/dist/core/validation/section-validator.js.map +1 -1
  174. package/dist/core/validation/validator.d.ts +9 -3
  175. package/dist/core/validation/validator.d.ts.map +1 -1
  176. package/dist/core/validation/validator.js +58 -8
  177. package/dist/core/validation/validator.js.map +1 -1
  178. package/dist/utils/change-utils.d.ts +28 -0
  179. package/dist/utils/change-utils.d.ts.map +1 -1
  180. package/dist/utils/change-utils.js +115 -26
  181. package/dist/utils/change-utils.js.map +1 -1
  182. package/dist/utils/file-system.d.ts +1 -1
  183. package/dist/utils/file-system.js +1 -1
  184. package/dist/utils/item-discovery.d.ts +20 -5
  185. package/dist/utils/item-discovery.d.ts.map +1 -1
  186. package/dist/utils/item-discovery.js +28 -9
  187. package/dist/utils/item-discovery.js.map +1 -1
  188. package/dist/utils/task-progress.js +1 -1
  189. package/package.json +1 -1
  190. package/schemas/decision/templates/decision.md +3 -1
  191. package/schemas/decision/templates/index.md +2 -2
  192. package/schemas/issue/templates/spec.md +8 -0
  193. package/schemas/sdd/templates/spec.md +8 -0
  194. /package/assets/rules/tospec/{single-sourc-of-truth.md → single-source-of-truth.md} +0 -0
@@ -16,6 +16,20 @@ export interface StatusOptions {
16
16
  * reference this one constant rather than each spelling the shape out.
17
17
  */
18
18
  export declare const BATCH_STATUS_FAILURE_PAYLOAD: Record<string, unknown>;
19
+ /**
20
+ * The single-change `--json` failure null-shape.
21
+ *
22
+ * Flat payload, like `instructions` and `show`: it spreads `changeName`,
23
+ * `artifacts` and a dozen siblings at the top level rather than nesting them
24
+ * under a wrapper. Per
25
+ * decisions/20260917_155623-flat-json-payloads-null-a-real-success-key.md, such
26
+ * a command nulls a key its success output really carries — `changeName` here,
27
+ * as `instruction` and `id` do there. It previously nulled nothing at all, which
28
+ * left this the one envelope a caller could not tell apart from an unrelated
29
+ * error document; the ADR's two tests both pass vacuously on an empty key set,
30
+ * so the rule had to be asserted directly (see json-failure.test.ts).
31
+ */
32
+ export declare const STATUS_FAILURE_PAYLOAD: Record<string, unknown>;
19
33
  export declare function statusCommand(options: StatusOptions): Promise<void>;
20
34
  export declare function printStatusText(status: ChangeStatus): void;
21
35
  //# sourceMappingURL=status.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/commands/workflow/status.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,oCAAoC,CAAC;AAa5C,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AASD;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAqB,CAAC;AAMvF,wBAAsB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAmHzE;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAmC1D"}
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/commands/workflow/status.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,oCAAoC,CAAC;AAe5C,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AASD;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAiC,CAAC;AAEnG;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAoC,CAAC;AAMhG,wBAAsB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAmJzE;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CA6C1D"}
@@ -6,14 +6,29 @@
6
6
  import { getChangeDir } from '../../core/planning-home.js';
7
7
  import { resolveRootForCommand, toPlanningHome, toRootOutput, } from '../../core/root-selection.js';
8
8
  import { loadChangeContext, formatChangeStatus, } from '../../core/artifact-graph/index.js';
9
- import { validateChangeExists, validateSchemaExists, getAvailableChanges, getStatusIndicator, } from './shared.js';
9
+ import { validateChangeExists, validateSchemaExists, assertChangeSchema, getAvailableChanges, getStatusIndicator, } from './shared.js';
10
10
  import { emitSuccess, asStatus } from '../shared-output.js';
11
+ import { findTicketPath } from '../../utils/item-discovery.js';
11
12
  /**
12
13
  * The `--all --json` failure null-shape. Root selection resolves inside this
13
14
  * module while thrown errors are caught by the CLI wrapper, so both call sites
14
15
  * reference this one constant rather than each spelling the shape out.
15
16
  */
16
- export const BATCH_STATUS_FAILURE_PAYLOAD = { changes: null };
17
+ export const BATCH_STATUS_FAILURE_PAYLOAD = { changes: null, root: null };
18
+ /**
19
+ * The single-change `--json` failure null-shape.
20
+ *
21
+ * Flat payload, like `instructions` and `show`: it spreads `changeName`,
22
+ * `artifacts` and a dozen siblings at the top level rather than nesting them
23
+ * under a wrapper. Per
24
+ * decisions/20260917_155623-flat-json-payloads-null-a-real-success-key.md, such
25
+ * a command nulls a key its success output really carries — `changeName` here,
26
+ * as `instruction` and `id` do there. It previously nulled nothing at all, which
27
+ * left this the one envelope a caller could not tell apart from an unrelated
28
+ * error document; the ADR's two tests both pass vacuously on an empty key set,
29
+ * so the rule had to be asserted directly (see json-failure.test.ts).
30
+ */
31
+ export const STATUS_FAILURE_PAYLOAD = { changeName: null, root: null };
17
32
  // -----------------------------------------------------------------------------
18
33
  // Command Implementation
19
34
  // -----------------------------------------------------------------------------
@@ -23,9 +38,16 @@ export async function statusCommand(options) {
23
38
  }
24
39
  // The batch null-shape rides along so a root-selection failure under
25
40
  // --all --json still carries `changes: null` rather than an empty payload.
41
+ //
42
+ // No implicit root: it resolves only when no ancestor holds a `tospec/` dir,
43
+ // and status would then answer "No active changes." with exit 0 about a
44
+ // directory that is not a project at all — the same vacuous pass `validate`
45
+ // refuses implicit roots to avoid. `list` and `archive` refuse it too, so all
46
+ // four now report the one `no_tospec_root` diagnostic for the one condition.
26
47
  const root = await resolveRootForCommand(options, {
27
48
  json: options.json,
28
- failurePayload: options.all ? BATCH_STATUS_FAILURE_PAYLOAD : undefined,
49
+ allowImplicitRoot: false,
50
+ failurePayload: options.all ? BATCH_STATUS_FAILURE_PAYLOAD : STATUS_FAILURE_PAYLOAD,
29
51
  });
30
52
  if (!root) {
31
53
  return;
@@ -40,6 +62,15 @@ export async function statusCommand(options) {
40
62
  changeDir: getChangeDir(planningHome, changeName),
41
63
  planningHome,
42
64
  }));
65
+ // The ticket lives outside the change dir under a CLI-generated timestamp, so
66
+ // it appears in no artifact path — an agent asked to fill in its Summary had
67
+ // to glob `tospec/tickets/` and match frontmatter by hand. Added here, inside
68
+ // the shared loader, so the batch and single-change payloads keep reporting
69
+ // the same fields.
70
+ const loadStatusWithTicket = async (changeName) => ({
71
+ ...loadStatus(changeName),
72
+ ticketPath: (await findTicketPath(projectRoot, changeName)) ?? null,
73
+ });
43
74
  // Handle no-changes case gracefully — status is informational,
44
75
  // so "no changes" is a valid state, not an error.
45
76
  if (!options.change) {
@@ -47,6 +78,7 @@ export async function statusCommand(options) {
47
78
  // the same way whether or not any change exists yet.
48
79
  if (options.all && options.schema) {
49
80
  validateSchemaExists(options.schema, projectRoot);
81
+ assertChangeSchema(options.schema);
50
82
  }
51
83
  const available = await getAvailableChanges(projectRoot, root.changesDir);
52
84
  if (available.length === 0) {
@@ -63,7 +95,7 @@ export async function statusCommand(options) {
63
95
  const entries = [];
64
96
  for (const changeName of available.sort((a, b) => a.localeCompare(b))) {
65
97
  try {
66
- entries.push(loadStatus(changeName));
98
+ entries.push(await loadStatusWithTicket(changeName));
67
99
  }
68
100
  catch (error) {
69
101
  entries.push({ changeName, status: [asStatus(error, 'change_error')] });
@@ -101,17 +133,31 @@ export async function statusCommand(options) {
101
133
  // every change should not have to find it in --help.
102
134
  throw new Error(`Missing required option --change (or --all for every active change). Available changes:\n ${available.join('\n ')}`);
103
135
  }
104
- const changeName = await validateChangeExists(options.change, projectRoot, root.changesDir, { newChangeHint });
105
- // Validate schema if explicitly provided
136
+ // Validate schema if explicitly provided.
137
+ //
138
+ // Guarded for the same reason as `instructions` and `new change`, and with
139
+ // more force: `status --schema decision` planned an artifact at
140
+ // tospec/changes/<change>/decision.md — the orphan file those two already
141
+ // refuse — and then handed back a nextSteps line telling the caller to run
142
+ // `tospec instructions decision`, which refuses. The two commands together
143
+ // formed a closed loop: the one that issues the instruction was the one
144
+ // without the check.
145
+ //
146
+ // Before change resolution, not after (round 4 report 15). Sitting after it,
147
+ // the guard never fired in an empty project: the caller got "Create one with:
148
+ // tospec new change <name>", did exactly that, and only then learned the
149
+ // schema was never usable — the misdirection this guard was added to remove.
106
150
  if (options.schema) {
107
151
  validateSchemaExists(options.schema, projectRoot);
152
+ assertChangeSchema(options.schema);
108
153
  }
154
+ const changeName = await validateChangeExists(options.change, projectRoot, root.changesDir, { newChangeHint });
109
155
  // loadChangeContext will auto-detect schema from metadata if not provided
110
- const status = loadStatus(changeName);
111
156
  if (options.json) {
112
- emitSuccess({ ...status }, rootOutput);
157
+ emitSuccess({ ...(await loadStatusWithTicket(changeName)) }, rootOutput);
113
158
  return;
114
159
  }
160
+ const status = loadStatus(changeName);
115
161
  printStatusText(status);
116
162
  }
117
163
  export function printStatusText(status) {
@@ -133,6 +179,14 @@ export function printStatusText(status) {
133
179
  if (artifact.status === 'stub') {
134
180
  line += ' (stub: file exists but is empty or template-identical — fill it in)';
135
181
  }
182
+ // The two share a marker; the label is what tells them apart, and the
183
+ // difference is whether writing it is still on the table.
184
+ if (artifact.status === 'optional') {
185
+ line += ' (optional: not written — write it if this change needs it)';
186
+ }
187
+ if (artifact.status === 'skipped') {
188
+ line += ' (skipped: this change declared it away)';
189
+ }
136
190
  console.log(line);
137
191
  }
138
192
  for (const diagnostic of status.status ?? []) {
@@ -1 +1 @@
1
- {"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/commands/workflow/status.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/commands/workflow/status.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,13 @@
3
3
  *
4
4
  * Shows resolved template paths for all artifacts in a schema.
5
5
  */
6
+ /**
7
+ * The `--json` null-shape. Exported so the commander-level shape table and this
8
+ * command's own catch block read the same object instead of two literals that
9
+ * drifted — the catch block's copy was missing `root`, which every success
10
+ * payload carries.
11
+ */
12
+ export declare const TEMPLATES_FAILURE_PAYLOAD: Record<string, unknown>;
6
13
  export interface TemplatesOptions {
7
14
  schema?: string;
8
15
  json?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../../src/commands/workflow/templates.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAiBH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC;CACxC;AAMD,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiE/E"}
1
+ {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../../src/commands/workflow/templates.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAiBH;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAG7D,CAAC;AAEF,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC;CACxC;AAMD,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiE/E"}
@@ -10,6 +10,19 @@ import { validateSchemaExists, DEFAULT_SCHEMA } from './shared.js';
10
10
  import { emitSuccess } from '../shared-output.js';
11
11
  import { resolveRootForCommand, toRootOutput } from '../../core/root-selection.js';
12
12
  // -----------------------------------------------------------------------------
13
+ // Types
14
+ // -----------------------------------------------------------------------------
15
+ /**
16
+ * The `--json` null-shape. Exported so the commander-level shape table and this
17
+ * command's own catch block read the same object instead of two literals that
18
+ * drifted — the catch block's copy was missing `root`, which every success
19
+ * payload carries.
20
+ */
21
+ export const TEMPLATES_FAILURE_PAYLOAD = {
22
+ templates: null,
23
+ root: null,
24
+ };
25
+ // -----------------------------------------------------------------------------
13
26
  // Command Implementation
14
27
  // -----------------------------------------------------------------------------
15
28
  export async function templatesCommand(options) {
@@ -1 +1 @@
1
- {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/commands/workflow/templates.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/commands/workflow/templates.ts"],"names":[],"mappings":"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"}
@@ -40,6 +40,20 @@ export declare class ArchiveCommand {
40
40
  * step by hand for the "every blocked path throws in JSON mode" invariant.
41
41
  */
42
42
  private gate;
43
+ /**
44
+ * Required artifacts the change never produced, in schema order.
45
+ *
46
+ * Reads the same graph `tospec status` does, so the two can never disagree
47
+ * about what "required" means. `skipped` covers the legitimate opt-out
48
+ * (`skip_specs: true`), and optional artifacts are the schema's own statement
49
+ * that their absence is fine — neither is reported here.
50
+ *
51
+ * A change whose graph cannot be loaded at all (unreadable metadata, unknown
52
+ * schema) returns nothing rather than throwing: this gate exists to describe
53
+ * a change, not to become a second way for archive to fail on one. Whatever
54
+ * broke the load is already validation's to report.
55
+ */
56
+ private findMissingRequiredArtifacts;
43
57
  /**
44
58
  * Shared archive flow. In human mode (json=false) prompts and prose match
45
59
  * the historical behavior and cancellations return null. In JSON mode no
@@ -1 +1 @@
1
- {"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../src/core/archive.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAQxD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,wBAAkB,CAAC;AAElD;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAYjF;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAoDD;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAe5E;AAgED,2FAA2F;AAC3F,wBAAsB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAYvE;AAED,qBAAa,cAAc;IACnB,OAAO,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoC9E;IAED,OAAO,CAAC,gBAAgB;IAiBxB;;;;;;;OAOG;YACW,IAAI;IA+BlB;;;;OAIG;YACW,GAAG;YA4YH,YAAY;CAwC3B"}
1
+ {"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../src/core/archive.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAQxD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,wBAAkB,CAAC;AAElD;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAYjF;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AA2DD;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAe5E;AAgED,2FAA2F;AAC3F,wBAAsB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAYvE;AAED,qBAAa,cAAc;IACnB,OAAO,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyC9E;IAED,OAAO,CAAC,gBAAgB;IAiBxB;;;;;;;OAOG;YACW,IAAI;IAoClB;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,4BAA4B;IAuBpC;;;;OAIG;YACW,GAAG;YAweH,YAAY;CAwC3B"}
@@ -5,11 +5,12 @@ import { Validator } from './validation/validator.js';
5
5
  import { validateChangeArtifacts } from '../commands/validate.js';
6
6
  import { isRootSelectionError, resolveRootForCommand, toRootOutput, } from './root-selection.js';
7
7
  import { findSpecUpdates, buildUpdatedSpec, writeUpdatedSpec, retireSpec, } from './specs-apply.js';
8
+ import { loadChangeContext, formatChangeStatus } from './artifact-graph/index.js';
8
9
  import { formatTimestamp } from '../utils/timestamp.js';
9
10
  import { findSpecFiles } from '../utils/spec-files.js';
10
11
  import { FileSystemUtils, isMissingPathError } from '../utils/file-system.js';
11
12
  import { isKebabId, KEBAB_ID_DESCRIPTION } from './id.js';
12
- import { findTicketPath, listActiveChangeDirs } from '../utils/item-discovery.js';
13
+ import { findTicketPaths, listActiveChangeDirs } from '../utils/item-discovery.js';
13
14
  import { METADATA_FILENAME, readChangeMetadata } from '../utils/change-metadata.js';
14
15
  import { emitSuccess, emitFailureStatus } from '../commands/shared-output.js';
15
16
  /**
@@ -169,7 +170,12 @@ export class ArchiveCommand {
169
170
  // Same root resolution adapter as every other command (report 4.3).
170
171
  const root = await resolveRootForCommand(options, {
171
172
  json,
172
- failurePayload: { archive: null },
173
+ // See workflow/status.ts: an implicit root means no ancestor holds a
174
+ // `tospec/` dir, and archiving there can only fail — but with a plain
175
+ // "no changes directory" message rather than the shared no_tospec_root
176
+ // diagnostic its sibling commands report for the same condition.
177
+ allowImplicitRoot: false,
178
+ failurePayload: { archive: null, root: null },
173
179
  });
174
180
  if (!root) {
175
181
  return;
@@ -178,32 +184,32 @@ export class ArchiveCommand {
178
184
  // A gate overridden by --yes has something to report but did not fail —
179
185
  // exit 0 stands, and the warning rides on `status` instead of being
180
186
  // dropped, since prose on stdout would corrupt the JSON document.
181
- const gateWarnings = [];
187
+ const jsonWarnings = [];
182
188
  try {
183
- const result = await this.run(changeName, options, root, true, gateWarnings);
189
+ const result = await this.run(changeName, options, root, true, jsonWarnings);
184
190
  if (!result) {
185
191
  return;
186
192
  }
187
- emitSuccess({ archive: result, ...(gateWarnings.length ? { status: gateWarnings } : {}) }, toRootOutput(root));
193
+ emitSuccess({ archive: result, ...(jsonWarnings.length ? { status: jsonWarnings } : {}) }, toRootOutput(root));
188
194
  }
189
195
  catch (error) {
190
196
  // The gates that were overridden before the failure still happened, and
191
197
  // a run that both skipped validation *and* then failed is exactly when
192
198
  // the reader needs to know. Dropping them here reproduced, on the
193
199
  // failure path, the discard this collection exists to prevent.
194
- this.printJsonFailure(root, toArchiveDiagnostic(error), gateWarnings);
200
+ this.printJsonFailure(root, toArchiveDiagnostic(error), jsonWarnings);
195
201
  }
196
202
  return;
197
203
  }
198
204
  await this.run(changeName, options, root, false, []);
199
205
  }
200
- printJsonFailure(root, diagnostic, gateWarnings = []) {
206
+ printJsonFailure(root, diagnostic, jsonWarnings = []) {
201
207
  // emitFailureStatus appends the error to any `status` already in the
202
208
  // payload, so the warnings keep their order and precede the failure.
203
209
  emitFailureStatus({
204
210
  archive: null,
205
211
  ...(root ? { root: toRootOutput(root) } : {}),
206
- ...(gateWarnings.length ? { status: gateWarnings } : {}),
212
+ ...(jsonWarnings.length ? { status: jsonWarnings } : {}),
207
213
  }, diagnostic);
208
214
  }
209
215
  /**
@@ -217,7 +223,12 @@ export class ArchiveCommand {
217
223
  async gate(opts) {
218
224
  if (opts.yes) {
219
225
  if (opts.json) {
220
- opts.warnings.push({ severity: 'warning', code: opts.code, message: opts.message, fix: opts.fix });
226
+ // No `fix`. Every gate's fix is phrased for the caller who is being
227
+ // blocked and ends in "or rerun with --yes" — advice that read as
228
+ // nonsense in the output of a run that already passed `--yes`, telling
229
+ // the reader to do the thing they just did. The archive has happened;
230
+ // there is nothing left to act on, so the message stands alone.
231
+ opts.warnings.push({ severity: 'warning', code: opts.code, message: opts.message });
221
232
  }
222
233
  else {
223
234
  console.error(opts.warning);
@@ -235,12 +246,42 @@ export class ArchiveCommand {
235
246
  }
236
247
  return true;
237
248
  }
249
+ /**
250
+ * Required artifacts the change never produced, in schema order.
251
+ *
252
+ * Reads the same graph `tospec status` does, so the two can never disagree
253
+ * about what "required" means. `skipped` covers the legitimate opt-out
254
+ * (`skip_specs: true`), and optional artifacts are the schema's own statement
255
+ * that their absence is fine — neither is reported here.
256
+ *
257
+ * A change whose graph cannot be loaded at all (unreadable metadata, unknown
258
+ * schema) returns nothing rather than throwing: this gate exists to describe
259
+ * a change, not to become a second way for archive to fail on one. Whatever
260
+ * broke the load is already validation's to report.
261
+ */
262
+ findMissingRequiredArtifacts(projectRoot, changeName, changeDir) {
263
+ try {
264
+ // Schema left undefined on purpose: loadChangeContext reads it from the
265
+ // change's own metadata, the same way `status` does.
266
+ const status = formatChangeStatus(loadChangeContext(projectRoot, changeName, undefined, { changeDir }));
267
+ return status.artifacts
268
+ .filter((artifact) => !artifact.optional && artifact.status !== 'done' && artifact.status !== 'skipped')
269
+ // A stub's file is on disk and still holds the template, so reporting it
270
+ // the same way as an absent one sent the reader to look for a file that
271
+ // was right there. The status is what distinguishes the two, and it is
272
+ // already in hand here.
273
+ .map((artifact) => (artifact.status === 'stub' ? `${artifact.id} (stub)` : artifact.id));
274
+ }
275
+ catch {
276
+ return [];
277
+ }
278
+ }
238
279
  /**
239
280
  * Shared archive flow. In human mode (json=false) prompts and prose match
240
281
  * the historical behavior and cancellations return null. In JSON mode no
241
282
  * prose reaches stdout and every blocked path throws.
242
283
  */
243
- async run(changeName, options, root, json, gateWarnings) {
284
+ async run(changeName, options, root, json, jsonWarnings) {
244
285
  const changesDir = root.changesDir;
245
286
  const archiveDir = root.archiveDir;
246
287
  const mainSpecsDir = root.specsDir;
@@ -249,7 +290,7 @@ export class ArchiveCommand {
249
290
  await fs.access(changesDir);
250
291
  }
251
292
  catch {
252
- throw new Error("No Tospec changes directory found. Run 'tospec init' first.");
293
+ throw new ArchiveBlockedError('changes_dir_missing', 'No Tospec changes directory found.', "Run 'tospec init' first.");
253
294
  }
254
295
  // Captured before the interactive branch can overwrite `changeName`: the
255
296
  // kebab guard below applies to the argument only, and provenance is the
@@ -323,11 +364,11 @@ export class ArchiveCommand {
323
364
  syncReportContent = await fs.readFile(syncReportPath, 'utf-8');
324
365
  }
325
366
  catch {
326
- throw new ArchiveBlockedError('SYNC_REPORT_MISSING', `sync-report.md not found for change '${changeName}'.`, 'Run tospec-sync first, or omit --require-sync.');
367
+ throw new ArchiveBlockedError('sync_report_missing', `sync-report.md not found for change '${changeName}'.`, 'Run tospec-sync first, or omit --require-sync.');
327
368
  }
328
369
  const conclusion = parseSyncReportConclusion(syncReportContent);
329
370
  if (conclusion !== 'PASS') {
330
- throw new ArchiveBlockedError('SYNC_REPORT_FAILED', `sync-report.md for change '${changeName}' does not report a PASS conclusion (found: ${conclusion ?? 'unparseable'}).`, 'Resolve the flagged Requirement(s) via tospec-apply, then re-run tospec-sync.');
371
+ throw new ArchiveBlockedError('sync_report_failed', `sync-report.md for change '${changeName}' does not report a PASS conclusion (found: ${conclusion ?? 'unparseable'}).`, 'Resolve the flagged Requirement(s) via tospec-apply, then re-run tospec-sync.');
331
372
  }
332
373
  }
333
374
  const skipValidation = options.validate === false || options.noValidate === true;
@@ -376,11 +417,18 @@ export class ArchiveCommand {
376
417
  json,
377
418
  yes: !!options.yes,
378
419
  code: 'archive_confirmation_required',
379
- message: 'Skipping validation requires confirmation: rerun with --yes.',
420
+ // States the condition, not the remedy. A gate's `message` is reused
421
+ // verbatim when `--yes` overrides the gate, where "rerun with --yes"
422
+ // told the reader to do the thing they had just done — the same defect
423
+ // that removing `fix` from overridden gates was meant to end. The other
424
+ // two gates were already written this way ("N incomplete task(s) found"),
425
+ // which is why only this one carried it. Remedies belong in `fix`, which
426
+ // an overridden gate drops.
427
+ message: `Validation is disabled for change '${changeName}' (--no-validate).`,
380
428
  fix: 'tospec archive <change-name> --json --no-validate --yes',
381
429
  prompt: '⚠️ WARNING: Skipping validation may archive invalid specs. Continue? (y/N)',
382
430
  warning: '\n⚠️ WARNING: Skipping validation may archive invalid specs.',
383
- warnings: gateWarnings,
431
+ warnings: jsonWarnings,
384
432
  });
385
433
  if (!proceed)
386
434
  return null;
@@ -390,6 +438,36 @@ export class ArchiveCommand {
390
438
  console.error(`Affected files: ${changeDir}`);
391
439
  }
392
440
  }
441
+ // The artifact graph already knows which artifacts a schema requires, and
442
+ // `status` reports it as isComplete — but nothing consulted that before
443
+ // archiving, so a change carrying only a delta spec archived clean with no
444
+ // proposal and no design. Validation cannot catch it: it checks the content
445
+ // of files that exist, and these do not exist.
446
+ //
447
+ // Archive is the last moment this is recoverable. Afterwards the change is
448
+ // in archive/ and its deltas are merged, so the why and the how the schema
449
+ // asked for are gone for good — and the person who had the answers has
450
+ // moved on. Overridable like every other gate, because a schema artifact is
451
+ // a planning obligation rather than a correctness one.
452
+ const missingArtifacts = this.findMissingRequiredArtifacts(root.path, changeName, changeDir);
453
+ if (missingArtifacts.length > 0) {
454
+ const names = missingArtifacts.join(', ');
455
+ // "missing or incomplete", because the list holds both: an artifact with no
456
+ // file, and one whose file is still the unfilled template. Saying "missing"
457
+ // of the second sent the reader looking for a file already on disk.
458
+ const proceed = await this.gate({
459
+ json,
460
+ yes: !!options.yes,
461
+ code: 'archive_artifacts_incomplete',
462
+ message: `Change '${changeName}' is missing or has incomplete required artifact(s): ${names}.`,
463
+ fix: `Run tospec status --change ${changeName} for the next step, or rerun with --yes.`,
464
+ prompt: `Warning: missing or incomplete required artifact(s): ${names}. Continue?`,
465
+ warning: `Warning: missing or incomplete required artifact(s): ${names}. Continuing due to --yes flag.`,
466
+ warnings: jsonWarnings,
467
+ });
468
+ if (!proceed)
469
+ return null;
470
+ }
393
471
  // Show progress and check for incomplete tasks
394
472
  // Use the already-resolved root rather than re-deriving it from changesDir:
395
473
  // the '..','..' hop silently encodes the tospec/changes layout.
@@ -408,7 +486,7 @@ export class ArchiveCommand {
408
486
  fix: 'Create the schema-tracked tasks file with checkboxes, or rerun with --yes.',
409
487
  prompt: 'Warning: no tracked task checkboxes were found. Continue?',
410
488
  warning: 'Warning: no tracked task checkboxes were found. Continuing due to --yes flag.',
411
- warnings: gateWarnings,
489
+ warnings: jsonWarnings,
412
490
  });
413
491
  if (!proceed)
414
492
  return null;
@@ -422,16 +500,39 @@ export class ArchiveCommand {
422
500
  fix: 'Complete the tasks or rerun with --yes.',
423
501
  prompt: `Warning: ${incompleteTasks} incomplete task(s) found. Continue?`,
424
502
  warning: `Warning: ${incompleteTasks} incomplete task(s) found. Continuing due to --yes flag.`,
425
- warnings: gateWarnings,
503
+ warnings: jsonWarnings,
426
504
  });
427
505
  if (!proceed)
428
506
  return null;
429
507
  }
430
508
  // Handle spec updates unless skipSpecs flag is set
431
509
  let specsUpdated = false;
432
- let totals;
510
+ let totals = { added: 0, modified: 0, removed: 0, renamed: 0, retired: 0 };
433
511
  if (options.skipSpecs) {
434
- if (!json) {
512
+ // Round 4 report 2. `--skip-specs` is documented for changes that have no
513
+ // deltas, so pointing it at one that does is user error — but archiving in
514
+ // silence made the mistake unrecoverable: the change moved to archive/ and
515
+ // the capability never reached the main specs, with nothing in the output
516
+ // saying so. The metadata spelling of the same intent (`skip_specs: true`)
517
+ // is an ERROR under exactly this shape; this at least names what was left
518
+ // behind. It stays a warning rather than a block because the flag is an
519
+ // explicit instruction and `--yes` already means "I confirm".
520
+ const discarded = await findSpecUpdates(changeDir, mainSpecsDir);
521
+ if (discarded.length > 0) {
522
+ // source is <changeDir>/specs/<capability>/spec.md — the capability is
523
+ // the directory that names it, the same level findSpecUpdates walks.
524
+ const listed = discarded
525
+ .map((update) => path.basename(path.dirname(update.source)))
526
+ .join(', ');
527
+ const message = `--skip-specs discarded ${discarded.length} delta spec(s); these capabilities were not merged into the main specs: ${listed}.`;
528
+ if (json) {
529
+ jsonWarnings.push({ severity: 'warning', code: 'archive_deltas_discarded', message });
530
+ }
531
+ else {
532
+ console.log(`Warning: ${message}`);
533
+ }
534
+ }
535
+ else if (!json) {
435
536
  console.log('Skipping spec updates (--skip-specs flag provided).');
436
537
  }
437
538
  }
@@ -482,6 +583,15 @@ export class ArchiveCommand {
482
583
  try {
483
584
  for (const update of specUpdates) {
484
585
  const built = await buildUpdatedSpec(update, changeName, { silent: json });
586
+ // In human mode buildUpdatedSpec already printed these. In JSON mode
587
+ // it stayed silent, so `status[]` is where they have to land — a
588
+ // dangling REMOVED used to be a completely invisible no-op for
589
+ // agent callers.
590
+ if (json) {
591
+ for (const n of built.notices) {
592
+ jsonWarnings.push({ severity: 'warning', code: n.code, message: n.message });
593
+ }
594
+ }
485
595
  prepared.push({ update, rebuilt: built.rebuilt, crlf: built.crlf, retired: built.retired, counts: built.counts });
486
596
  }
487
597
  }
@@ -559,7 +669,27 @@ export class ArchiveCommand {
559
669
  // The change's ticket lives in the global tospec/tickets/ index (outside the
560
670
  // change dir), so move it alongside into tickets/archive/ to keep the active
561
671
  // index limited to in-flight changes.
562
- const ticketPath = await findTicketPath(root.path, changeName);
672
+ const ticketPaths = await findTicketPaths(root.path, changeName);
673
+ // Newest wins. A second ticket exists only because the change was recreated
674
+ // before this was fixed, so the later stamp is the one describing the change
675
+ // being archived — taking `readdir` order filed the run under the abandoned
676
+ // attempt's ticket and stranded the real one (round 4 report 6). Reported
677
+ // rather than cleaned up: the leftovers are the user's to keep or delete,
678
+ // and archive must not silently remove a record.
679
+ const ticketPath = ticketPaths[ticketPaths.length - 1];
680
+ if (ticketPaths.length > 1) {
681
+ const stranded = ticketPaths
682
+ .slice(0, -1)
683
+ .map((file) => path.basename(file))
684
+ .join(', ');
685
+ const message = `${ticketPaths.length} active tickets name change '${changeName}'; archived ${path.basename(ticketPath)} and left the rest in tospec/tickets/: ${stranded}.`;
686
+ if (json) {
687
+ jsonWarnings.push({ severity: 'warning', code: 'ticket_duplicates_left', message });
688
+ }
689
+ else {
690
+ console.log(`Warning: ${message}`);
691
+ }
692
+ }
563
693
  if (ticketPath) {
564
694
  const ticketArchiveDir = path.join(root.path, 'tospec', 'tickets', 'archive');
565
695
  await fs.mkdir(ticketArchiveDir, { recursive: true });
@@ -576,7 +706,7 @@ export class ArchiveCommand {
576
706
  archivedAs: archiveName,
577
707
  path: archivePath,
578
708
  specsUpdated,
579
- ...(totals ? { totals } : {}),
709
+ totals,
580
710
  };
581
711
  }
582
712
  async selectChange(changesDir, projectRoot) {