@planu/cli 4.11.1 → 4.11.2

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 (116) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/engine/cascade-hooks/registry.js +0 -2
  3. package/dist/engine/challenge-scenarios-loader.d.ts +3 -3
  4. package/dist/engine/compliance-injector.d.ts +3 -3
  5. package/dist/engine/dashboard/kanban-logic.d.ts +1 -1
  6. package/dist/engine/doc-generator/portal/risk-matrix-svg.d.ts +1 -1
  7. package/dist/engine/doc-generator/proposal/proposal-generator.d.ts +1 -1
  8. package/dist/engine/elicitation/answer-extractor.d.ts +1 -4
  9. package/dist/engine/elicitation/answer-extractor.js +197 -68
  10. package/dist/engine/elicitation/decision-gap-detector.js +59 -79
  11. package/dist/engine/elicitation/index.d.ts +0 -1
  12. package/dist/engine/elicitation/index.js +0 -1
  13. package/dist/engine/elicitation/question-grounding-gate.js +83 -34
  14. package/dist/engine/evidence-gates/lifecycle-gate.js +27 -14
  15. package/dist/engine/evidence-index/index-builder.js +7 -2
  16. package/dist/engine/frontmatter-sha/frozen-fields.d.ts +1 -1
  17. package/dist/engine/handoff-artifacts/schemas/red-tests-handoff.d.ts +2 -2
  18. package/dist/engine/handoff-artifacts/schemas.d.ts +22 -22
  19. package/dist/engine/human-summary.js +3 -3
  20. package/dist/engine/implementation-contract/common.d.ts +1 -1
  21. package/dist/engine/keyword-matcher/stopwords.d.ts +2 -2
  22. package/dist/engine/provider-adapters/adapters/claude.d.ts +1 -1
  23. package/dist/engine/provider-adapters/adapters/gemini.d.ts +1 -1
  24. package/dist/engine/provider-adapters/adapters/gpt4.d.ts +1 -1
  25. package/dist/engine/provider-adapters/adapters/markdown.d.ts +1 -1
  26. package/dist/engine/safety/atomic-write-file.d.ts +1 -1
  27. package/dist/engine/safety/cross-process-lock.d.ts +1 -1
  28. package/dist/engine/safety/path-sanitizer.d.ts +1 -1
  29. package/dist/engine/security-analyzer/profile-detector.js +48 -16
  30. package/dist/engine/spec-format/copula-blacklist.d.ts +2 -2
  31. package/dist/engine/spec-format/metadata-value-policy.d.ts +20 -20
  32. package/dist/engine/text-signal-boundaries.js +45 -12
  33. package/dist/engine/universal-rules/rules/planu-modes.js +0 -2
  34. package/dist/engine/well-known/manifest-schema.d.ts +33 -33
  35. package/dist/engine/workers/schema.d.ts +3 -3
  36. package/dist/hosts/claude-code/ux/mcp-resources.d.ts +4 -4
  37. package/dist/hosts/codex/rest-shim.d.ts +1 -1
  38. package/dist/native/lightweight-command-catalog.d.ts +30 -30
  39. package/dist/server/openapi-spec.d.ts +132 -132
  40. package/dist/tools/challenge-spec/event-challenge-scenarios.js +8 -27
  41. package/dist/tools/challenge-spec/resilience-challenge-scenarios-a.js +16 -32
  42. package/dist/tools/challenge-spec/resilience-challenge-scenarios-b.js +15 -20
  43. package/dist/tools/challenge-spec/scenario-collector.d.ts +13 -0
  44. package/dist/tools/challenge-spec/scenario-collector.js +86 -0
  45. package/dist/tools/challenge-spec/scenarios-data.js +10 -9
  46. package/dist/tools/challenge-spec/scenarios-failure.js +38 -54
  47. package/dist/tools/challenge-spec/scenarios-scale.js +14 -15
  48. package/dist/tools/challenge-spec/scenarios-security.d.ts +1 -1
  49. package/dist/tools/challenge-spec/scenarios-security.js +18 -11
  50. package/dist/tools/challenge-spec/scenarios-utils.d.ts +31 -5
  51. package/dist/tools/challenge-spec/scenarios-utils.js +102 -6
  52. package/dist/tools/challenge-spec/security-challenge-scenarios.d.ts +1 -1
  53. package/dist/tools/challenge-spec/security-challenge-scenarios.js +20 -25
  54. package/dist/tools/challenge-spec.js +39 -118
  55. package/dist/tools/compliance-gate-handler.d.ts +1 -1
  56. package/dist/tools/create-spec.js +4 -24
  57. package/dist/tools/delete-first/suggest-deletions.d.ts +1 -1
  58. package/dist/tools/generate-batch-script.d.ts +2 -2
  59. package/dist/tools/init-project/rules-generator.js +0 -1
  60. package/dist/tools/oauth-handler.d.ts +1 -1
  61. package/dist/tools/register-sdd-tools.d.ts +1 -1
  62. package/dist/tools/render-spec-for-provider.d.ts +2 -2
  63. package/dist/tools/scan-orphan-spec-refs.d.ts +6 -6
  64. package/dist/tools/schemas/agents.d.ts +7 -7
  65. package/dist/tools/schemas/analysis.d.ts +11 -11
  66. package/dist/tools/schemas/delete.d.ts +5 -5
  67. package/dist/tools/schemas/github.d.ts +4 -4
  68. package/dist/tools/schemas/ide-config.d.ts +12 -12
  69. package/dist/tools/schemas/infra.d.ts +9 -9
  70. package/dist/tools/schemas/lifecycle.d.ts +50 -50
  71. package/dist/tools/schemas/llm-provider-schemas.d.ts +7 -7
  72. package/dist/tools/schemas/plugins-schemas.d.ts +12 -12
  73. package/dist/tools/schemas/project-graph.d.ts +6 -6
  74. package/dist/tools/schemas/rbac.d.ts +2 -2
  75. package/dist/tools/schemas/registry.d.ts +3 -3
  76. package/dist/tools/schemas/runtime-security.d.ts +2 -2
  77. package/dist/tools/schemas/session.d.ts +2 -2
  78. package/dist/tools/schemas/spec.d.ts +15 -15
  79. package/dist/tools/schemas/token-intelligence.d.ts +6 -6
  80. package/dist/tools/schemas/token-optimization.d.ts +2 -2
  81. package/dist/tools/schemas/workers-schema.d.ts +4 -4
  82. package/dist/tools/skill-bootstrap-handler.d.ts +7 -7
  83. package/dist/tools/tool-registry/deprecated-stubs.d.ts +1 -1
  84. package/dist/tools/triage-request.d.ts +3 -3
  85. package/dist/tools/update-status/file-sync.d.ts +1 -1
  86. package/dist/tools/update-status/file-sync.js +10 -45
  87. package/dist/tools/update-status/index.js +28 -27
  88. package/dist/tools/update-status/response-builder.d.ts +1 -1
  89. package/dist/tools/update-status/response-builder.js +11 -19
  90. package/dist/tools/update-status/transition-guard.js +1 -1
  91. package/dist/tools/update-status-actions.d.ts +0 -1
  92. package/dist/tools/update-status-actions.js +10 -26
  93. package/dist/tools/update-status-convention-gate.d.ts +1 -6
  94. package/dist/tools/update-status-convention-gate.js +9 -33
  95. package/dist/types/docs.d.ts +0 -4
  96. package/dist/types/env.d.ts +0 -4
  97. package/dist/types/estimation.d.ts +0 -2
  98. package/dist/types/multi-teammate-review.d.ts +4 -4
  99. package/dist/types/plugin-install.d.ts +7 -7
  100. package/package.json +21 -18
  101. package/planu-native.json +1 -1
  102. package/planu-plugin.json +1 -1
  103. package/src/i18n/messages/en.json +0 -72
  104. package/src/i18n/messages/es.json +0 -72
  105. package/src/i18n/messages/pt.json +0 -72
  106. package/dist/config/elicitation-dimensions.json +0 -51
  107. package/dist/engine/actuals-estimator.d.ts +0 -14
  108. package/dist/engine/actuals-estimator.js +0 -64
  109. package/dist/engine/cascade-hooks/hooks/living-specs.hook.d.ts +0 -3
  110. package/dist/engine/cascade-hooks/hooks/living-specs.hook.js +0 -19
  111. package/dist/engine/elicitation/option-builder.d.ts +0 -9
  112. package/dist/engine/elicitation/option-builder.js +0 -85
  113. package/dist/engine/progress-writer.d.ts +0 -10
  114. package/dist/engine/progress-writer.js +0 -63
  115. package/dist/tools/update-status/mode-hints.d.ts +0 -4
  116. package/dist/tools/update-status/mode-hints.js +0 -24
@@ -4,50 +4,50 @@
4
4
  * SPEC-610: Planu HTTP API — OpenAPI document for LLM function calling
5
5
  */
6
6
  export declare const OPENAPI_SPEC: {
7
- readonly openapi: "3.1.0";
7
+ readonly openapi: '3.1.0';
8
8
  readonly info: {
9
- readonly title: "Planu HTTP API";
10
- readonly version: "1.0.0";
11
- readonly description: "Planu Spec Driven Development HTTP API — transport-agnostic access to Planu engine";
9
+ readonly title: 'Planu HTTP API';
10
+ readonly version: '1.0.0';
11
+ readonly description: 'Planu Spec Driven Development HTTP API — transport-agnostic access to Planu engine';
12
12
  };
13
13
  readonly servers: readonly [{
14
- readonly url: "http://localhost:3000";
15
- readonly description: "Local development server";
14
+ readonly url: 'http://localhost:3000';
15
+ readonly description: 'Local development server';
16
16
  }];
17
17
  readonly paths: {
18
18
  readonly '/api/health': {
19
19
  readonly get: {
20
- readonly operationId: "getHealth";
21
- readonly summary: "Health check";
22
- readonly description: "Returns server status and version information";
20
+ readonly operationId: 'getHealth';
21
+ readonly summary: 'Health check';
22
+ readonly description: 'Returns server status and version information';
23
23
  readonly responses: {
24
24
  readonly '200': {
25
- readonly description: "Server is healthy";
25
+ readonly description: 'Server is healthy';
26
26
  readonly content: {
27
27
  readonly 'application/json': {
28
28
  readonly schema: {
29
- readonly type: "object";
29
+ readonly type: 'object';
30
30
  readonly properties: {
31
31
  readonly data: {
32
- readonly type: "object";
32
+ readonly type: 'object';
33
33
  readonly properties: {
34
34
  readonly status: {
35
- readonly type: "string";
36
- readonly example: "ok";
35
+ readonly type: 'string';
36
+ readonly example: 'ok';
37
37
  };
38
38
  readonly version: {
39
- readonly type: "string";
40
- readonly example: "1.0.0";
39
+ readonly type: 'string';
40
+ readonly example: '1.0.0';
41
41
  };
42
42
  readonly uptime: {
43
- readonly type: "number";
44
- readonly description: "Process uptime in seconds";
43
+ readonly type: 'number';
44
+ readonly description: 'Process uptime in seconds';
45
45
  };
46
46
  };
47
- readonly required: readonly ["status", "version", "uptime"];
47
+ readonly required: readonly ['status', 'version', 'uptime'];
48
48
  };
49
49
  readonly error: {
50
- readonly type: "null";
50
+ readonly type: 'null';
51
51
  };
52
52
  };
53
53
  };
@@ -59,35 +59,35 @@ export declare const OPENAPI_SPEC: {
59
59
  };
60
60
  readonly '/api/specs': {
61
61
  readonly get: {
62
- readonly operationId: "listSpecs";
63
- readonly summary: "List specs";
64
- readonly description: "Returns all specs, optionally filtered by status";
62
+ readonly operationId: 'listSpecs';
63
+ readonly summary: 'List specs';
64
+ readonly description: 'Returns all specs, optionally filtered by status';
65
65
  readonly parameters: readonly [{
66
- readonly name: "status";
67
- readonly in: "query";
68
- readonly description: "Filter by spec status. Valid values: draft, review, approved, implementing, done, discarded";
66
+ readonly name: 'status';
67
+ readonly in: 'query';
68
+ readonly description: 'Filter by spec status. Valid values: draft, review, approved, implementing, done, discarded';
69
69
  readonly required: false;
70
70
  readonly schema: {
71
- readonly type: "string";
72
- readonly enum: readonly ["draft", "review", "approved", "implementing", "done", "discarded"];
71
+ readonly type: 'string';
72
+ readonly enum: readonly ['draft', 'review', 'approved', 'implementing', 'done', 'discarded'];
73
73
  };
74
74
  }];
75
75
  readonly responses: {
76
76
  readonly '200': {
77
- readonly description: "List of specs";
77
+ readonly description: 'List of specs';
78
78
  readonly content: {
79
79
  readonly 'application/json': {
80
80
  readonly schema: {
81
- readonly type: "object";
81
+ readonly type: 'object';
82
82
  readonly properties: {
83
83
  readonly data: {
84
- readonly type: "array";
84
+ readonly type: 'array';
85
85
  readonly items: {
86
- readonly $ref: "#/components/schemas/Spec";
86
+ readonly $ref: '#/components/schemas/Spec';
87
87
  };
88
88
  };
89
89
  readonly error: {
90
- readonly type: "null";
90
+ readonly type: 'null';
91
91
  };
92
92
  };
93
93
  };
@@ -97,43 +97,43 @@ export declare const OPENAPI_SPEC: {
97
97
  };
98
98
  };
99
99
  readonly post: {
100
- readonly operationId: "createSpec";
101
- readonly summary: "Create a spec";
102
- readonly description: "Creates a new spec with the given title and description";
100
+ readonly operationId: 'createSpec';
101
+ readonly summary: 'Create a spec';
102
+ readonly description: 'Creates a new spec with the given title and description';
103
103
  readonly requestBody: {
104
104
  readonly required: true;
105
105
  readonly content: {
106
106
  readonly 'application/json': {
107
107
  readonly schema: {
108
- readonly type: "object";
108
+ readonly type: 'object';
109
109
  readonly properties: {
110
110
  readonly title: {
111
- readonly type: "string";
112
- readonly description: "Spec title";
111
+ readonly type: 'string';
112
+ readonly description: 'Spec title';
113
113
  };
114
114
  readonly description: {
115
- readonly type: "string";
116
- readonly description: "Spec description / requirements";
115
+ readonly type: 'string';
116
+ readonly description: 'Spec description / requirements';
117
117
  };
118
118
  };
119
- readonly required: readonly ["title", "description"];
119
+ readonly required: readonly ['title', 'description'];
120
120
  };
121
121
  };
122
122
  };
123
123
  };
124
124
  readonly responses: {
125
125
  readonly '201': {
126
- readonly description: "Spec created";
126
+ readonly description: 'Spec created';
127
127
  readonly content: {
128
128
  readonly 'application/json': {
129
129
  readonly schema: {
130
- readonly type: "object";
130
+ readonly type: 'object';
131
131
  readonly properties: {
132
132
  readonly data: {
133
- readonly $ref: "#/components/schemas/Spec";
133
+ readonly $ref: '#/components/schemas/Spec';
134
134
  };
135
135
  readonly error: {
136
- readonly type: "null";
136
+ readonly type: 'null';
137
137
  };
138
138
  };
139
139
  };
@@ -141,38 +141,38 @@ export declare const OPENAPI_SPEC: {
141
141
  };
142
142
  };
143
143
  readonly '400': {
144
- readonly $ref: "#/components/responses/BadRequest";
144
+ readonly $ref: '#/components/responses/BadRequest';
145
145
  };
146
146
  };
147
147
  };
148
148
  };
149
149
  readonly '/api/specs/{id}': {
150
150
  readonly get: {
151
- readonly operationId: "getSpec";
152
- readonly summary: "Get spec details";
153
- readonly description: "Returns a single spec by ID";
151
+ readonly operationId: 'getSpec';
152
+ readonly summary: 'Get spec details';
153
+ readonly description: 'Returns a single spec by ID';
154
154
  readonly parameters: readonly [{
155
- readonly name: "id";
156
- readonly in: "path";
155
+ readonly name: 'id';
156
+ readonly in: 'path';
157
157
  readonly required: true;
158
158
  readonly schema: {
159
- readonly type: "string";
160
- readonly example: "SPEC-001";
159
+ readonly type: 'string';
160
+ readonly example: 'SPEC-001';
161
161
  };
162
162
  }];
163
163
  readonly responses: {
164
164
  readonly '200': {
165
- readonly description: "Spec details";
165
+ readonly description: 'Spec details';
166
166
  readonly content: {
167
167
  readonly 'application/json': {
168
168
  readonly schema: {
169
- readonly type: "object";
169
+ readonly type: 'object';
170
170
  readonly properties: {
171
171
  readonly data: {
172
- readonly $ref: "#/components/schemas/Spec";
172
+ readonly $ref: '#/components/schemas/Spec';
173
173
  };
174
174
  readonly error: {
175
- readonly type: "null";
175
+ readonly type: 'null';
176
176
  };
177
177
  };
178
178
  };
@@ -180,23 +180,23 @@ export declare const OPENAPI_SPEC: {
180
180
  };
181
181
  };
182
182
  readonly '404': {
183
- readonly $ref: "#/components/responses/NotFound";
183
+ readonly $ref: '#/components/responses/NotFound';
184
184
  };
185
185
  };
186
186
  };
187
187
  };
188
188
  readonly '/api/specs/{id}/status': {
189
189
  readonly patch: {
190
- readonly operationId: "updateSpecStatus";
191
- readonly summary: "Update spec status";
192
- readonly description: "Transitions a spec to a new status";
190
+ readonly operationId: 'updateSpecStatus';
191
+ readonly summary: 'Update spec status';
192
+ readonly description: 'Transitions a spec to a new status';
193
193
  readonly parameters: readonly [{
194
- readonly name: "id";
195
- readonly in: "path";
194
+ readonly name: 'id';
195
+ readonly in: 'path';
196
196
  readonly required: true;
197
197
  readonly schema: {
198
- readonly type: "string";
199
- readonly example: "SPEC-001";
198
+ readonly type: 'string';
199
+ readonly example: 'SPEC-001';
200
200
  };
201
201
  }];
202
202
  readonly requestBody: {
@@ -204,32 +204,32 @@ export declare const OPENAPI_SPEC: {
204
204
  readonly content: {
205
205
  readonly 'application/json': {
206
206
  readonly schema: {
207
- readonly type: "object";
207
+ readonly type: 'object';
208
208
  readonly properties: {
209
209
  readonly status: {
210
- readonly type: "string";
211
- readonly enum: readonly ["draft", "review", "approved", "implementing", "done", "discarded"];
212
- readonly description: "New status. Valid values: draft, review, approved, implementing, done, discarded";
210
+ readonly type: 'string';
211
+ readonly enum: readonly ['draft', 'review', 'approved', 'implementing', 'done', 'discarded'];
212
+ readonly description: 'New status. Valid values: draft, review, approved, implementing, done, discarded';
213
213
  };
214
214
  };
215
- readonly required: readonly ["status"];
215
+ readonly required: readonly ['status'];
216
216
  };
217
217
  };
218
218
  };
219
219
  };
220
220
  readonly responses: {
221
221
  readonly '200': {
222
- readonly description: "Spec status updated";
222
+ readonly description: 'Spec status updated';
223
223
  readonly content: {
224
224
  readonly 'application/json': {
225
225
  readonly schema: {
226
- readonly type: "object";
226
+ readonly type: 'object';
227
227
  readonly properties: {
228
228
  readonly data: {
229
- readonly $ref: "#/components/schemas/Spec";
229
+ readonly $ref: '#/components/schemas/Spec';
230
230
  };
231
231
  readonly error: {
232
- readonly type: "null";
232
+ readonly type: 'null';
233
233
  };
234
234
  };
235
235
  };
@@ -237,58 +237,58 @@ export declare const OPENAPI_SPEC: {
237
237
  };
238
238
  };
239
239
  readonly '400': {
240
- readonly $ref: "#/components/responses/BadRequest";
240
+ readonly $ref: '#/components/responses/BadRequest';
241
241
  };
242
242
  readonly '404': {
243
- readonly $ref: "#/components/responses/NotFound";
243
+ readonly $ref: '#/components/responses/NotFound';
244
244
  };
245
245
  };
246
246
  };
247
247
  };
248
248
  readonly '/api/specs/{id}/validate': {
249
249
  readonly post: {
250
- readonly operationId: "validateSpec";
251
- readonly summary: "Validate a spec";
252
- readonly description: "Runs readiness and quality checks on a spec";
250
+ readonly operationId: 'validateSpec';
251
+ readonly summary: 'Validate a spec';
252
+ readonly description: 'Runs readiness and quality checks on a spec';
253
253
  readonly parameters: readonly [{
254
- readonly name: "id";
255
- readonly in: "path";
254
+ readonly name: 'id';
255
+ readonly in: 'path';
256
256
  readonly required: true;
257
257
  readonly schema: {
258
- readonly type: "string";
259
- readonly example: "SPEC-001";
258
+ readonly type: 'string';
259
+ readonly example: 'SPEC-001';
260
260
  };
261
261
  }];
262
262
  readonly responses: {
263
263
  readonly '200': {
264
- readonly description: "Validation results";
264
+ readonly description: 'Validation results';
265
265
  readonly content: {
266
266
  readonly 'application/json': {
267
267
  readonly schema: {
268
- readonly type: "object";
268
+ readonly type: 'object';
269
269
  readonly properties: {
270
270
  readonly data: {
271
- readonly type: "object";
271
+ readonly type: 'object';
272
272
  readonly properties: {
273
273
  readonly specId: {
274
- readonly type: "string";
274
+ readonly type: 'string';
275
275
  };
276
276
  readonly ready: {
277
- readonly type: "boolean";
277
+ readonly type: 'boolean';
278
278
  };
279
279
  readonly score: {
280
- readonly type: "number";
280
+ readonly type: 'number';
281
281
  };
282
282
  readonly issues: {
283
- readonly type: "array";
283
+ readonly type: 'array';
284
284
  readonly items: {
285
- readonly type: "string";
285
+ readonly type: 'string';
286
286
  };
287
287
  };
288
288
  };
289
289
  };
290
290
  readonly error: {
291
- readonly type: "null";
291
+ readonly type: 'null';
292
292
  };
293
293
  };
294
294
  };
@@ -296,23 +296,23 @@ export declare const OPENAPI_SPEC: {
296
296
  };
297
297
  };
298
298
  readonly '404': {
299
- readonly $ref: "#/components/responses/NotFound";
299
+ readonly $ref: '#/components/responses/NotFound';
300
300
  };
301
301
  };
302
302
  };
303
303
  };
304
304
  readonly '/api/openapi.json': {
305
305
  readonly get: {
306
- readonly operationId: "getOpenApiSpec";
307
- readonly summary: "OpenAPI specification";
308
- readonly description: "Returns this OpenAPI document for LLM function calling";
306
+ readonly operationId: 'getOpenApiSpec';
307
+ readonly summary: 'OpenAPI specification';
308
+ readonly description: 'Returns this OpenAPI document for LLM function calling';
309
309
  readonly responses: {
310
310
  readonly '200': {
311
- readonly description: "OpenAPI spec";
311
+ readonly description: 'OpenAPI spec';
312
312
  readonly content: {
313
313
  readonly 'application/json': {
314
314
  readonly schema: {
315
- readonly type: "object";
315
+ readonly type: 'object';
316
316
  };
317
317
  };
318
318
  };
@@ -324,74 +324,74 @@ export declare const OPENAPI_SPEC: {
324
324
  readonly components: {
325
325
  readonly schemas: {
326
326
  readonly Spec: {
327
- readonly type: "object";
327
+ readonly type: 'object';
328
328
  readonly properties: {
329
329
  readonly id: {
330
- readonly type: "string";
331
- readonly example: "SPEC-001";
330
+ readonly type: 'string';
331
+ readonly example: 'SPEC-001';
332
332
  };
333
333
  readonly title: {
334
- readonly type: "string";
334
+ readonly type: 'string';
335
335
  };
336
336
  readonly status: {
337
- readonly type: "string";
338
- readonly enum: readonly ["draft", "review", "approved", "implementing", "done", "discarded"];
337
+ readonly type: 'string';
338
+ readonly enum: readonly ['draft', 'review', 'approved', 'implementing', 'done', 'discarded'];
339
339
  };
340
340
  readonly type: {
341
- readonly type: "string";
341
+ readonly type: 'string';
342
342
  };
343
343
  readonly scope: {
344
- readonly type: "string";
344
+ readonly type: 'string';
345
345
  };
346
346
  readonly difficulty: {
347
- readonly type: "string";
347
+ readonly type: 'string';
348
348
  };
349
349
  readonly risk: {
350
- readonly type: "string";
350
+ readonly type: 'string';
351
351
  };
352
352
  readonly tags: {
353
- readonly type: "array";
353
+ readonly type: 'array';
354
354
  readonly items: {
355
- readonly type: "string";
355
+ readonly type: 'string';
356
356
  };
357
357
  };
358
358
  readonly createdAt: {
359
- readonly type: "string";
360
- readonly format: "date-time";
359
+ readonly type: 'string';
360
+ readonly format: 'date-time';
361
361
  };
362
362
  readonly updatedAt: {
363
- readonly type: "string";
364
- readonly format: "date-time";
363
+ readonly type: 'string';
364
+ readonly format: 'date-time';
365
365
  };
366
366
  };
367
- readonly required: readonly ["id", "title", "status"];
367
+ readonly required: readonly ['id', 'title', 'status'];
368
368
  };
369
369
  readonly ApiError: {
370
- readonly type: "object";
370
+ readonly type: 'object';
371
371
  readonly properties: {
372
372
  readonly message: {
373
- readonly type: "string";
373
+ readonly type: 'string';
374
374
  };
375
375
  readonly code: {
376
- readonly type: "string";
376
+ readonly type: 'string';
377
377
  };
378
378
  };
379
- readonly required: readonly ["message", "code"];
379
+ readonly required: readonly ['message', 'code'];
380
380
  };
381
381
  };
382
382
  readonly responses: {
383
383
  readonly BadRequest: {
384
- readonly description: "Bad request — validation error";
384
+ readonly description: 'Bad request — validation error';
385
385
  readonly content: {
386
386
  readonly 'application/json': {
387
387
  readonly schema: {
388
- readonly type: "object";
388
+ readonly type: 'object';
389
389
  readonly properties: {
390
390
  readonly data: {
391
- readonly type: "null";
391
+ readonly type: 'null';
392
392
  };
393
393
  readonly error: {
394
- readonly $ref: "#/components/schemas/ApiError";
394
+ readonly $ref: '#/components/schemas/ApiError';
395
395
  };
396
396
  };
397
397
  };
@@ -399,17 +399,17 @@ export declare const OPENAPI_SPEC: {
399
399
  };
400
400
  };
401
401
  readonly NotFound: {
402
- readonly description: "Resource not found";
402
+ readonly description: 'Resource not found';
403
403
  readonly content: {
404
404
  readonly 'application/json': {
405
405
  readonly schema: {
406
- readonly type: "object";
406
+ readonly type: 'object';
407
407
  readonly properties: {
408
408
  readonly data: {
409
- readonly type: "null";
409
+ readonly type: 'null';
410
410
  };
411
411
  readonly error: {
412
- readonly $ref: "#/components/schemas/ApiError";
412
+ readonly $ref: '#/components/schemas/ApiError';
413
413
  };
414
414
  };
415
415
  };
@@ -417,17 +417,17 @@ export declare const OPENAPI_SPEC: {
417
417
  };
418
418
  };
419
419
  readonly InternalError: {
420
- readonly description: "Internal server error";
420
+ readonly description: 'Internal server error';
421
421
  readonly content: {
422
422
  readonly 'application/json': {
423
423
  readonly schema: {
424
- readonly type: "object";
424
+ readonly type: 'object';
425
425
  readonly properties: {
426
426
  readonly data: {
427
- readonly type: "null";
427
+ readonly type: 'null';
428
428
  };
429
429
  readonly error: {
430
- readonly $ref: "#/components/schemas/ApiError";
430
+ readonly $ref: '#/components/schemas/ApiError';
431
431
  };
432
432
  };
433
433
  };
@@ -2,30 +2,13 @@
2
2
  // Generates backward-compatibility contract and idempotence challenges
3
3
  // for specs that produce or consume events.
4
4
  import { detectBrokers, getBrokerConfig, requiresIdempotence, } from '../../engine/event-detector.js';
5
+ import { detectChallengeCapabilities } from './scenarios-utils.js';
5
6
  /**
6
7
  * Returns true when the spec or project has event-driven characteristics.
7
8
  */
8
9
  export function isEventDrivenSpec(spec, specContent, knowledge) {
9
- const lower = `${spec.title} ${spec.tags.join(' ')} ${specContent}`.toLowerCase();
10
- const specSignals = lower.includes('event') ||
11
- lower.includes('kafka') ||
12
- lower.includes('rabbitmq') ||
13
- lower.includes('pubsub') ||
14
- lower.includes('nats') ||
15
- lower.includes('eventbridge') ||
16
- lower.includes('sqs') ||
17
- lower.includes('sns') ||
18
- lower.includes('message') ||
19
- lower.includes('consumer') ||
20
- lower.includes('producer');
21
- if (spec.target === 'frontend' && !specSignals) {
22
- return false;
23
- }
24
- const brokers = detectBrokers(knowledge.stack);
25
- if (specSignals) {
26
- return true;
27
- }
28
- return brokers.length > 0 && brokers[0] !== 'unknown' && spec.target !== 'frontend';
10
+ void knowledge;
11
+ return detectChallengeCapabilities(spec, specContent).events;
29
12
  }
30
13
  /**
31
14
  * Generate event-driven failure scenarios for challenge_spec.
@@ -50,7 +33,7 @@ export function generateEventChallengeScenarios(spec, specContent, knowledge) {
50
33
  impact: 'critical',
51
34
  currentHandling: 'Schema change may not have a formal contract review — consumers may fail silently with unrecognized fields or crash on missing ones.',
52
35
  requiredHandling: 'Classify the change: additive (new optional field — safe), breaking (removed/type-changed field — requires dual-version emission), or deprecation (field marked deprecated with a sunset date). ' +
53
- 'For breaking changes: emit both old and new versions during the transition period (recommended: 2-4 weeks). ' +
36
+ 'For breaking changes: emit both old and new versions during the transition period defined by the rollout plan. ' +
54
37
  'Update the event contract in event-contracts/ before merging.',
55
38
  dataConsistency: 'If the change is breaking and dual-version is not implemented, consumers will receive invalid events and may write corrupt state.',
56
39
  userExperience: 'Invisible to end users, but breaking event changes cause downstream service failures that eventually surface as user-facing errors.',
@@ -62,9 +45,7 @@ export function generateEventChallengeScenarios(spec, specContent, knowledge) {
62
45
  probability: 'high',
63
46
  impact: 'high',
64
47
  currentHandling: 'Consumer may lack a deduplication check — processing the same event twice could double-charge, double-ship, or create duplicate records.',
65
- requiredHandling: 'Store the event ID (or a derived idempotency key) in a durable store (DB, Redis with TTL) before processing. ' +
66
- 'Check at the start of each consumer handler: if ID already processed, acknowledge and skip. ' +
67
- 'Choose the deduplication window based on expected redelivery window (typically 24h–7d).',
48
+ requiredHandling: 'Define the deduplication identifier, durable boundary, atomicity rule, and retention window from the event contract.',
68
49
  dataConsistency: 'The idempotency record must be written atomically with the side-effect (same DB transaction or two-phase commit) to avoid the "processed but not recorded" gap.',
69
50
  userExperience: 'Idempotence failure is invisible until users report duplicates (duplicate orders, double payments, etc.) — prevent, do not detect.',
70
51
  });
@@ -72,13 +53,13 @@ export function generateEventChallengeScenarios(spec, specContent, knowledge) {
72
53
  // 3. DLQ poisoned message challenge
73
54
  if (brokerConfig?.dlqSupport && brokerConfig.dlqSupport !== '') {
74
55
  scenarios.push({
75
- scenario: `[${spec.id}] DLQ Poisoned Message: a consumer receives an event with a malformed payload (missing required field, wrong type, corrupt JSON). Does the consumer retry forever and block the queue? How many retries before the message goes to the DLQ?`,
56
+ scenario: `[${spec.id}] DLQ Poisoned Message: a consumer receives an event with a malformed payload. Does the consumer retry indefinitely and block the queue? Which declared failure condition moves the message to the DLQ?`,
76
57
  probability: 'medium',
77
58
  impact: 'high',
78
59
  currentHandling: 'Consumer may retry indefinitely on schema validation errors, blocking queue processing for all subsequent events.',
79
- requiredHandling: 'Implement retry with exponential backoff (e.g., 1s, 2s, 4s, 8s, 16s). After max retries (e.g., 5), route to DLQ with original payload + error context. ' +
60
+ requiredHandling: 'Use the retry limit and delay policy declared by the event contract, then route terminal failures with enough diagnostic context. ' +
80
61
  `DLQ support: ${brokerConfig.dlqSupport}. ` +
81
- 'Set an alert when DLQ depth exceeds threshold. Document the re-injection procedure for manual recovery.',
62
+ 'Define the alert threshold and re-injection procedure from the operations contract.',
82
63
  dataConsistency: 'Messages in the DLQ must be investigated and re-injected only after the root cause is fixed — re-injecting without fix will loop back to DLQ.',
83
64
  userExperience: 'DLQ accumulation means events are not processed — monitor and alert before SLA is breached.',
84
65
  });