@substrate-ai/sdlc 0.19.54

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 (166) hide show
  1. package/dist/events.d.ts +336 -0
  2. package/dist/events.d.ts.map +1 -0
  3. package/dist/events.js +11 -0
  4. package/dist/events.js.map +1 -0
  5. package/dist/gating/conflict-detector.d.ts +59 -0
  6. package/dist/gating/conflict-detector.d.ts.map +1 -0
  7. package/dist/gating/conflict-detector.js +101 -0
  8. package/dist/gating/conflict-detector.js.map +1 -0
  9. package/dist/gating/dispatch-gate.d.ts +42 -0
  10. package/dist/gating/dispatch-gate.d.ts.map +1 -0
  11. package/dist/gating/dispatch-gate.js +197 -0
  12. package/dist/gating/dispatch-gate.js.map +1 -0
  13. package/dist/gating/index.d.ts +9 -0
  14. package/dist/gating/index.d.ts.map +1 -0
  15. package/dist/gating/index.js +8 -0
  16. package/dist/gating/index.js.map +1 -0
  17. package/dist/gating/types.d.ts +98 -0
  18. package/dist/gating/types.d.ts.map +1 -0
  19. package/dist/gating/types.js +8 -0
  20. package/dist/gating/types.js.map +1 -0
  21. package/dist/handlers/event-bridge.d.ts +56 -0
  22. package/dist/handlers/event-bridge.d.ts.map +1 -0
  23. package/dist/handlers/event-bridge.js +140 -0
  24. package/dist/handlers/event-bridge.js.map +1 -0
  25. package/dist/handlers/index.d.ts +15 -0
  26. package/dist/handlers/index.d.ts.map +1 -0
  27. package/dist/handlers/index.js +14 -0
  28. package/dist/handlers/index.js.map +1 -0
  29. package/dist/handlers/sdlc-code-review-handler.d.ts +119 -0
  30. package/dist/handlers/sdlc-code-review-handler.d.ts.map +1 -0
  31. package/dist/handlers/sdlc-code-review-handler.js +131 -0
  32. package/dist/handlers/sdlc-code-review-handler.js.map +1 -0
  33. package/dist/handlers/sdlc-create-story-handler.d.ts +97 -0
  34. package/dist/handlers/sdlc-create-story-handler.d.ts.map +1 -0
  35. package/dist/handlers/sdlc-create-story-handler.js +91 -0
  36. package/dist/handlers/sdlc-create-story-handler.js.map +1 -0
  37. package/dist/handlers/sdlc-dev-story-handler.d.ts +121 -0
  38. package/dist/handlers/sdlc-dev-story-handler.d.ts.map +1 -0
  39. package/dist/handlers/sdlc-dev-story-handler.js +288 -0
  40. package/dist/handlers/sdlc-dev-story-handler.js.map +1 -0
  41. package/dist/handlers/sdlc-phase-handler.d.ts +32 -0
  42. package/dist/handlers/sdlc-phase-handler.d.ts.map +1 -0
  43. package/dist/handlers/sdlc-phase-handler.js +166 -0
  44. package/dist/handlers/sdlc-phase-handler.js.map +1 -0
  45. package/dist/handlers/types.d.ts +132 -0
  46. package/dist/handlers/types.d.ts.map +1 -0
  47. package/dist/handlers/types.js +10 -0
  48. package/dist/handlers/types.js.map +1 -0
  49. package/dist/index.d.ts +8 -0
  50. package/dist/index.d.ts.map +1 -0
  51. package/dist/index.js +14 -0
  52. package/dist/index.js.map +1 -0
  53. package/dist/learning/failure-classifier.d.ts +23 -0
  54. package/dist/learning/failure-classifier.d.ts.map +1 -0
  55. package/dist/learning/failure-classifier.js +75 -0
  56. package/dist/learning/failure-classifier.js.map +1 -0
  57. package/dist/learning/finding-classifier.d.ts +25 -0
  58. package/dist/learning/finding-classifier.d.ts.map +1 -0
  59. package/dist/learning/finding-classifier.js +37 -0
  60. package/dist/learning/finding-classifier.js.map +1 -0
  61. package/dist/learning/finding-lifecycle.d.ts +69 -0
  62. package/dist/learning/finding-lifecycle.d.ts.map +1 -0
  63. package/dist/learning/finding-lifecycle.js +162 -0
  64. package/dist/learning/finding-lifecycle.js.map +1 -0
  65. package/dist/learning/finding-store.d.ts +16 -0
  66. package/dist/learning/finding-store.d.ts.map +1 -0
  67. package/dist/learning/finding-store.js +26 -0
  68. package/dist/learning/finding-store.js.map +1 -0
  69. package/dist/learning/findings-injector.d.ts +34 -0
  70. package/dist/learning/findings-injector.d.ts.map +1 -0
  71. package/dist/learning/findings-injector.js +140 -0
  72. package/dist/learning/findings-injector.js.map +1 -0
  73. package/dist/learning/index.d.ts +8 -0
  74. package/dist/learning/index.d.ts.map +1 -0
  75. package/dist/learning/index.js +10 -0
  76. package/dist/learning/index.js.map +1 -0
  77. package/dist/learning/relevance-scorer.d.ts +25 -0
  78. package/dist/learning/relevance-scorer.d.ts.map +1 -0
  79. package/dist/learning/relevance-scorer.js +49 -0
  80. package/dist/learning/relevance-scorer.js.map +1 -0
  81. package/dist/learning/types.d.ts +55 -0
  82. package/dist/learning/types.d.ts.map +1 -0
  83. package/dist/learning/types.js +36 -0
  84. package/dist/learning/types.js.map +1 -0
  85. package/dist/orchestrator/graph-orchestrator.d.ts +208 -0
  86. package/dist/orchestrator/graph-orchestrator.d.ts.map +1 -0
  87. package/dist/orchestrator/graph-orchestrator.js +213 -0
  88. package/dist/orchestrator/graph-orchestrator.js.map +1 -0
  89. package/dist/run-manifest/cli-flags.d.ts +11 -0
  90. package/dist/run-manifest/cli-flags.d.ts.map +1 -0
  91. package/dist/run-manifest/cli-flags.js +10 -0
  92. package/dist/run-manifest/cli-flags.js.map +1 -0
  93. package/dist/run-manifest/index.d.ts +10 -0
  94. package/dist/run-manifest/index.d.ts.map +1 -0
  95. package/dist/run-manifest/index.js +10 -0
  96. package/dist/run-manifest/index.js.map +1 -0
  97. package/dist/run-model/cli-flags.d.ts +27 -0
  98. package/dist/run-model/cli-flags.d.ts.map +1 -0
  99. package/dist/run-model/cli-flags.js +31 -0
  100. package/dist/run-model/cli-flags.js.map +1 -0
  101. package/dist/run-model/index.d.ts +21 -0
  102. package/dist/run-model/index.d.ts.map +1 -0
  103. package/dist/run-model/index.js +19 -0
  104. package/dist/run-model/index.js.map +1 -0
  105. package/dist/run-model/per-story-state.d.ts +62 -0
  106. package/dist/run-model/per-story-state.d.ts.map +1 -0
  107. package/dist/run-model/per-story-state.js +70 -0
  108. package/dist/run-model/per-story-state.js.map +1 -0
  109. package/dist/run-model/recovery-history.d.ts +56 -0
  110. package/dist/run-model/recovery-history.d.ts.map +1 -0
  111. package/dist/run-model/recovery-history.js +83 -0
  112. package/dist/run-model/recovery-history.js.map +1 -0
  113. package/dist/run-model/run-manifest.d.ts +146 -0
  114. package/dist/run-model/run-manifest.d.ts.map +1 -0
  115. package/dist/run-model/run-manifest.js +481 -0
  116. package/dist/run-model/run-manifest.js.map +1 -0
  117. package/dist/run-model/schemas.d.ts +117 -0
  118. package/dist/run-model/schemas.d.ts.map +1 -0
  119. package/dist/run-model/schemas.js +83 -0
  120. package/dist/run-model/schemas.js.map +1 -0
  121. package/dist/run-model/supervisor-lock.d.ts +104 -0
  122. package/dist/run-model/supervisor-lock.d.ts.map +1 -0
  123. package/dist/run-model/supervisor-lock.js +284 -0
  124. package/dist/run-model/supervisor-lock.js.map +1 -0
  125. package/dist/run-model/types.d.ts +74 -0
  126. package/dist/run-model/types.d.ts.map +1 -0
  127. package/dist/run-model/types.js +8 -0
  128. package/dist/run-model/types.js.map +1 -0
  129. package/dist/run-model/verification-result.d.ts +60 -0
  130. package/dist/run-model/verification-result.d.ts.map +1 -0
  131. package/dist/run-model/verification-result.js +55 -0
  132. package/dist/run-model/verification-result.js.map +1 -0
  133. package/dist/verification/checks/acceptance-criteria-evidence-check.d.ts +21 -0
  134. package/dist/verification/checks/acceptance-criteria-evidence-check.d.ts.map +1 -0
  135. package/dist/verification/checks/acceptance-criteria-evidence-check.js +159 -0
  136. package/dist/verification/checks/acceptance-criteria-evidence-check.js.map +1 -0
  137. package/dist/verification/checks/build-check.d.ts +52 -0
  138. package/dist/verification/checks/build-check.d.ts.map +1 -0
  139. package/dist/verification/checks/build-check.js +160 -0
  140. package/dist/verification/checks/build-check.js.map +1 -0
  141. package/dist/verification/checks/index.d.ts +15 -0
  142. package/dist/verification/checks/index.d.ts.map +1 -0
  143. package/dist/verification/checks/index.js +15 -0
  144. package/dist/verification/checks/index.js.map +1 -0
  145. package/dist/verification/checks/phantom-review-check.d.ts +29 -0
  146. package/dist/verification/checks/phantom-review-check.d.ts.map +1 -0
  147. package/dist/verification/checks/phantom-review-check.js +70 -0
  148. package/dist/verification/checks/phantom-review-check.js.map +1 -0
  149. package/dist/verification/checks/trivial-output-check.d.ts +47 -0
  150. package/dist/verification/checks/trivial-output-check.d.ts.map +1 -0
  151. package/dist/verification/checks/trivial-output-check.js +72 -0
  152. package/dist/verification/checks/trivial-output-check.js.map +1 -0
  153. package/dist/verification/index.d.ts +13 -0
  154. package/dist/verification/index.d.ts.map +1 -0
  155. package/dist/verification/index.js +13 -0
  156. package/dist/verification/index.js.map +1 -0
  157. package/dist/verification/types.d.ts +149 -0
  158. package/dist/verification/types.d.ts.map +1 -0
  159. package/dist/verification/types.js +12 -0
  160. package/dist/verification/types.js.map +1 -0
  161. package/dist/verification/verification-pipeline.d.ts +65 -0
  162. package/dist/verification/verification-pipeline.d.ts.map +1 -0
  163. package/dist/verification/verification-pipeline.js +149 -0
  164. package/dist/verification/verification-pipeline.js.map +1 -0
  165. package/graphs/sdlc-pipeline.dot +42 -0
  166. package/package.json +22 -0
@@ -0,0 +1,288 @@
1
+ /**
2
+ * SdlcDevStoryHandler — wraps the runDevStory compiled workflow
3
+ * as a graph NodeHandler for sdlc.dev-story nodes.
4
+ *
5
+ * Story 43-4.
6
+ *
7
+ * Architecture note (ADR-003): The SDLC package does not compile-time-depend on
8
+ * @substrate-ai/factory to avoid circular references. Compatible types are
9
+ * defined locally using TypeScript structural typing — they are assignable to
10
+ * the factory types when the CLI composition root wires them together at runtime.
11
+ */
12
+ import { readFileSync } from 'node:fs';
13
+ import { classifyAndPersist } from '../learning/finding-classifier.js';
14
+ import { FindingsInjector, extractTargetFilesFromStoryContent } from '../learning/findings-injector.js';
15
+ import { FindingLifecycleManager } from '../learning/finding-lifecycle.js';
16
+ import { DispatchGate } from '../gating/dispatch-gate.js';
17
+ // ---------------------------------------------------------------------------
18
+ // Factory
19
+ // ---------------------------------------------------------------------------
20
+ /**
21
+ * Create an sdlc.dev-story node handler.
22
+ *
23
+ * The returned handler:
24
+ * 1. Validates storyKey and storyFilePath are present in GraphContext (AC6)
25
+ * 2. Reads optional retry remediation context from prior iteration (AC4)
26
+ * 3. Injects relevant prior-run findings into dispatch params (Story 53-8 AC2)
27
+ * 4. Emits orchestrator:story-phase-start telemetry (AC5)
28
+ * 5. Delegates to runDevStory(deps, params) (AC1)
29
+ * 6. Emits orchestrator:story-phase-complete telemetry in finally block (AC5)
30
+ * 7. Maps the DevStoryResult to an Outcome (AC2, AC3)
31
+ * 8. On failure: classifyAndPersist + emit pipeline:finding-captured (Story 53-8 AC1, AC6)
32
+ * 9. On success: retireContradictedFindings (Story 53-8 AC4)
33
+ *
34
+ * @param options - Handler configuration.
35
+ * @returns A NodeHandler function ready for registration under the 'sdlc.dev-story' key.
36
+ */
37
+ export function createSdlcDevStoryHandler(options) {
38
+ return async (_node, context, _graph) => {
39
+ // AC6: Validate required context keys before calling runDevStory
40
+ const storyKey = context.getString('storyKey', '');
41
+ const storyFilePath = context.getString('storyFilePath', '');
42
+ if (!storyKey || !storyFilePath) {
43
+ const missingFields = [
44
+ !storyKey && 'storyKey',
45
+ !storyFilePath && 'storyFilePath',
46
+ ].filter(Boolean);
47
+ return {
48
+ status: 'FAILURE',
49
+ failureReason: `Missing required context: ${missingFields.join(', ')}`,
50
+ };
51
+ }
52
+ // AC1: Extract optional pipelineRunId — omit key when absent
53
+ // (exactOptionalPropertyTypes requires optional fields to be absent, not undefined)
54
+ const pipelineRunIdRaw = context.getString('pipelineRunId', '');
55
+ // AC4: Read prior iteration remediation context from context
56
+ const priorFiles = context.getList?.('devStoryFilesModified') ?? [];
57
+ const priorAcFailures = context.getList?.('devStoryAcFailures') ?? [];
58
+ // ---------------------------------------------------------------------------
59
+ // Read story content (used for findings injection and dispatch gating)
60
+ // ---------------------------------------------------------------------------
61
+ let storyContent = '';
62
+ try {
63
+ storyContent = readFileSync(storyFilePath, 'utf-8');
64
+ }
65
+ catch {
66
+ // Non-fatal: if file can't be read, use empty content
67
+ }
68
+ // ---------------------------------------------------------------------------
69
+ // Story 53-8 AC2: Pre-dispatch findings injection
70
+ // ---------------------------------------------------------------------------
71
+ let findingsPrompt = '';
72
+ if (options.db != null) {
73
+ try {
74
+ // Infer packageName from storyKey prefix (e.g., '53-8' → no package, or from path)
75
+ const pkgMatch = /packages\/([^/]+)\//.exec(storyFilePath);
76
+ const packageName = pkgMatch?.[1];
77
+ const injectionCtx = {
78
+ storyKey,
79
+ runId: pipelineRunIdRaw !== '' ? pipelineRunIdRaw : 'unknown',
80
+ targetFiles: extractTargetFilesFromStoryContent(storyContent),
81
+ ...(packageName !== undefined ? { packageName } : {}),
82
+ };
83
+ findingsPrompt = await FindingsInjector.inject(options.db, injectionCtx);
84
+ }
85
+ catch {
86
+ // AC5: Non-fatal — DB errors must never block dispatch
87
+ console.warn('[sdlc-dev-story-handler] FindingsInjector.inject failed; proceeding without findings');
88
+ findingsPrompt = '';
89
+ }
90
+ }
91
+ // ---------------------------------------------------------------------------
92
+ // Story 53-9: Dispatch pre-condition gating
93
+ // Runs after findings injection, before agent dispatch.
94
+ // Non-fatal: any gate error is caught and dispatch proceeds normally.
95
+ // ---------------------------------------------------------------------------
96
+ if (options.db != null) {
97
+ try {
98
+ const pendingFiles = extractTargetFilesFromStoryContent(storyContent);
99
+ const gateOptions = {
100
+ storyKey,
101
+ storyContent,
102
+ pendingFiles,
103
+ // completedStories: populated from run manifest per_story_state.
104
+ // Currently no modifiedFiles tracked in manifest — empty array is
105
+ // correct (gate degrades gracefully per AC7). Learning pre-emption
106
+ // (AC6) still functions via the DB query path.
107
+ completedStories: [],
108
+ db: options.db,
109
+ projectRoot: process.cwd(),
110
+ };
111
+ const gateResult = await DispatchGate.check(gateOptions);
112
+ if (gateResult.decision === 'warn' && gateResult.overlappingFiles !== undefined && gateResult.completedStoryKey !== undefined) {
113
+ // AC2: emit warning event; dispatch proceeds normally
114
+ options.eventBus.emit('pipeline:dispatch-warn', {
115
+ storyKey,
116
+ completedStoryKey: gateResult.completedStoryKey,
117
+ overlappingFiles: gateResult.overlappingFiles,
118
+ });
119
+ }
120
+ else if (gateResult.decision === 'block' && gateResult.modifiedPrompt !== undefined) {
121
+ // AC4: auto-resolved; extract extension note from modifiedPrompt and inject
122
+ // into findingsPrompt so the agent receives the namespace extension guidance.
123
+ // modifiedPrompt = storyContent + '\n\n' + extensionNote
124
+ const extensionNote = gateResult.modifiedPrompt.slice(storyContent.length).trim();
125
+ if (extensionNote.length > 0) {
126
+ findingsPrompt = findingsPrompt !== ''
127
+ ? `${findingsPrompt}\n\n${extensionNote}`
128
+ : extensionNote;
129
+ }
130
+ }
131
+ else if (gateResult.decision === 'gated') {
132
+ // AC5: non-resolvable conflict; place story in gated phase
133
+ options.eventBus.emit('pipeline:story-gated', {
134
+ storyKey,
135
+ conflictType: gateResult.conflictType ?? 'namespace-collision',
136
+ reason: gateResult.reason ?? 'dispatch gate: non-resolvable conflict',
137
+ ...(gateResult.completedStoryKey !== undefined
138
+ ? { completedStoryKey: gateResult.completedStoryKey }
139
+ : {}),
140
+ });
141
+ // Return early without dispatching — story stays in gated phase
142
+ return {
143
+ status: 'FAILURE',
144
+ failureReason: gateResult.reason ?? 'dispatch gate: story gated — operator review required',
145
+ };
146
+ }
147
+ }
148
+ catch {
149
+ // AC7: gate error must never block dispatch
150
+ console.debug('[sdlc-dev-story-handler] DispatchGate.check failed; proceeding with original dispatch');
151
+ }
152
+ }
153
+ // Build DevStoryParams with required + optional fields
154
+ const devStoryParams = {
155
+ storyKey,
156
+ storyFilePath,
157
+ ...(pipelineRunIdRaw !== '' ? { pipelineRunId: pipelineRunIdRaw } : {}),
158
+ // AC4: Pass accumulated modified files from prior iteration as priorFiles
159
+ ...(priorFiles.length > 0 ? { priorFiles } : {}),
160
+ // AC4: Construct taskScope note describing prior failures if present
161
+ ...(priorAcFailures.length > 0
162
+ ? { taskScope: `Prior attempt failed ACs: ${priorAcFailures.join(', ')}` }
163
+ : {}),
164
+ // Story 53-8 AC2 + Story 53-9 AC4: findings + gate extension note (if any)
165
+ ...(findingsPrompt !== '' ? { findingsPrompt } : {}),
166
+ };
167
+ // AC5: Emit phase-start telemetry before calling runDevStory
168
+ options.eventBus.emit('orchestrator:story-phase-start', {
169
+ storyKey,
170
+ phase: 'dev-story',
171
+ ...(pipelineRunIdRaw !== '' ? { pipelineRunId: pipelineRunIdRaw } : {}),
172
+ });
173
+ // Initialize outcome to a default so finally block always has a valid status
174
+ let outcome = { status: 'FAILURE', failureReason: 'unexpected error in dev-story handler' };
175
+ try {
176
+ // AC1: Delegate to runDevStory
177
+ const workflowResult = await options.runDevStory(options.deps, devStoryParams);
178
+ if (workflowResult.result === 'success') {
179
+ // Build verification gate: catch compile errors before code-review
180
+ if (options.buildVerifier) {
181
+ const projectRoot = context.getString('projectRoot', '');
182
+ if (projectRoot) {
183
+ const buildResult = options.buildVerifier(projectRoot);
184
+ if (buildResult.status === 'failed' || buildResult.status === 'timeout') {
185
+ outcome = {
186
+ status: 'FAILURE',
187
+ failureReason: `build verification failed after dev-story: ${buildResult.output?.slice(0, 500) ?? 'no output'}`,
188
+ contextUpdates: {
189
+ filesModified: workflowResult.files_modified,
190
+ devStoryFilesModified: workflowResult.files_modified,
191
+ devStoryAcFailures: ['build-verification'],
192
+ },
193
+ };
194
+ return outcome;
195
+ }
196
+ }
197
+ }
198
+ // AC2: Map success result to SUCCESS Outcome with implementation artifacts
199
+ outcome = {
200
+ status: 'SUCCESS',
201
+ contextUpdates: {
202
+ filesModified: workflowResult.files_modified,
203
+ acMet: workflowResult.ac_met,
204
+ // Persist for retry pass-through (AC4)
205
+ devStoryFilesModified: workflowResult.files_modified,
206
+ },
207
+ };
208
+ // ---------------------------------------------------------------------------
209
+ // Story 53-8 AC4: Retire contradicted findings on success
210
+ // ---------------------------------------------------------------------------
211
+ if (options.db != null) {
212
+ const successCtx = {
213
+ modifiedFiles: workflowResult.files_modified,
214
+ runId: pipelineRunIdRaw !== '' ? pipelineRunIdRaw : 'unknown',
215
+ };
216
+ try {
217
+ await FindingLifecycleManager.retireContradictedFindings(successCtx, options.db);
218
+ }
219
+ catch {
220
+ // AC5: Non-fatal — DB errors must never block success outcome
221
+ console.warn('[sdlc-dev-story-handler] retireContradictedFindings failed; continuing');
222
+ }
223
+ }
224
+ }
225
+ else {
226
+ // AC3: Map failure result to FAILURE Outcome with remediation context
227
+ const failureReason = workflowResult.error ??
228
+ (workflowResult.ac_failures.length > 0
229
+ ? `dev-story failed ACs: ${workflowResult.ac_failures.join(', ')}`
230
+ : 'dev-story workflow failed');
231
+ outcome = {
232
+ status: 'FAILURE',
233
+ failureReason,
234
+ contextUpdates: {
235
+ acFailures: workflowResult.ac_failures,
236
+ filesModified: workflowResult.files_modified,
237
+ // Persist for retry pass-through (AC4)
238
+ devStoryFilesModified: workflowResult.files_modified,
239
+ devStoryAcFailures: workflowResult.ac_failures,
240
+ },
241
+ };
242
+ // ---------------------------------------------------------------------------
243
+ // Story 53-8 AC1: Classify and persist failure finding
244
+ // ---------------------------------------------------------------------------
245
+ if (options.db != null) {
246
+ const failureCtx = {
247
+ storyKey,
248
+ runId: pipelineRunIdRaw !== '' ? pipelineRunIdRaw : 'unknown',
249
+ // exactOptionalPropertyTypes: omit 'error' when undefined rather than set to undefined
250
+ ...(workflowResult.error !== undefined ? { error: workflowResult.error } : {}),
251
+ affectedFiles: workflowResult.files_modified,
252
+ buildFailed: workflowResult.ac_failures.includes('build-verification'),
253
+ testsFailed: workflowResult.tests === 'fail',
254
+ };
255
+ try {
256
+ const finding = await classifyAndPersist(failureCtx, options.db);
257
+ // AC6: Emit pipeline:finding-captured after successful persist
258
+ options.eventBus.emit('pipeline:finding-captured', {
259
+ storyKey,
260
+ runId: failureCtx.runId,
261
+ rootCause: finding.root_cause,
262
+ });
263
+ }
264
+ catch {
265
+ // AC5: Non-fatal — DB errors must never block failure outcome
266
+ console.warn('[sdlc-dev-story-handler] classifyAndPersist failed; continuing');
267
+ }
268
+ }
269
+ }
270
+ }
271
+ catch (err) {
272
+ // Handle unexpected throws from runDevStory
273
+ const failureReason = err instanceof Error ? err.message : String(err);
274
+ outcome = { status: 'FAILURE', failureReason };
275
+ }
276
+ finally {
277
+ // AC5: Emit phase-complete in finally block — guaranteed even on throw
278
+ options.eventBus.emit('orchestrator:story-phase-complete', {
279
+ storyKey,
280
+ phase: 'dev-story',
281
+ result: { status: outcome.status },
282
+ ...(pipelineRunIdRaw !== '' ? { pipelineRunId: pipelineRunIdRaw } : {}),
283
+ });
284
+ }
285
+ return outcome;
286
+ };
287
+ }
288
+ //# sourceMappingURL=sdlc-dev-story-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdlc-dev-story-handler.js","sourceRoot":"","sources":["../../src/handlers/sdlc-dev-story-handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * SdlcPhaseHandler — wraps SDLC pipeline phase execution as a graph NodeHandler.
3
+ *
4
+ * Story 43-2.
5
+ *
6
+ * Architecture note (ADR-003): This package does not import from @substrate-ai/factory
7
+ * or from the monolith source tree at compile time. All external dependencies
8
+ * (orchestrator, phaseDeps, phase runner functions) are injected via
9
+ * SdlcPhaseHandlerDeps at construction time.
10
+ *
11
+ * TypeScript structural typing ensures the returned SdlcNodeHandler is
12
+ * assignable to NodeHandler from @substrate-ai/factory at the CLI composition
13
+ * root — no sdlc→factory import required.
14
+ */
15
+ import type { SdlcPhaseHandlerDeps, SdlcNodeHandler } from './types.js';
16
+ /**
17
+ * Create an sdlc.phase node handler.
18
+ *
19
+ * The returned handler:
20
+ * 1. Resolves the phase name from node.id (AC5)
21
+ * 2. Looks up the corresponding runner in the PHASE_RUNNERS map (AC7)
22
+ * 3. Calls the runner with phaseDeps and phase-specific params (AC1, AC2, AC5)
23
+ * 4. On runner error, returns FAILURE without re-throwing (AC3)
24
+ * 5. If advanceAfterRun !== false, calls orchestrator.advancePhase(runId) (AC4)
25
+ * 6. If gate check fails (advanced === false), returns FAILURE with gate messages (AC4)
26
+ * 7. On full success, returns SUCCESS with phase output in contextUpdates (AC1, AC2)
27
+ *
28
+ * @param deps - Injected dependencies: orchestrator, phaseDeps, phase runners.
29
+ * @returns A SdlcNodeHandler ready for registration under the 'sdlc.phase' key.
30
+ */
31
+ export declare function createSdlcPhaseHandler(deps: SdlcPhaseHandlerDeps): SdlcNodeHandler;
32
+ //# sourceMappingURL=sdlc-phase-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdlc-phase-handler.d.ts","sourceRoot":"","sources":["../../src/handlers/sdlc-phase-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,eAAe,EAAe,MAAM,YAAY,CAAA;AAMpF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,oBAAoB,GAAG,eAAe,CAiKlF"}
@@ -0,0 +1,166 @@
1
+ /**
2
+ * SdlcPhaseHandler — wraps SDLC pipeline phase execution as a graph NodeHandler.
3
+ *
4
+ * Story 43-2.
5
+ *
6
+ * Architecture note (ADR-003): This package does not import from @substrate-ai/factory
7
+ * or from the monolith source tree at compile time. All external dependencies
8
+ * (orchestrator, phaseDeps, phase runner functions) are injected via
9
+ * SdlcPhaseHandlerDeps at construction time.
10
+ *
11
+ * TypeScript structural typing ensures the returned SdlcNodeHandler is
12
+ * assignable to NodeHandler from @substrate-ai/factory at the CLI composition
13
+ * root — no sdlc→factory import required.
14
+ */
15
+ // ---------------------------------------------------------------------------
16
+ // Factory
17
+ // ---------------------------------------------------------------------------
18
+ /**
19
+ * Create an sdlc.phase node handler.
20
+ *
21
+ * The returned handler:
22
+ * 1. Resolves the phase name from node.id (AC5)
23
+ * 2. Looks up the corresponding runner in the PHASE_RUNNERS map (AC7)
24
+ * 3. Calls the runner with phaseDeps and phase-specific params (AC1, AC2, AC5)
25
+ * 4. On runner error, returns FAILURE without re-throwing (AC3)
26
+ * 5. If advanceAfterRun !== false, calls orchestrator.advancePhase(runId) (AC4)
27
+ * 6. If gate check fails (advanced === false), returns FAILURE with gate messages (AC4)
28
+ * 7. On full success, returns SUCCESS with phase output in contextUpdates (AC1, AC2)
29
+ *
30
+ * @param deps - Injected dependencies: orchestrator, phaseDeps, phase runners.
31
+ * @returns A SdlcNodeHandler ready for registration under the 'sdlc.phase' key.
32
+ */
33
+ export function createSdlcPhaseHandler(deps) {
34
+ // Build the PHASE_RUNNERS map from the injected phase runner functions.
35
+ // Using a Map allows O(1) lookup and supports the unknown-phase check (AC7).
36
+ const PHASE_RUNNERS = new Map(Object.entries(deps.phases));
37
+ return async (node, context, _graph) => {
38
+ // AC5: Phase selection is driven by node.id
39
+ const phaseName = node.id;
40
+ // AC7: Unknown phase — no runner registered
41
+ const runner = PHASE_RUNNERS.get(phaseName);
42
+ if (runner === undefined) {
43
+ return {
44
+ status: 'FAILURE',
45
+ failureReason: `No phase runner registered for phase: ${phaseName}`,
46
+ };
47
+ }
48
+ // Extract context values
49
+ const runId = context.getString('runId');
50
+ // AC1: concept is only needed for the analysis phase
51
+ const concept = phaseName === 'analysis' ? context.getString('concept', '') : '';
52
+ // Story-key skip: when --stories is provided (explicit story dispatch), the linear
53
+ // engine skips analysis/planning/solutioning entirely. Mirror that behavior in the
54
+ // graph engine by checking for storyKey in context — its presence means we're
55
+ // targeting implementation directly and early phases should be skipped.
56
+ const PRE_IMPL_PHASES = ['analysis', 'planning', 'solutioning'];
57
+ const storyKey = context.getString('storyKey', '');
58
+ if (storyKey && PRE_IMPL_PHASES.includes(phaseName)) {
59
+ return {
60
+ status: 'SUCCESS',
61
+ notes: `Phase ${phaseName} skipped — explicit story dispatch (storyKey=${storyKey})`,
62
+ };
63
+ }
64
+ // Phase-skip check: if the phase's output artifact already exists (from a prior run or
65
+ // from the linear engine having completed it), skip dispatch and return SUCCESS.
66
+ // This gives the graph engine behavioral parity with the linear engine's detectStartPhase().
67
+ //
68
+ // When skipping, we also register the artifact(s) for the CURRENT pipeline run so that
69
+ // downstream entry gates (which filter by pipeline_run_id) can find them. Without this,
70
+ // the implementation phase's entry gate would fail because it only sees artifacts from
71
+ // the current run.
72
+ const PHASE_ARTIFACT_TYPES = {
73
+ analysis: ['product-brief'],
74
+ planning: ['prd'],
75
+ solutioning: ['architecture', 'stories'],
76
+ };
77
+ const artifactTypes = PHASE_ARTIFACT_TYPES[phaseName];
78
+ if (artifactTypes !== undefined) {
79
+ try {
80
+ const db = deps.phaseDeps.db;
81
+ if (db) {
82
+ // Check if ALL required artifacts for this phase exist globally
83
+ let allExist = true;
84
+ for (const at of artifactTypes) {
85
+ const rows = await db.query('SELECT id, path, content_hash, summary FROM artifacts WHERE phase = ? AND type = ? ORDER BY created_at DESC LIMIT 1', [phaseName, at]);
86
+ if (!Array.isArray(rows) || rows.length === 0) {
87
+ allExist = false;
88
+ break;
89
+ }
90
+ }
91
+ if (allExist) {
92
+ // Register each artifact for the current pipeline run so downstream entry gates pass.
93
+ // The pipelineRunId comes from context (set by the graph orchestrator).
94
+ const pipelineRunId = context.getString('pipelineRunId', '');
95
+ if (pipelineRunId) {
96
+ for (const at of artifactTypes) {
97
+ const existing = await db.query('SELECT id, path, content_hash, summary FROM artifacts WHERE phase = ? AND type = ? ORDER BY created_at DESC LIMIT 1', [phaseName, at]);
98
+ const src = existing[0];
99
+ if (src) {
100
+ // Check if we've already registered this for the current run
101
+ const alreadyRegistered = await db.query('SELECT id FROM artifacts WHERE pipeline_run_id = ? AND phase = ? AND type = ? LIMIT 1', [pipelineRunId, phaseName, at]);
102
+ if (!Array.isArray(alreadyRegistered) || alreadyRegistered.length === 0) {
103
+ const newId = crypto.randomUUID();
104
+ await db.query('INSERT INTO artifacts (id, pipeline_run_id, phase, type, path, content_hash, summary) VALUES (?, ?, ?, ?, ?, ?, ?)', [newId, pipelineRunId, phaseName, at, src.path, src.content_hash ?? null, src.summary ?? null]);
105
+ }
106
+ }
107
+ }
108
+ }
109
+ return {
110
+ status: 'SUCCESS',
111
+ notes: `Phase ${phaseName} already complete — artifact(s) exist, skipping dispatch`,
112
+ };
113
+ }
114
+ }
115
+ }
116
+ catch {
117
+ // DB query failed — proceed with normal dispatch (don't block on skip check failure)
118
+ }
119
+ }
120
+ // Build phase-specific params (analysis requires concept; others only runId)
121
+ const params = phaseName === 'analysis' ? { runId, concept } : { runId };
122
+ // Outer try/catch wraps the entry gate check, runner call, and advancePhase call.
123
+ // This boundary satisfies AC3 (runner error) and also handles the case
124
+ // where evaluateEntryGates or advancePhase itself throws (network/DB error).
125
+ try {
126
+ // Story 43-13 AC1, AC2, AC4: Evaluate entry gates before dispatching runner.
127
+ // evaluateEntryGates is always called regardless of advanceAfterRun flag.
128
+ const entryGateResult = await deps.orchestrator.evaluateEntryGates(runId);
129
+ if (!entryGateResult.passed) {
130
+ const failures = entryGateResult.failures
131
+ ?.map((f) => `${f.gate}: ${f.error}`)
132
+ .join('; ') ?? 'no details';
133
+ return { status: 'FAILURE', failureReason: `entry gate failed: ${failures}` };
134
+ }
135
+ // AC1, AC2, AC5: Dispatch to the registered phase runner
136
+ const phaseOutput = await runner(deps.phaseDeps, params);
137
+ // AC4: Advance phase unless the caller has disabled it
138
+ if (deps.advanceAfterRun !== false) {
139
+ const advanceResult = await deps.orchestrator.advancePhase(runId);
140
+ if (!advanceResult.advanced) {
141
+ // Story 43-13 AC3, AC4: Exit gate failure — prefix with 'exit gate failed: '
142
+ const failures = advanceResult.gateFailures
143
+ ?.map((f) => `${f.gate}: ${f.error}`)
144
+ .join('; ') ?? 'no details';
145
+ return { status: 'FAILURE', failureReason: `exit gate failed: ${failures}` };
146
+ }
147
+ // AC1, AC2: Full success — include phase output and advanced phase name
148
+ return {
149
+ status: 'SUCCESS',
150
+ contextUpdates: { ...phaseOutput, advancedPhase: advanceResult.phase },
151
+ };
152
+ }
153
+ // advanceAfterRun === false: return success without advancing
154
+ return {
155
+ status: 'SUCCESS',
156
+ contextUpdates: phaseOutput,
157
+ };
158
+ }
159
+ catch (err) {
160
+ // AC3: runner threw, or evaluateEntryGates/advancePhase threw unexpectedly
161
+ const message = err instanceof Error ? err.message : String(err);
162
+ return { status: 'FAILURE', failureReason: message };
163
+ }
164
+ };
165
+ }
166
+ //# sourceMappingURL=sdlc-phase-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdlc-phase-handler.js","sourceRoot":"","sources":["../../src/handlers/sdlc-phase-handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,132 @@
1
+ /**
2
+ * Type definitions for the SDLC handler module.
3
+ * Story 43-2.
4
+ *
5
+ * All types are defined locally — structurally compatible with monolith types
6
+ * but not compile-time coupled to the monolith or @substrate-ai/factory.
7
+ * See ADR-003: sdlc must NOT import from @substrate-ai/factory.
8
+ */
9
+ /**
10
+ * Structured outcome returned by every SDLC node handler.
11
+ *
12
+ * Structurally compatible with Outcome from @substrate-ai/factory via
13
+ * TypeScript duck-typing — the CLI composition root can assign one to
14
+ * the other without any sdlc→factory import.
15
+ */
16
+ export interface SdlcOutcome {
17
+ status: 'SUCCESS' | 'FAILURE' | 'PARTIAL_SUCCESS' | 'NEEDS_RETRY' | 'ESCALATE';
18
+ failureReason?: string;
19
+ contextUpdates?: Record<string, unknown>;
20
+ notes?: string;
21
+ /**
22
+ * Optional preferred edge label for the graph engine's edge selector.
23
+ * The graph engine uses this to match the DOT edge `label` attribute when
24
+ * choosing the next node after this handler returns.
25
+ * e.g., 'SHIP_IT' routes to exit, 'NEEDS_FIXES' routes back to dev_story.
26
+ */
27
+ preferredLabel?: string;
28
+ }
29
+ /**
30
+ * SDLC node handler type alias.
31
+ *
32
+ * Structurally compatible with NodeHandler from @substrate-ai/factory:
33
+ * type NodeHandler = (node: GraphNode, context: IGraphContext, graph: Graph) => Promise<Outcome>
34
+ *
35
+ * TypeScript structural typing ensures the CLI composition root can assign
36
+ * SdlcNodeHandler to NodeHandler without any sdlc→factory import.
37
+ */
38
+ export type SdlcNodeHandler = (node: {
39
+ id: string;
40
+ label: string;
41
+ prompt: string;
42
+ }, context: {
43
+ getString(key: string, defaultValue?: string): string;
44
+ }, graph: unknown) => Promise<SdlcOutcome>;
45
+ /** Gate failure detail from a phase advance attempt. */
46
+ export interface GateFailure {
47
+ gate: string;
48
+ error: string;
49
+ }
50
+ /** Result of attempting to advance the pipeline phase. */
51
+ interface AdvancePhaseResult {
52
+ advanced: boolean;
53
+ phase: string;
54
+ gateFailures?: GateFailure[];
55
+ }
56
+ /**
57
+ * Result of evaluating entry gates before a phase dispatch.
58
+ * Story 43-13.
59
+ */
60
+ export interface EntryGateResult {
61
+ passed: boolean;
62
+ failures?: GateFailure[];
63
+ }
64
+ /**
65
+ * Local minimal PhaseOrchestrator interface.
66
+ * Structurally compatible with the monolith PhaseOrchestrator.
67
+ * `advancePhase` handles post-runner exit gates; `evaluateEntryGates` handles
68
+ * pre-runner entry gates (added in story 43-13).
69
+ */
70
+ export interface PhaseOrchestrator {
71
+ advancePhase(runId: string): Promise<AdvancePhaseResult>;
72
+ evaluateEntryGates(runId: string): Promise<EntryGateResult>;
73
+ }
74
+ /**
75
+ * Phase runner function type.
76
+ *
77
+ * Structurally compatible with the monolith phase runner signatures
78
+ * (runAnalysisPhase, runPlanningPhase, runSolutioningPhase) when called
79
+ * with the monolith's PhaseDeps and phase-specific params.
80
+ *
81
+ * `deps` is typed as `unknown` because PhaseDeps is defined in the monolith
82
+ * and this package has no need to inspect or modify it — it is passed through
83
+ * as-is from SdlcPhaseHandlerDeps.phaseDeps.
84
+ */
85
+ export type PhaseRunnerFn = (deps: unknown, params: Record<string, unknown>) => Promise<Record<string, unknown>>;
86
+ /**
87
+ * Map of phase name → runner function.
88
+ * Index signature allows additional phases to be registered without
89
+ * modifying the type (e.g., ux-design in a follow-on story).
90
+ */
91
+ export interface PhaseRunners {
92
+ analysis: PhaseRunnerFn;
93
+ planning: PhaseRunnerFn;
94
+ solutioning: PhaseRunnerFn;
95
+ [key: string]: PhaseRunnerFn;
96
+ }
97
+ /**
98
+ * Dependency injection container for createSdlcPhaseHandler.
99
+ *
100
+ * Architecture note (ADR-003): phaseDeps is typed as `unknown` because
101
+ * PhaseDeps is defined in the monolith. It is passed through opaquely to the
102
+ * injected phase runner functions — this package has no need to inspect or
103
+ * modify it. The CLI composition root injects the concrete PhaseDeps instance
104
+ * at runtime.
105
+ *
106
+ * Phase runner functions are provided via `phases` to allow test injection of
107
+ * mocks without vi.mock — preferred per ADR-003 (no monolith compile-time
108
+ * coupling). At runtime the CLI composition root injects the real runners.
109
+ */
110
+ export interface SdlcPhaseHandlerDeps {
111
+ /** Phase orchestrator for gate evaluation and phase advancement. */
112
+ orchestrator: PhaseOrchestrator;
113
+ /**
114
+ * Phase dependencies — passed through to runner functions.
115
+ * Typed as `unknown` to avoid compile-time coupling to monolith PhaseDeps.
116
+ */
117
+ phaseDeps: unknown;
118
+ /**
119
+ * Whether to call orchestrator.advancePhase() after each runner completes.
120
+ * Defaults to `true`. Pass `false` when managing phase advancement
121
+ * externally or in integration scenarios where only the runner is tested.
122
+ */
123
+ advanceAfterRun?: boolean;
124
+ /**
125
+ * Injectable phase runner functions — keyed by phase name (node.id).
126
+ * At runtime, the CLI composition root provides the real monolith runners.
127
+ * In tests, pass vi.fn() stubs directly (no vi.mock needed).
128
+ */
129
+ phases: PhaseRunners;
130
+ }
131
+ export {};
132
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/handlers/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,iBAAiB,GAAG,aAAa,GAAG,UAAU,CAAA;IAC9E,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACxC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,eAAe,GAAG,CAC5B,IAAI,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EACnD,OAAO,EAAE;IAAE,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,EAClE,KAAK,EAAE,OAAO,KACX,OAAO,CAAC,WAAW,CAAC,CAAA;AAMzB,wDAAwD;AACxD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;CACd;AAED,0DAA0D;AAC1D,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,OAAO,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,YAAY,CAAC,EAAE,WAAW,EAAE,CAAA;CAC7B;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,OAAO,CAAA;IACf,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAA;CACzB;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAA;IACxD,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAA;CAC5D;AAED;;;;;;;;;;GAUG;AACH,MAAM,MAAM,aAAa,GAAG,CAC1B,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;AAErC;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,aAAa,CAAA;IACvB,QAAQ,EAAE,aAAa,CAAA;IACvB,WAAW,EAAE,aAAa,CAAA;IAC1B,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAAA;CAC7B;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,oBAAoB;IACnC,oEAAoE;IACpE,YAAY,EAAE,iBAAiB,CAAA;IAC/B;;;OAGG;IACH,SAAS,EAAE,OAAO,CAAA;IAClB;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB;;;;OAIG;IACH,MAAM,EAAE,YAAY,CAAA;CACrB"}