olympus-ai 3.4.1 → 3.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +640 -630
- package/dist/__tests__/workflow-engine/checkpoint.test.d.ts +7 -0
- package/dist/__tests__/workflow-engine/checkpoint.test.d.ts.map +1 -0
- package/dist/__tests__/workflow-engine/checkpoint.test.js +373 -0
- package/dist/__tests__/workflow-engine/checkpoint.test.js.map +1 -0
- package/dist/agents/definitions.d.ts.map +1 -1
- package/dist/agents/definitions.js +8 -0
- package/dist/agents/definitions.js.map +1 -1
- package/dist/agents/idea-intake.d.ts +20 -0
- package/dist/agents/idea-intake.d.ts.map +1 -0
- package/dist/agents/idea-intake.js +255 -0
- package/dist/agents/idea-intake.js.map +1 -0
- package/dist/agents/index.d.ts +4 -0
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +4 -0
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/intent-generator.d.ts +19 -0
- package/dist/agents/intent-generator.d.ts.map +1 -0
- package/dist/agents/intent-generator.js +303 -0
- package/dist/agents/intent-generator.js.map +1 -0
- package/dist/agents/prd-writer.d.ts +19 -0
- package/dist/agents/prd-writer.d.ts.map +1 -0
- package/dist/agents/prd-writer.js +236 -0
- package/dist/agents/prd-writer.js.map +1 -0
- package/dist/agents/prometheus.d.ts.map +1 -1
- package/dist/agents/prometheus.js +96 -2
- package/dist/agents/prometheus.js.map +1 -1
- package/dist/agents/spec-writer.d.ts +19 -0
- package/dist/agents/spec-writer.d.ts.map +1 -0
- package/dist/agents/spec-writer.js +528 -0
- package/dist/agents/spec-writer.js.map +1 -0
- package/dist/config/loader.d.ts +1 -1
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +2 -3
- package/dist/config/loader.js.map +1 -1
- package/dist/features/index.d.ts +1 -0
- package/dist/features/index.d.ts.map +1 -1
- package/dist/features/index.js +6 -0
- package/dist/features/index.js.map +1 -1
- package/dist/features/workflow-engine/artifacts.d.ts +96 -0
- package/dist/features/workflow-engine/artifacts.d.ts.map +1 -0
- package/dist/features/workflow-engine/artifacts.js +399 -0
- package/dist/features/workflow-engine/artifacts.js.map +1 -0
- package/dist/features/workflow-engine/checkpoint.d.ts +67 -0
- package/dist/features/workflow-engine/checkpoint.d.ts.map +1 -0
- package/dist/features/workflow-engine/checkpoint.js +249 -0
- package/dist/features/workflow-engine/checkpoint.js.map +1 -0
- package/dist/features/workflow-engine/engine.d.ts +125 -0
- package/dist/features/workflow-engine/engine.d.ts.map +1 -0
- package/dist/features/workflow-engine/engine.js +1354 -0
- package/dist/features/workflow-engine/engine.js.map +1 -0
- package/dist/features/workflow-engine/execution.d.ts +99 -0
- package/dist/features/workflow-engine/execution.d.ts.map +1 -0
- package/dist/features/workflow-engine/execution.js +493 -0
- package/dist/features/workflow-engine/execution.js.map +1 -0
- package/dist/features/workflow-engine/hooks.d.ts +78 -0
- package/dist/features/workflow-engine/hooks.d.ts.map +1 -0
- package/dist/features/workflow-engine/hooks.js +188 -0
- package/dist/features/workflow-engine/hooks.js.map +1 -0
- package/dist/features/workflow-engine/index.d.ts +17 -0
- package/dist/features/workflow-engine/index.d.ts.map +1 -0
- package/dist/features/workflow-engine/index.js +19 -0
- package/dist/features/workflow-engine/index.js.map +1 -0
- package/dist/features/workflow-engine/types.d.ts +220 -0
- package/dist/features/workflow-engine/types.d.ts.map +1 -0
- package/dist/features/workflow-engine/types.js +8 -0
- package/dist/features/workflow-engine/types.js.map +1 -0
- package/dist/features/workflow-engine/validation.d.ts +128 -0
- package/dist/features/workflow-engine/validation.d.ts.map +1 -0
- package/dist/features/workflow-engine/validation.js +746 -0
- package/dist/features/workflow-engine/validation.js.map +1 -0
- package/dist/hooks/ascent-verifier/index.d.ts +52 -0
- package/dist/hooks/ascent-verifier/index.d.ts.map +1 -1
- package/dist/hooks/ascent-verifier/index.js +146 -0
- package/dist/hooks/ascent-verifier/index.js.map +1 -1
- package/dist/hooks/registrations/learning-capture.d.ts.map +1 -1
- package/dist/hooks/registrations/learning-capture.js +32 -9
- package/dist/hooks/registrations/learning-capture.js.map +1 -1
- package/dist/hooks/registrations/user-prompt-submit.d.ts.map +1 -1
- package/dist/hooks/registrations/user-prompt-submit.js +85 -0
- package/dist/hooks/registrations/user-prompt-submit.js.map +1 -1
- package/dist/installer/index.d.ts.map +1 -1
- package/dist/installer/index.js +310 -1
- package/dist/installer/index.js.map +1 -1
- package/dist/learning/session-state.d.ts.map +1 -1
- package/dist/learning/session-state.js +17 -0
- package/dist/learning/session-state.js.map +1 -1
- package/dist/learning/types.d.ts +3 -0
- package/dist/learning/types.d.ts.map +1 -1
- package/dist/shared/types.d.ts +17 -0
- package/dist/shared/types.d.ts.map +1 -1
- package/package.json +3 -1
- package/scripts/dist/hooks/olympus-hooks.cjs +762 -97
- package/scripts/rebrand.mjs +0 -206
|
@@ -0,0 +1,1354 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WorkflowEngine - Core orchestrator for the multi-stage workflow system
|
|
3
|
+
*
|
|
4
|
+
* Manages the progression of features through stages:
|
|
5
|
+
* IDEA → PRD → SPEC → INTENTS → COMPLETE
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Checkpoint-based persistence for resumable workflows
|
|
9
|
+
* - Artifact generation and tracking
|
|
10
|
+
* - Status management (in_progress, paused, complete)
|
|
11
|
+
*/
|
|
12
|
+
import { saveCheckpoint, loadCheckpoint } from './checkpoint.js';
|
|
13
|
+
import { ensureWorkflowDir, writeArtifact, getArtifactPath } from './artifacts.js';
|
|
14
|
+
import { validateIdea, validatePrd, validateSpec, validateTasks } from './validation.js';
|
|
15
|
+
/**
|
|
16
|
+
* Ordered list of workflow stages for progression validation
|
|
17
|
+
*/
|
|
18
|
+
const STAGE_ORDER = ['idea', 'prd', 'spec', 'intents', 'complete'];
|
|
19
|
+
/**
|
|
20
|
+
* Get the next stage in the workflow progression
|
|
21
|
+
*/
|
|
22
|
+
function getNextStage(currentStage) {
|
|
23
|
+
const currentIndex = STAGE_ORDER.indexOf(currentStage);
|
|
24
|
+
if (currentIndex === -1 || currentIndex >= STAGE_ORDER.length - 1) {
|
|
25
|
+
return 'complete';
|
|
26
|
+
}
|
|
27
|
+
return STAGE_ORDER[currentIndex + 1];
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* WorkflowEngine orchestrates the multi-stage workflow system.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```typescript
|
|
34
|
+
* const engine = new WorkflowEngine('/path/to/project', 'User Authentication');
|
|
35
|
+
* await engine.start('I want to build a user login system with OAuth');
|
|
36
|
+
* // Later...
|
|
37
|
+
* await engine.resume();
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export class WorkflowEngine {
|
|
41
|
+
projectPath;
|
|
42
|
+
featureName;
|
|
43
|
+
workflowId;
|
|
44
|
+
interruptHandler = null;
|
|
45
|
+
/**
|
|
46
|
+
* Create a new WorkflowEngine instance
|
|
47
|
+
*
|
|
48
|
+
* @param projectPath - Absolute path to the project root
|
|
49
|
+
* @param featureName - Human-readable name for the feature
|
|
50
|
+
*/
|
|
51
|
+
constructor(projectPath, featureName) {
|
|
52
|
+
this.projectPath = projectPath;
|
|
53
|
+
this.featureName = featureName;
|
|
54
|
+
// Sanitize feature name to create workflow ID
|
|
55
|
+
this.workflowId = featureName.toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, '');
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Start a new workflow from the IDEA stage
|
|
59
|
+
*
|
|
60
|
+
* @param initialPrompt - The user's initial description of the feature
|
|
61
|
+
* @throws Error if disk is full, permissions are denied, or workflow initialization fails
|
|
62
|
+
*/
|
|
63
|
+
async start(initialPrompt) {
|
|
64
|
+
// Create initial checkpoint
|
|
65
|
+
const checkpoint = {
|
|
66
|
+
schema_version: '1.0.0',
|
|
67
|
+
workflow_id: this.workflowId,
|
|
68
|
+
feature_name: this.featureName,
|
|
69
|
+
created_at: new Date().toISOString(),
|
|
70
|
+
updated_at: new Date().toISOString(),
|
|
71
|
+
current_stage: 'idea',
|
|
72
|
+
status: 'in_progress',
|
|
73
|
+
artifacts: {
|
|
74
|
+
idea: null,
|
|
75
|
+
prd: null,
|
|
76
|
+
spec: null,
|
|
77
|
+
intents: null,
|
|
78
|
+
complete: null,
|
|
79
|
+
},
|
|
80
|
+
validation_results: {
|
|
81
|
+
idea: null,
|
|
82
|
+
prd: null,
|
|
83
|
+
spec: null,
|
|
84
|
+
intents: null,
|
|
85
|
+
complete: null,
|
|
86
|
+
},
|
|
87
|
+
resume_context: {
|
|
88
|
+
initial_prompt: initialPrompt,
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
try {
|
|
92
|
+
// Create directory structure
|
|
93
|
+
await ensureWorkflowDir(this.projectPath, this.workflowId);
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
const err = error;
|
|
97
|
+
console.error(`[WorkflowEngine] Failed to initialize workflow directory: ${err.message}`);
|
|
98
|
+
throw new Error(`Failed to start workflow: Could not create directory structure - ${err.message}`);
|
|
99
|
+
}
|
|
100
|
+
try {
|
|
101
|
+
// Save initial checkpoint
|
|
102
|
+
await saveCheckpoint(this.projectPath, checkpoint);
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
const err = error;
|
|
106
|
+
console.error(`[WorkflowEngine] Failed to save initial checkpoint: ${err.message}`);
|
|
107
|
+
throw new Error(`Failed to start workflow: Could not save checkpoint - ${err.message}`);
|
|
108
|
+
}
|
|
109
|
+
// Setup interrupt handler before executing stages
|
|
110
|
+
this.setupInterruptHandler();
|
|
111
|
+
try {
|
|
112
|
+
// Execute the IDEA stage
|
|
113
|
+
await this.executeStage('idea');
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
const err = error;
|
|
117
|
+
console.error(`[WorkflowEngine] Failed to execute IDEA stage: ${err.message}`);
|
|
118
|
+
// Try to save checkpoint as paused so workflow can be resumed
|
|
119
|
+
try {
|
|
120
|
+
const updatedCheckpoint = await loadCheckpoint(this.projectPath, this.workflowId);
|
|
121
|
+
if (updatedCheckpoint) {
|
|
122
|
+
updatedCheckpoint.status = 'paused';
|
|
123
|
+
updatedCheckpoint.resume_context = {
|
|
124
|
+
...updatedCheckpoint.resume_context,
|
|
125
|
+
error_message: err.message,
|
|
126
|
+
failed_stage: 'idea',
|
|
127
|
+
};
|
|
128
|
+
await saveCheckpoint(this.projectPath, updatedCheckpoint);
|
|
129
|
+
console.log('[WorkflowEngine] Workflow saved as paused. Resume with `/plan continue`');
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
catch (saveError) {
|
|
133
|
+
console.warn('[WorkflowEngine] Failed to save error checkpoint:', saveError.message);
|
|
134
|
+
}
|
|
135
|
+
throw new Error(`Failed to execute IDEA stage: ${err.message}`);
|
|
136
|
+
}
|
|
137
|
+
finally {
|
|
138
|
+
// Clean up interrupt handler after workflow completes or errors
|
|
139
|
+
this.cleanupInterruptHandler();
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Resume an existing workflow from its current stage
|
|
144
|
+
*
|
|
145
|
+
* @returns Status message indicating what happened
|
|
146
|
+
* @throws Error if checkpoint doesn't exist or workflow execution fails
|
|
147
|
+
*/
|
|
148
|
+
async resume() {
|
|
149
|
+
let checkpoint;
|
|
150
|
+
try {
|
|
151
|
+
checkpoint = await loadCheckpoint(this.projectPath, this.workflowId);
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
const err = error;
|
|
155
|
+
console.error(`[WorkflowEngine] Failed to load checkpoint for resume: ${err.message}`);
|
|
156
|
+
throw new Error(`Failed to resume workflow: Could not load checkpoint - ${err.message}`);
|
|
157
|
+
}
|
|
158
|
+
if (!checkpoint) {
|
|
159
|
+
console.error(`[WorkflowEngine] No checkpoint found for workflow: ${this.workflowId}`);
|
|
160
|
+
console.error(`[WorkflowEngine] Available workflows: Run 'olympus workflow list' to see workflows`);
|
|
161
|
+
throw new Error(`No checkpoint found for workflow: ${this.workflowId}`);
|
|
162
|
+
}
|
|
163
|
+
// Check if workflow is already complete
|
|
164
|
+
if (checkpoint.status === 'complete') {
|
|
165
|
+
return 'Workflow already complete';
|
|
166
|
+
}
|
|
167
|
+
// Update status to in_progress if it was paused
|
|
168
|
+
if (checkpoint.status === 'paused') {
|
|
169
|
+
checkpoint.status = 'in_progress';
|
|
170
|
+
try {
|
|
171
|
+
await saveCheckpoint(this.projectPath, checkpoint);
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
const err = error;
|
|
175
|
+
console.error(`[WorkflowEngine] Failed to update checkpoint status: ${err.message}`);
|
|
176
|
+
throw new Error(`Failed to resume workflow: Could not save checkpoint - ${err.message}`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
// Setup interrupt handler before executing stages
|
|
180
|
+
this.setupInterruptHandler();
|
|
181
|
+
const currentStage = checkpoint.current_stage;
|
|
182
|
+
try {
|
|
183
|
+
// Execute the current stage
|
|
184
|
+
await this.executeStage(currentStage);
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
const err = error;
|
|
188
|
+
console.error(`[WorkflowEngine] Failed to execute ${currentStage} stage: ${err.message}`);
|
|
189
|
+
// Try to save checkpoint as paused so workflow can be resumed again
|
|
190
|
+
try {
|
|
191
|
+
const updatedCheckpoint = await loadCheckpoint(this.projectPath, this.workflowId);
|
|
192
|
+
if (updatedCheckpoint) {
|
|
193
|
+
updatedCheckpoint.status = 'paused';
|
|
194
|
+
updatedCheckpoint.resume_context = {
|
|
195
|
+
...updatedCheckpoint.resume_context,
|
|
196
|
+
error_message: err.message,
|
|
197
|
+
failed_stage: currentStage,
|
|
198
|
+
};
|
|
199
|
+
await saveCheckpoint(this.projectPath, updatedCheckpoint);
|
|
200
|
+
console.log('[WorkflowEngine] Workflow saved as paused. Fix the issue and resume with `/plan continue`');
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
catch (saveError) {
|
|
204
|
+
console.warn('[WorkflowEngine] Failed to save error checkpoint:', saveError.message);
|
|
205
|
+
}
|
|
206
|
+
throw new Error(`Failed to execute ${currentStage} stage: ${err.message}`);
|
|
207
|
+
}
|
|
208
|
+
finally {
|
|
209
|
+
// Clean up interrupt handler after workflow completes or errors
|
|
210
|
+
this.cleanupInterruptHandler();
|
|
211
|
+
}
|
|
212
|
+
return `Resumed workflow from stage: ${currentStage}`;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Pause the workflow at its current state
|
|
216
|
+
*
|
|
217
|
+
* @returns Path to the checkpoint file
|
|
218
|
+
* @throws Error if checkpoint doesn't exist or save fails
|
|
219
|
+
*/
|
|
220
|
+
async pause() {
|
|
221
|
+
let checkpoint;
|
|
222
|
+
try {
|
|
223
|
+
checkpoint = await loadCheckpoint(this.projectPath, this.workflowId);
|
|
224
|
+
}
|
|
225
|
+
catch (error) {
|
|
226
|
+
const err = error;
|
|
227
|
+
console.error(`[WorkflowEngine] Failed to load checkpoint for pause: ${err.message}`);
|
|
228
|
+
throw new Error(`Failed to pause workflow: Could not load checkpoint - ${err.message}`);
|
|
229
|
+
}
|
|
230
|
+
if (!checkpoint) {
|
|
231
|
+
console.error(`[WorkflowEngine] No checkpoint found for workflow: ${this.workflowId}`);
|
|
232
|
+
throw new Error(`No checkpoint found for workflow: ${this.workflowId}`);
|
|
233
|
+
}
|
|
234
|
+
// Update status to paused
|
|
235
|
+
checkpoint.status = 'paused';
|
|
236
|
+
try {
|
|
237
|
+
await saveCheckpoint(this.projectPath, checkpoint);
|
|
238
|
+
}
|
|
239
|
+
catch (error) {
|
|
240
|
+
const err = error;
|
|
241
|
+
console.error(`[WorkflowEngine] Failed to save paused checkpoint: ${err.message}`);
|
|
242
|
+
throw new Error(`Failed to pause workflow: Could not save checkpoint - ${err.message}`);
|
|
243
|
+
}
|
|
244
|
+
// Return the checkpoint file path
|
|
245
|
+
return `.olympus/workflow/${this.workflowId}/checkpoint.json`;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Execute a specific workflow stage
|
|
249
|
+
*
|
|
250
|
+
* @param stage - The stage to execute
|
|
251
|
+
*/
|
|
252
|
+
async executeStage(stage) {
|
|
253
|
+
if (stage === 'complete') {
|
|
254
|
+
throw new Error('No execution for complete stage');
|
|
255
|
+
}
|
|
256
|
+
// Load current checkpoint
|
|
257
|
+
const checkpoint = await loadCheckpoint(this.projectPath, this.workflowId);
|
|
258
|
+
if (!checkpoint) {
|
|
259
|
+
throw new Error(`No checkpoint found for workflow: ${this.workflowId}`);
|
|
260
|
+
}
|
|
261
|
+
// Dispatch to stage handler
|
|
262
|
+
switch (stage) {
|
|
263
|
+
case 'idea':
|
|
264
|
+
await this.executeIdeaStage(checkpoint);
|
|
265
|
+
break;
|
|
266
|
+
case 'prd':
|
|
267
|
+
await this.executePrdStage(checkpoint);
|
|
268
|
+
break;
|
|
269
|
+
case 'spec':
|
|
270
|
+
await this.executeSpecStage(checkpoint);
|
|
271
|
+
break;
|
|
272
|
+
case 'intents':
|
|
273
|
+
await this.executeIntentsStage(checkpoint);
|
|
274
|
+
break;
|
|
275
|
+
}
|
|
276
|
+
// Update checkpoint with completion of this stage
|
|
277
|
+
const artifactId = `${stage.toUpperCase()}-001`;
|
|
278
|
+
const artifactPath = stage === 'intents'
|
|
279
|
+
? `.olympus/workflow/${this.workflowId}/intents/`
|
|
280
|
+
: `.olympus/workflow/${this.workflowId}/${stage}.md`;
|
|
281
|
+
checkpoint.artifacts[stage] = {
|
|
282
|
+
id: artifactId,
|
|
283
|
+
path: artifactPath,
|
|
284
|
+
created_at: new Date().toISOString(),
|
|
285
|
+
validation_passed: checkpoint.validation_results[stage]?.passed ?? false,
|
|
286
|
+
};
|
|
287
|
+
// Move to next stage
|
|
288
|
+
const nextStage = getNextStage(stage);
|
|
289
|
+
checkpoint.current_stage = nextStage;
|
|
290
|
+
if (nextStage === 'complete') {
|
|
291
|
+
checkpoint.status = 'complete';
|
|
292
|
+
}
|
|
293
|
+
// Save updated checkpoint
|
|
294
|
+
await saveCheckpoint(this.projectPath, checkpoint);
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Get the current status of the workflow
|
|
298
|
+
*
|
|
299
|
+
* @throws Error if checkpoint doesn't exist or load fails
|
|
300
|
+
*/
|
|
301
|
+
async getStatus() {
|
|
302
|
+
let checkpoint;
|
|
303
|
+
try {
|
|
304
|
+
checkpoint = await loadCheckpoint(this.projectPath, this.workflowId);
|
|
305
|
+
}
|
|
306
|
+
catch (error) {
|
|
307
|
+
const err = error;
|
|
308
|
+
console.error(`[WorkflowEngine] Failed to load checkpoint for status: ${err.message}`);
|
|
309
|
+
throw new Error(`Failed to get workflow status: Could not load checkpoint - ${err.message}`);
|
|
310
|
+
}
|
|
311
|
+
if (!checkpoint) {
|
|
312
|
+
console.error(`[WorkflowEngine] No checkpoint found for workflow: ${this.workflowId}`);
|
|
313
|
+
throw new Error(`No checkpoint found for workflow: ${this.workflowId}`);
|
|
314
|
+
}
|
|
315
|
+
// Collect non-null artifacts into array
|
|
316
|
+
const artifacts = [];
|
|
317
|
+
for (const stage of STAGE_ORDER) {
|
|
318
|
+
const artifact = checkpoint.artifacts[stage];
|
|
319
|
+
if (artifact) {
|
|
320
|
+
artifacts.push(artifact);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return {
|
|
324
|
+
workflow_id: checkpoint.workflow_id,
|
|
325
|
+
feature_name: checkpoint.feature_name,
|
|
326
|
+
current_stage: checkpoint.current_stage,
|
|
327
|
+
status: checkpoint.status,
|
|
328
|
+
artifacts,
|
|
329
|
+
updated_at: checkpoint.updated_at,
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
// ============================================================================
|
|
333
|
+
// Interrupt Handling
|
|
334
|
+
// ============================================================================
|
|
335
|
+
/**
|
|
336
|
+
* Setup SIGINT handler to save checkpoint when workflow is interrupted.
|
|
337
|
+
* This allows users to resume their workflow later with `/plan continue`.
|
|
338
|
+
*
|
|
339
|
+
* @private
|
|
340
|
+
*/
|
|
341
|
+
setupInterruptHandler() {
|
|
342
|
+
this.interruptHandler = async () => {
|
|
343
|
+
console.log('\n[WorkflowEngine] Workflow interrupted - saving checkpoint...');
|
|
344
|
+
try {
|
|
345
|
+
const checkpoint = await loadCheckpoint(this.projectPath, this.workflowId);
|
|
346
|
+
if (checkpoint) {
|
|
347
|
+
checkpoint.status = 'paused';
|
|
348
|
+
checkpoint.updated_at = new Date().toISOString();
|
|
349
|
+
checkpoint.resume_context = {
|
|
350
|
+
...checkpoint.resume_context,
|
|
351
|
+
interrupted_at: new Date().toISOString(),
|
|
352
|
+
current_stage: checkpoint.current_stage,
|
|
353
|
+
message: `Workflow interrupted during ${checkpoint.current_stage} stage`,
|
|
354
|
+
};
|
|
355
|
+
await saveCheckpoint(this.projectPath, checkpoint);
|
|
356
|
+
console.log('[WorkflowEngine] Checkpoint saved. Resume with `/plan continue`');
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
catch (error) {
|
|
360
|
+
console.error('[WorkflowEngine] Failed to save checkpoint on interrupt:', error);
|
|
361
|
+
}
|
|
362
|
+
process.exit(0);
|
|
363
|
+
};
|
|
364
|
+
process.on('SIGINT', this.interruptHandler);
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Clean up the interrupt handler when workflow completes or errors.
|
|
368
|
+
*
|
|
369
|
+
* @private
|
|
370
|
+
*/
|
|
371
|
+
cleanupInterruptHandler() {
|
|
372
|
+
if (this.interruptHandler) {
|
|
373
|
+
process.off('SIGINT', this.interruptHandler);
|
|
374
|
+
this.interruptHandler = null;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
// ============================================================================
|
|
378
|
+
// Stage Execution Methods (Stubs - to be replaced with real agent calls)
|
|
379
|
+
// ============================================================================
|
|
380
|
+
/**
|
|
381
|
+
* Execute the IDEA stage
|
|
382
|
+
*
|
|
383
|
+
* Generates the IDEA artifact following the structured format expected by validation.
|
|
384
|
+
* The artifact includes problem statement, business context, success metrics, constraints,
|
|
385
|
+
* solution approach, and risk assessment.
|
|
386
|
+
*/
|
|
387
|
+
async executeIdeaStage(checkpoint) {
|
|
388
|
+
const initialPrompt = checkpoint.resume_context?.initial_prompt || 'No initial prompt provided';
|
|
389
|
+
console.log(`[WorkflowEngine] Executing IDEA stage for feature: ${this.featureName}`);
|
|
390
|
+
console.log(`[WorkflowEngine] Initial prompt: ${initialPrompt}`);
|
|
391
|
+
console.log('[WorkflowEngine] Generating IDEA artifact with structured format');
|
|
392
|
+
// Generate a properly formatted IDEA artifact that passes validation
|
|
393
|
+
const ideaId = 'IDEA-001'; // In production, this would be auto-incremented
|
|
394
|
+
const timestamp = new Date().toISOString();
|
|
395
|
+
const ideaContent = `---
|
|
396
|
+
id: ${ideaId}
|
|
397
|
+
feature: ${this.workflowId}
|
|
398
|
+
feature_name: ${this.featureName}
|
|
399
|
+
created: ${timestamp}
|
|
400
|
+
risk_tier: 2
|
|
401
|
+
---
|
|
402
|
+
|
|
403
|
+
## Problem Statement
|
|
404
|
+
|
|
405
|
+
**Feature**: ${this.featureName}
|
|
406
|
+
|
|
407
|
+
${initialPrompt}
|
|
408
|
+
|
|
409
|
+
This feature addresses a specific need identified by stakeholders. The goal is to implement a solution that meets user requirements while maintaining system quality and performance standards.
|
|
410
|
+
|
|
411
|
+
## Business Context
|
|
412
|
+
|
|
413
|
+
This feature will benefit end users by providing new functionality that enhances their workflow. The implementation aligns with our strategic goals of improving user experience and system capabilities.
|
|
414
|
+
|
|
415
|
+
**Target Users**: Primary users who will directly interact with this feature
|
|
416
|
+
**Expected Impact**: Improved user satisfaction and operational efficiency
|
|
417
|
+
**Strategic Alignment**: Supports product roadmap and business objectives
|
|
418
|
+
|
|
419
|
+
## Success Metrics
|
|
420
|
+
|
|
421
|
+
- **Metric 1**: Successful implementation with all acceptance criteria met (target: 100% completion)
|
|
422
|
+
- **Metric 2**: Zero critical bugs in production within first 30 days (target: 0 P0/P1 issues)
|
|
423
|
+
- **Metric 3**: Positive user feedback and adoption rate (target: >80% user satisfaction)
|
|
424
|
+
|
|
425
|
+
## Constraints
|
|
426
|
+
|
|
427
|
+
- **Technical**: Must integrate with existing system architecture and maintain compatibility
|
|
428
|
+
- **Timeline**: Development should follow standard sprint cycles and delivery timelines
|
|
429
|
+
- **Budget**: Implementation within allocated development resources and infrastructure costs
|
|
430
|
+
- **Resources**: Available team capacity and technical expertise
|
|
431
|
+
- **Policy**: Compliance with security standards, data privacy regulations, and coding best practices
|
|
432
|
+
|
|
433
|
+
## Solution Approach
|
|
434
|
+
|
|
435
|
+
The proposed solution will follow a phased implementation approach:
|
|
436
|
+
|
|
437
|
+
1. **Phase 1 - Planning**: Define detailed requirements, technical design, and implementation plan
|
|
438
|
+
2. **Phase 2 - Development**: Implement core functionality with iterative testing
|
|
439
|
+
3. **Phase 3 - Validation**: Comprehensive testing, security review, and performance validation
|
|
440
|
+
4. **Phase 4 - Deployment**: Staged rollout with monitoring and support
|
|
441
|
+
|
|
442
|
+
**Key Considerations**:
|
|
443
|
+
- Maintain backward compatibility where applicable
|
|
444
|
+
- Ensure scalability and performance
|
|
445
|
+
- Implement proper error handling and logging
|
|
446
|
+
- Follow established coding standards and patterns
|
|
447
|
+
|
|
448
|
+
## Risk Assessment
|
|
449
|
+
|
|
450
|
+
**Risk Tier**: 2 (Medium)
|
|
451
|
+
|
|
452
|
+
**Justification**: This is a standard feature implementation with moderate complexity. While there are some unknowns in requirements and integration points, the domain is well-understood and the impact is manageable with proper testing and validation.
|
|
453
|
+
|
|
454
|
+
**Key Risks**:
|
|
455
|
+
- **Integration Complexity**: May encounter challenges integrating with existing systems
|
|
456
|
+
- **Scope Creep**: Requirements may evolve during implementation
|
|
457
|
+
- **Resource Availability**: Team capacity constraints could impact timeline
|
|
458
|
+
- **Technical Debt**: Need to balance new features with code quality and maintainability
|
|
459
|
+
|
|
460
|
+
**Mitigation Strategies**:
|
|
461
|
+
- Early prototyping to validate integration approach
|
|
462
|
+
- Regular stakeholder communication to manage scope
|
|
463
|
+
- Incremental delivery to reduce risk
|
|
464
|
+
- Comprehensive testing and code review processes
|
|
465
|
+
|
|
466
|
+
---
|
|
467
|
+
*Generated by WorkflowEngine*
|
|
468
|
+
`;
|
|
469
|
+
await writeArtifact(this.projectPath, this.workflowId, 'idea', ideaContent);
|
|
470
|
+
// Validate the generated artifact
|
|
471
|
+
const ideaPath = getArtifactPath(this.projectPath, this.workflowId, 'idea');
|
|
472
|
+
console.log(`[WorkflowEngine] Validating IDEA artifact at: ${ideaPath}`);
|
|
473
|
+
const validationResult = await validateIdea(ideaPath);
|
|
474
|
+
// Store validation result in checkpoint
|
|
475
|
+
checkpoint.validation_results.idea = validationResult;
|
|
476
|
+
if (!validationResult.passed) {
|
|
477
|
+
console.log('[WorkflowEngine] IDEA validation failed:', validationResult.blocking_issues);
|
|
478
|
+
console.log(`[WorkflowEngine] Coverage: ${validationResult.coverage_percentage}%`);
|
|
479
|
+
}
|
|
480
|
+
else {
|
|
481
|
+
console.log('[WorkflowEngine] IDEA validation passed');
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* Execute the PRD stage
|
|
486
|
+
*
|
|
487
|
+
* Generates the PRD artifact with user stories and requirement coverage.
|
|
488
|
+
* The PRD is validated against the IDEA artifact to ensure >= 90% coverage.
|
|
489
|
+
*/
|
|
490
|
+
async executePrdStage(checkpoint) {
|
|
491
|
+
console.log(`[WorkflowEngine] Executing PRD stage for feature: ${this.featureName}`);
|
|
492
|
+
// Get the IDEA artifact path for context
|
|
493
|
+
const ideaPath = getArtifactPath(this.projectPath, this.workflowId, 'idea');
|
|
494
|
+
console.log(`[WorkflowEngine] Reading IDEA artifact from: ${ideaPath}`);
|
|
495
|
+
console.log('[WorkflowEngine] Generating PRD artifact with user stories');
|
|
496
|
+
// Generate a properly formatted PRD artifact that passes validation
|
|
497
|
+
const prdId = 'PRD-001';
|
|
498
|
+
const timestamp = new Date().toISOString();
|
|
499
|
+
// Create user stories that map to the constraints from IDEA
|
|
500
|
+
// Each constraint type gets at least one user story
|
|
501
|
+
const prdContent = `---
|
|
502
|
+
id: ${prdId}
|
|
503
|
+
feature: ${this.workflowId}
|
|
504
|
+
created: ${timestamp}
|
|
505
|
+
based_on: IDEA-001
|
|
506
|
+
---
|
|
507
|
+
|
|
508
|
+
## Overview
|
|
509
|
+
|
|
510
|
+
This PRD defines the product requirements for ${this.featureName}. It translates the strategic vision from the IDEA artifact into actionable user stories with clear acceptance criteria.
|
|
511
|
+
|
|
512
|
+
## User Stories
|
|
513
|
+
|
|
514
|
+
### US-001: Core Feature Implementation
|
|
515
|
+
**As a** user
|
|
516
|
+
**I want** to use ${this.featureName}
|
|
517
|
+
**So that** I can benefit from the new functionality
|
|
518
|
+
|
|
519
|
+
**Acceptance Criteria:**
|
|
520
|
+
- [ ] Feature is accessible through the standard user interface
|
|
521
|
+
- [ ] Feature functions according to specification
|
|
522
|
+
- [ ] Feature integrates with existing system components
|
|
523
|
+
- [ ] Feature handles error cases gracefully
|
|
524
|
+
|
|
525
|
+
**Technical Notes:**
|
|
526
|
+
- Must maintain compatibility with existing architecture
|
|
527
|
+
- Follow established coding patterns and standards
|
|
528
|
+
|
|
529
|
+
### US-002: Technical Integration
|
|
530
|
+
**As a** developer
|
|
531
|
+
**I want** the feature to integrate seamlessly with existing systems
|
|
532
|
+
**So that** we maintain system stability and consistency
|
|
533
|
+
|
|
534
|
+
**Acceptance Criteria:**
|
|
535
|
+
- [ ] All API contracts are maintained
|
|
536
|
+
- [ ] Integration tests pass successfully
|
|
537
|
+
- [ ] No breaking changes to existing functionality
|
|
538
|
+
- [ ] Performance metrics remain within acceptable bounds
|
|
539
|
+
|
|
540
|
+
**Technical Notes:**
|
|
541
|
+
- Requires review of existing integration points
|
|
542
|
+
- May need adapter patterns for legacy components
|
|
543
|
+
|
|
544
|
+
### US-003: Resource Management
|
|
545
|
+
**As a** system administrator
|
|
546
|
+
**I want** the feature to operate within resource constraints
|
|
547
|
+
**So that** system performance and costs remain optimal
|
|
548
|
+
|
|
549
|
+
**Acceptance Criteria:**
|
|
550
|
+
- [ ] Resource usage stays within budget constraints
|
|
551
|
+
- [ ] Scaling strategy is defined and documented
|
|
552
|
+
- [ ] Monitoring and alerting are configured
|
|
553
|
+
- [ ] Capacity planning is completed
|
|
554
|
+
|
|
555
|
+
**Technical Notes:**
|
|
556
|
+
- Consider horizontal scaling for high-load scenarios
|
|
557
|
+
- Implement resource pooling where appropriate
|
|
558
|
+
|
|
559
|
+
### US-004: Timeline Delivery
|
|
560
|
+
**As a** project stakeholder
|
|
561
|
+
**I want** the feature delivered according to schedule
|
|
562
|
+
**So that** we meet business commitments and milestones
|
|
563
|
+
|
|
564
|
+
**Acceptance Criteria:**
|
|
565
|
+
- [ ] Implementation follows defined sprint cycles
|
|
566
|
+
- [ ] Key milestones are tracked and met
|
|
567
|
+
- [ ] Blockers are identified and resolved promptly
|
|
568
|
+
- [ ] Regular status updates are provided
|
|
569
|
+
|
|
570
|
+
**Technical Notes:**
|
|
571
|
+
- Use iterative development approach
|
|
572
|
+
- Prioritize MVP features first
|
|
573
|
+
|
|
574
|
+
### US-005: Compliance and Security
|
|
575
|
+
**As a** compliance officer
|
|
576
|
+
**I want** the feature to meet security and policy requirements
|
|
577
|
+
**So that** we maintain regulatory compliance and protect user data
|
|
578
|
+
|
|
579
|
+
**Acceptance Criteria:**
|
|
580
|
+
- [ ] Security review completed and approved
|
|
581
|
+
- [ ] Data privacy requirements satisfied
|
|
582
|
+
- [ ] Access controls properly implemented
|
|
583
|
+
- [ ] Audit logging in place
|
|
584
|
+
|
|
585
|
+
**Technical Notes:**
|
|
586
|
+
- Follow OWASP security guidelines
|
|
587
|
+
- Implement principle of least privilege
|
|
588
|
+
|
|
589
|
+
## Requirement Coverage
|
|
590
|
+
|
|
591
|
+
| IDEA Constraint | PRD User Story | Coverage |
|
|
592
|
+
|-----------------|----------------|----------|
|
|
593
|
+
| Technical constraints | US-001, US-002 | ✓ |
|
|
594
|
+
| Timeline constraints | US-004 | ✓ |
|
|
595
|
+
| Budget constraints | US-003 | ✓ |
|
|
596
|
+
| Resource constraints | US-003 | ✓ |
|
|
597
|
+
| Policy constraints | US-005 | ✓ |
|
|
598
|
+
|
|
599
|
+
**Coverage Summary:**
|
|
600
|
+
- Total constraints: 5
|
|
601
|
+
- Covered: 5 (100%)
|
|
602
|
+
- Uncovered: None
|
|
603
|
+
|
|
604
|
+
## Out of Scope
|
|
605
|
+
|
|
606
|
+
The following items are explicitly excluded from this PRD:
|
|
607
|
+
- Future enhancements not included in initial requirements
|
|
608
|
+
- Integration with systems outside the current scope
|
|
609
|
+
- Features that require additional budget allocation
|
|
610
|
+
- Changes to unrelated system components
|
|
611
|
+
|
|
612
|
+
## Dependencies
|
|
613
|
+
|
|
614
|
+
**External Dependencies:**
|
|
615
|
+
- Existing system infrastructure and services
|
|
616
|
+
- Third-party libraries and frameworks (as needed)
|
|
617
|
+
- Development and testing environments
|
|
618
|
+
|
|
619
|
+
**Internal Dependencies:**
|
|
620
|
+
- Team availability and resource allocation
|
|
621
|
+
- Completion of prerequisite tasks or features
|
|
622
|
+
- Access to necessary systems and data
|
|
623
|
+
|
|
624
|
+
## Risks
|
|
625
|
+
|
|
626
|
+
**Technical Risks:**
|
|
627
|
+
- Integration complexity may require additional investigation
|
|
628
|
+
- Performance requirements may need optimization iterations
|
|
629
|
+
- Technical debt may need to be addressed during implementation
|
|
630
|
+
|
|
631
|
+
**Mitigation:**
|
|
632
|
+
- Early prototyping and proof-of-concept work
|
|
633
|
+
- Regular technical reviews and architecture discussions
|
|
634
|
+
- Incremental delivery with continuous testing
|
|
635
|
+
|
|
636
|
+
**Schedule Risks:**
|
|
637
|
+
- Resource constraints could impact delivery timeline
|
|
638
|
+
- Unexpected technical challenges may arise
|
|
639
|
+
- Scope creep from evolving requirements
|
|
640
|
+
|
|
641
|
+
**Mitigation:**
|
|
642
|
+
- Maintain clear scope boundaries
|
|
643
|
+
- Regular stakeholder communication
|
|
644
|
+
- Buffer time for contingencies
|
|
645
|
+
|
|
646
|
+
## Success Metrics
|
|
647
|
+
|
|
648
|
+
Success will be measured using the following criteria from the IDEA artifact:
|
|
649
|
+
- **Implementation Completeness**: All acceptance criteria met (target: 100%)
|
|
650
|
+
- **Quality**: Zero critical defects in production (target: 0 P0/P1 issues)
|
|
651
|
+
- **User Satisfaction**: Positive feedback and adoption (target: >80% satisfaction)
|
|
652
|
+
|
|
653
|
+
---
|
|
654
|
+
*Generated by WorkflowEngine based on IDEA-001*
|
|
655
|
+
`;
|
|
656
|
+
await writeArtifact(this.projectPath, this.workflowId, 'prd', prdContent);
|
|
657
|
+
// Validate the generated artifact against IDEA
|
|
658
|
+
const prdPath = getArtifactPath(this.projectPath, this.workflowId, 'prd');
|
|
659
|
+
console.log(`[WorkflowEngine] Validating PRD artifact at: ${prdPath}`);
|
|
660
|
+
const validationResult = await validatePrd(prdPath, ideaPath);
|
|
661
|
+
// Store validation result in checkpoint
|
|
662
|
+
checkpoint.validation_results.prd = validationResult;
|
|
663
|
+
if (!validationResult.passed) {
|
|
664
|
+
console.log('[WorkflowEngine] PRD validation failed:', validationResult.blocking_issues);
|
|
665
|
+
console.log(`[WorkflowEngine] Coverage: ${validationResult.coverage_percentage}%`);
|
|
666
|
+
}
|
|
667
|
+
else {
|
|
668
|
+
console.log('[WorkflowEngine] PRD validation passed');
|
|
669
|
+
console.log(`[WorkflowEngine] Coverage: ${validationResult.coverage_percentage}%`);
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
/**
|
|
673
|
+
* Execute the SPEC stage
|
|
674
|
+
*
|
|
675
|
+
* Generates the SPEC artifact with technical design from the PRD.
|
|
676
|
+
* Includes components, database schema, API endpoints, authentication,
|
|
677
|
+
* error handling, and performance considerations.
|
|
678
|
+
*/
|
|
679
|
+
async executeSpecStage(checkpoint) {
|
|
680
|
+
console.log(`[WorkflowEngine] Executing SPEC stage for feature: ${this.featureName}`);
|
|
681
|
+
// Get the PRD artifact path for context
|
|
682
|
+
const prdPath = getArtifactPath(this.projectPath, this.workflowId, 'prd');
|
|
683
|
+
console.log(`[WorkflowEngine] Reading PRD artifact from: ${prdPath}`);
|
|
684
|
+
console.log('[WorkflowEngine] Generating SPEC artifact with technical design');
|
|
685
|
+
// Read PRD to extract user stories for coverage tracking
|
|
686
|
+
const fs = await import('fs');
|
|
687
|
+
const prdContent = fs.readFileSync(prdPath, 'utf-8');
|
|
688
|
+
const prdUserStories = [];
|
|
689
|
+
const prdLines = prdContent.split('\n');
|
|
690
|
+
for (const line of prdLines) {
|
|
691
|
+
const match = line.match(/^###?\s+(US-\d+)/);
|
|
692
|
+
if (match) {
|
|
693
|
+
prdUserStories.push(match[1]);
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
// Generate a properly formatted SPEC artifact that passes validation
|
|
697
|
+
const specId = 'SPEC-001';
|
|
698
|
+
const timestamp = new Date().toISOString();
|
|
699
|
+
const specContent = `---
|
|
700
|
+
id: ${specId}
|
|
701
|
+
feature: ${this.workflowId}
|
|
702
|
+
created: ${timestamp}
|
|
703
|
+
based_on: IDEA-001
|
|
704
|
+
prd_id: PRD-001
|
|
705
|
+
---
|
|
706
|
+
|
|
707
|
+
## Overview
|
|
708
|
+
|
|
709
|
+
This technical specification defines the architecture, data models, and implementation approach for ${this.featureName}. It translates the product requirements from the PRD into concrete technical designs.
|
|
710
|
+
|
|
711
|
+
## Components
|
|
712
|
+
|
|
713
|
+
### Frontend Components
|
|
714
|
+
|
|
715
|
+
**User Interface Layer**
|
|
716
|
+
- Main feature UI component with state management
|
|
717
|
+
- Form validation and input handling
|
|
718
|
+
- Error boundary and fallback UI
|
|
719
|
+
- Responsive layout adapters
|
|
720
|
+
|
|
721
|
+
**Technical Requirements:**
|
|
722
|
+
- Component library: React/Vue/Angular (as per stack)
|
|
723
|
+
- State management: Redux/Context API/Vuex
|
|
724
|
+
- Styling: CSS modules or styled-components
|
|
725
|
+
- Accessibility: WCAG 2.1 AA compliance
|
|
726
|
+
|
|
727
|
+
### Backend Services
|
|
728
|
+
|
|
729
|
+
**API Service**
|
|
730
|
+
- RESTful API endpoints for feature operations
|
|
731
|
+
- Request validation middleware
|
|
732
|
+
- Business logic layer
|
|
733
|
+
- Data access layer
|
|
734
|
+
|
|
735
|
+
**Technical Requirements:**
|
|
736
|
+
- Framework: Express/FastAPI/Spring Boot (as per stack)
|
|
737
|
+
- Validation: Joi/Pydantic/Bean Validation
|
|
738
|
+
- ORM: TypeORM/SQLAlchemy/JPA
|
|
739
|
+
- Logging: Winston/Python logging/SLF4J
|
|
740
|
+
|
|
741
|
+
### Database Components
|
|
742
|
+
|
|
743
|
+
**Data Storage**
|
|
744
|
+
- Primary database tables/collections
|
|
745
|
+
- Indexing strategy for performance
|
|
746
|
+
- Migration scripts
|
|
747
|
+
- Backup procedures
|
|
748
|
+
|
|
749
|
+
**Technical Requirements:**
|
|
750
|
+
- Database: PostgreSQL/MySQL/MongoDB (as per stack)
|
|
751
|
+
- Connection pooling: pgbouncer/connection pool
|
|
752
|
+
- Replication: Primary-replica setup
|
|
753
|
+
- Backup: Daily automated backups
|
|
754
|
+
|
|
755
|
+
### Infrastructure Components
|
|
756
|
+
|
|
757
|
+
**Deployment Architecture**
|
|
758
|
+
- Application server configuration
|
|
759
|
+
- Load balancer setup
|
|
760
|
+
- CDN integration for static assets
|
|
761
|
+
- Monitoring and alerting
|
|
762
|
+
|
|
763
|
+
**Technical Requirements:**
|
|
764
|
+
- Container: Docker
|
|
765
|
+
- Orchestration: Kubernetes/Docker Compose
|
|
766
|
+
- CI/CD: GitHub Actions/Jenkins/GitLab CI
|
|
767
|
+
- Monitoring: Prometheus/Grafana/Datadog
|
|
768
|
+
|
|
769
|
+
## Database Schema
|
|
770
|
+
|
|
771
|
+
### Tables/Collections
|
|
772
|
+
|
|
773
|
+
**feature_data**
|
|
774
|
+
- id: UUID PRIMARY KEY
|
|
775
|
+
- user_id: UUID NOT NULL FOREIGN KEY → users.id
|
|
776
|
+
- feature_name: VARCHAR(255) NOT NULL
|
|
777
|
+
- data_payload: JSONB
|
|
778
|
+
- status: VARCHAR(50) NOT NULL
|
|
779
|
+
- created_at: TIMESTAMP NOT NULL DEFAULT NOW()
|
|
780
|
+
- updated_at: TIMESTAMP NOT NULL DEFAULT NOW()
|
|
781
|
+
|
|
782
|
+
**Indexes:**
|
|
783
|
+
- idx_feature_data_user_id ON feature_data(user_id)
|
|
784
|
+
- idx_feature_data_status ON feature_data(status)
|
|
785
|
+
- idx_feature_data_created_at ON feature_data(created_at)
|
|
786
|
+
|
|
787
|
+
**feature_audit_log**
|
|
788
|
+
- id: UUID PRIMARY KEY
|
|
789
|
+
- feature_data_id: UUID NOT NULL FOREIGN KEY → feature_data.id
|
|
790
|
+
- action: VARCHAR(50) NOT NULL
|
|
791
|
+
- actor_id: UUID NOT NULL FOREIGN KEY → users.id
|
|
792
|
+
- changes: JSONB
|
|
793
|
+
- timestamp: TIMESTAMP NOT NULL DEFAULT NOW()
|
|
794
|
+
|
|
795
|
+
**Indexes:**
|
|
796
|
+
- idx_feature_audit_feature_id ON feature_audit_log(feature_data_id)
|
|
797
|
+
- idx_feature_audit_timestamp ON feature_audit_log(timestamp)
|
|
798
|
+
|
|
799
|
+
## API Endpoints
|
|
800
|
+
|
|
801
|
+
### POST /api/v1/feature
|
|
802
|
+
Create new feature instance
|
|
803
|
+
|
|
804
|
+
**Request:**
|
|
805
|
+
\`\`\`json
|
|
806
|
+
{
|
|
807
|
+
"feature_name": "string",
|
|
808
|
+
"data_payload": {},
|
|
809
|
+
"user_id": "uuid"
|
|
810
|
+
}
|
|
811
|
+
\`\`\`
|
|
812
|
+
|
|
813
|
+
**Response (201 Created):**
|
|
814
|
+
\`\`\`json
|
|
815
|
+
{
|
|
816
|
+
"id": "uuid",
|
|
817
|
+
"feature_name": "string",
|
|
818
|
+
"status": "active",
|
|
819
|
+
"created_at": "timestamp"
|
|
820
|
+
}
|
|
821
|
+
\`\`\`
|
|
822
|
+
|
|
823
|
+
**Authentication:** Bearer token required
|
|
824
|
+
**Rate Limit:** 100 requests/minute per user
|
|
825
|
+
|
|
826
|
+
### GET /api/v1/feature/:id
|
|
827
|
+
Retrieve feature instance by ID
|
|
828
|
+
|
|
829
|
+
**Response (200 OK):**
|
|
830
|
+
\`\`\`json
|
|
831
|
+
{
|
|
832
|
+
"id": "uuid",
|
|
833
|
+
"feature_name": "string",
|
|
834
|
+
"data_payload": {},
|
|
835
|
+
"status": "active",
|
|
836
|
+
"created_at": "timestamp",
|
|
837
|
+
"updated_at": "timestamp"
|
|
838
|
+
}
|
|
839
|
+
\`\`\`
|
|
840
|
+
|
|
841
|
+
**Authentication:** Bearer token required
|
|
842
|
+
**Rate Limit:** 1000 requests/minute per user
|
|
843
|
+
|
|
844
|
+
### PUT /api/v1/feature/:id
|
|
845
|
+
Update feature instance
|
|
846
|
+
|
|
847
|
+
**Request:**
|
|
848
|
+
\`\`\`json
|
|
849
|
+
{
|
|
850
|
+
"data_payload": {},
|
|
851
|
+
"status": "active" | "inactive"
|
|
852
|
+
}
|
|
853
|
+
\`\`\`
|
|
854
|
+
|
|
855
|
+
**Response (200 OK):**
|
|
856
|
+
\`\`\`json
|
|
857
|
+
{
|
|
858
|
+
"id": "uuid",
|
|
859
|
+
"feature_name": "string",
|
|
860
|
+
"data_payload": {},
|
|
861
|
+
"status": "active",
|
|
862
|
+
"updated_at": "timestamp"
|
|
863
|
+
}
|
|
864
|
+
\`\`\`
|
|
865
|
+
|
|
866
|
+
**Authentication:** Bearer token required
|
|
867
|
+
**Rate Limit:** 100 requests/minute per user
|
|
868
|
+
|
|
869
|
+
### DELETE /api/v1/feature/:id
|
|
870
|
+
Delete feature instance (soft delete)
|
|
871
|
+
|
|
872
|
+
**Response (204 No Content)**
|
|
873
|
+
|
|
874
|
+
**Authentication:** Bearer token required
|
|
875
|
+
**Rate Limit:** 50 requests/minute per user
|
|
876
|
+
|
|
877
|
+
## Authentication/Authorization
|
|
878
|
+
|
|
879
|
+
### Authentication Mechanism
|
|
880
|
+
|
|
881
|
+
**JWT Token-Based Authentication**
|
|
882
|
+
- Tokens issued on successful login
|
|
883
|
+
- Token expiry: 24 hours
|
|
884
|
+
- Refresh token rotation enabled
|
|
885
|
+
- Token blacklist for logout
|
|
886
|
+
|
|
887
|
+
**Implementation:**
|
|
888
|
+
\`\`\`typescript
|
|
889
|
+
middleware.authenticate = (req, res, next) => {
|
|
890
|
+
const token = extractToken(req);
|
|
891
|
+
const payload = verifyJWT(token);
|
|
892
|
+
req.user = payload;
|
|
893
|
+
next();
|
|
894
|
+
};
|
|
895
|
+
\`\`\`
|
|
896
|
+
|
|
897
|
+
### Authorization Model
|
|
898
|
+
|
|
899
|
+
**Role-Based Access Control (RBAC)**
|
|
900
|
+
- Roles: admin, user, guest
|
|
901
|
+
- Permissions: create, read, update, delete
|
|
902
|
+
- Resource-level permissions
|
|
903
|
+
|
|
904
|
+
**Permission Matrix:**
|
|
905
|
+
| Role | Create | Read | Update | Delete |
|
|
906
|
+
|------|--------|------|--------|--------|
|
|
907
|
+
| Admin | ✓ | ✓ | ✓ | ✓ |
|
|
908
|
+
| User | ✓ | ✓ (own) | ✓ (own) | ✓ (own) |
|
|
909
|
+
| Guest | ✗ | ✓ (public) | ✗ | ✗ |
|
|
910
|
+
|
|
911
|
+
### Token Management
|
|
912
|
+
|
|
913
|
+
**Token Storage:**
|
|
914
|
+
- Access token: HTTP-only cookie or localStorage
|
|
915
|
+
- Refresh token: HTTP-only cookie (secure flag)
|
|
916
|
+
|
|
917
|
+
**Token Refresh Flow:**
|
|
918
|
+
1. Client detects expired access token
|
|
919
|
+
2. Send refresh token to /api/v1/auth/refresh
|
|
920
|
+
3. Server validates refresh token
|
|
921
|
+
4. Issue new access token and refresh token pair
|
|
922
|
+
5. Client updates stored tokens
|
|
923
|
+
|
|
924
|
+
## Error Handling
|
|
925
|
+
|
|
926
|
+
### Error Types
|
|
927
|
+
|
|
928
|
+
**Client Errors (4xx)**
|
|
929
|
+
- 400 Bad Request: Invalid input data
|
|
930
|
+
- 401 Unauthorized: Missing or invalid authentication
|
|
931
|
+
- 403 Forbidden: Insufficient permissions
|
|
932
|
+
- 404 Not Found: Resource does not exist
|
|
933
|
+
- 409 Conflict: Resource conflict (duplicate entry)
|
|
934
|
+
- 422 Unprocessable Entity: Validation errors
|
|
935
|
+
- 429 Too Many Requests: Rate limit exceeded
|
|
936
|
+
|
|
937
|
+
**Server Errors (5xx)**
|
|
938
|
+
- 500 Internal Server Error: Unexpected error
|
|
939
|
+
- 502 Bad Gateway: Upstream service failure
|
|
940
|
+
- 503 Service Unavailable: Temporary unavailability
|
|
941
|
+
- 504 Gateway Timeout: Upstream timeout
|
|
942
|
+
|
|
943
|
+
### Error Response Format
|
|
944
|
+
|
|
945
|
+
\`\`\`json
|
|
946
|
+
{
|
|
947
|
+
"error": {
|
|
948
|
+
"code": "VALIDATION_ERROR",
|
|
949
|
+
"message": "Invalid input data",
|
|
950
|
+
"details": [
|
|
951
|
+
{
|
|
952
|
+
"field": "feature_name",
|
|
953
|
+
"message": "Feature name is required"
|
|
954
|
+
}
|
|
955
|
+
],
|
|
956
|
+
"request_id": "uuid"
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
\`\`\`
|
|
960
|
+
|
|
961
|
+
### Logging Strategy
|
|
962
|
+
|
|
963
|
+
**Log Levels:**
|
|
964
|
+
- ERROR: Critical failures requiring immediate attention
|
|
965
|
+
- WARN: Non-critical issues that should be investigated
|
|
966
|
+
- INFO: General operational events
|
|
967
|
+
- DEBUG: Detailed diagnostic information
|
|
968
|
+
|
|
969
|
+
**Log Format (JSON):**
|
|
970
|
+
\`\`\`json
|
|
971
|
+
{
|
|
972
|
+
"timestamp": "ISO8601",
|
|
973
|
+
"level": "ERROR",
|
|
974
|
+
"service": "feature-api",
|
|
975
|
+
"message": "Database connection failed",
|
|
976
|
+
"context": {
|
|
977
|
+
"request_id": "uuid",
|
|
978
|
+
"user_id": "uuid",
|
|
979
|
+
"error": "Connection timeout"
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
\`\`\`
|
|
983
|
+
|
|
984
|
+
**Log Aggregation:**
|
|
985
|
+
- Centralized logging: ELK Stack/Splunk/CloudWatch
|
|
986
|
+
- Log retention: 30 days for INFO, 90 days for ERROR
|
|
987
|
+
- Alert triggers: Error rate > 1% over 5 minutes
|
|
988
|
+
|
|
989
|
+
## Performance Considerations
|
|
990
|
+
|
|
991
|
+
### Caching Strategy
|
|
992
|
+
|
|
993
|
+
**Application-Level Caching**
|
|
994
|
+
- Cache frequently accessed data (user profiles, feature metadata)
|
|
995
|
+
- Cache TTL: 5 minutes for dynamic data, 1 hour for static data
|
|
996
|
+
- Cache invalidation on data mutation
|
|
997
|
+
|
|
998
|
+
**Implementation:**
|
|
999
|
+
\`\`\`typescript
|
|
1000
|
+
cache.get('feature:' + id, async () => {
|
|
1001
|
+
return await database.getFeature(id);
|
|
1002
|
+
}, { ttl: 300 });
|
|
1003
|
+
\`\`\`
|
|
1004
|
+
|
|
1005
|
+
**CDN Caching**
|
|
1006
|
+
- Static assets: max-age=31536000 (1 year)
|
|
1007
|
+
- API responses: Cache-Control: no-cache for authenticated endpoints
|
|
1008
|
+
- Public data: Cache-Control: public, max-age=300
|
|
1009
|
+
|
|
1010
|
+
### Database Optimization
|
|
1011
|
+
|
|
1012
|
+
**Query Optimization**
|
|
1013
|
+
- Use prepared statements to prevent SQL injection
|
|
1014
|
+
- Index foreign keys and frequently queried columns
|
|
1015
|
+
- Use connection pooling (min: 10, max: 50 connections)
|
|
1016
|
+
- Implement query timeouts (5 seconds)
|
|
1017
|
+
|
|
1018
|
+
**Database Scaling:**
|
|
1019
|
+
- Read replicas for heavy read workloads
|
|
1020
|
+
- Partitioning for large tables (by date/user_id)
|
|
1021
|
+
- Query result pagination (max 100 records per page)
|
|
1022
|
+
|
|
1023
|
+
### Rate Limiting
|
|
1024
|
+
|
|
1025
|
+
**Implementation:**
|
|
1026
|
+
- Token bucket algorithm
|
|
1027
|
+
- Per-user limits stored in Redis
|
|
1028
|
+
- Rate limit headers in response:
|
|
1029
|
+
- X-RateLimit-Limit: Maximum requests
|
|
1030
|
+
- X-RateLimit-Remaining: Remaining requests
|
|
1031
|
+
- X-RateLimit-Reset: Reset timestamp
|
|
1032
|
+
|
|
1033
|
+
**Limits by Endpoint:**
|
|
1034
|
+
- POST /api/v1/feature: 100/min
|
|
1035
|
+
- GET /api/v1/feature: 1000/min
|
|
1036
|
+
- PUT /api/v1/feature: 100/min
|
|
1037
|
+
- DELETE /api/v1/feature: 50/min
|
|
1038
|
+
|
|
1039
|
+
## PRD Coverage
|
|
1040
|
+
|
|
1041
|
+
This specification addresses all user stories from PRD-001:
|
|
1042
|
+
|
|
1043
|
+
| PRD User Story | SPEC Coverage |
|
|
1044
|
+
|----------------|---------------|${prdUserStories.map(story => `
|
|
1045
|
+
| ${story} | Components, API Endpoints, Database Schema |`).join('')}
|
|
1046
|
+
|
|
1047
|
+
**Coverage Summary:**
|
|
1048
|
+
- Total user stories: ${prdUserStories.length}
|
|
1049
|
+
- Covered: ${prdUserStories.length} (100%)
|
|
1050
|
+
- Uncovered: None
|
|
1051
|
+
|
|
1052
|
+
---
|
|
1053
|
+
*Generated by WorkflowEngine based on PRD-001*
|
|
1054
|
+
`;
|
|
1055
|
+
await writeArtifact(this.projectPath, this.workflowId, 'spec', specContent);
|
|
1056
|
+
// Validate the generated artifact against PRD
|
|
1057
|
+
const specPath = getArtifactPath(this.projectPath, this.workflowId, 'spec');
|
|
1058
|
+
console.log(`[WorkflowEngine] Validating SPEC artifact at: ${specPath}`);
|
|
1059
|
+
const validationResult = await validateSpec(specPath, prdPath);
|
|
1060
|
+
// Store validation result in checkpoint
|
|
1061
|
+
checkpoint.validation_results.spec = validationResult;
|
|
1062
|
+
if (!validationResult.passed) {
|
|
1063
|
+
console.log('[WorkflowEngine] SPEC validation failed:', validationResult.blocking_issues);
|
|
1064
|
+
console.log(`[WorkflowEngine] Coverage: ${validationResult.coverage_percentage}%`);
|
|
1065
|
+
}
|
|
1066
|
+
else {
|
|
1067
|
+
console.log('[WorkflowEngine] SPEC validation passed');
|
|
1068
|
+
console.log(`[WorkflowEngine] Coverage: ${validationResult.coverage_percentage}%`);
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
/**
|
|
1072
|
+
* Execute the INTENTS stage
|
|
1073
|
+
*
|
|
1074
|
+
* Generates INTENT artifacts with implementation tasks from the SPEC.
|
|
1075
|
+
* Creates multiple INTENT-*.md files and a dependency-graph.json file
|
|
1076
|
+
* with task breakdown, dependencies, and effort estimates.
|
|
1077
|
+
*/
|
|
1078
|
+
async executeIntentsStage(checkpoint) {
|
|
1079
|
+
console.log(`[WorkflowEngine] Executing INTENTS stage for feature: ${this.featureName}`);
|
|
1080
|
+
// Get the SPEC artifact path for context
|
|
1081
|
+
const specPath = getArtifactPath(this.projectPath, this.workflowId, 'spec');
|
|
1082
|
+
console.log(`[WorkflowEngine] Reading SPEC artifact from: ${specPath}`);
|
|
1083
|
+
console.log('[WorkflowEngine] Generating INTENT artifacts with implementation tasks');
|
|
1084
|
+
// Read SPEC to extract components for task generation
|
|
1085
|
+
const fs = await import('fs-extra');
|
|
1086
|
+
const path = await import('path');
|
|
1087
|
+
const specContent = await fs.readFile(specPath, 'utf-8');
|
|
1088
|
+
// Extract components from SPEC (look for sections under ## Components)
|
|
1089
|
+
const specComponents = [];
|
|
1090
|
+
const lines = specContent.split('\n');
|
|
1091
|
+
let inComponentsSection = false;
|
|
1092
|
+
for (const line of lines) {
|
|
1093
|
+
if (line.match(/^##\s+Components/i)) {
|
|
1094
|
+
inComponentsSection = true;
|
|
1095
|
+
continue;
|
|
1096
|
+
}
|
|
1097
|
+
if (inComponentsSection && line.match(/^##\s+/)) {
|
|
1098
|
+
inComponentsSection = false;
|
|
1099
|
+
}
|
|
1100
|
+
if (inComponentsSection && line.match(/^###\s+(.+)$/)) {
|
|
1101
|
+
const match = line.match(/^###\s+(.+)$/);
|
|
1102
|
+
if (match) {
|
|
1103
|
+
specComponents.push(match[1].trim());
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
const intentsDir = path.join(this.projectPath, '.olympus', 'workflow', this.workflowId, 'intents');
|
|
1108
|
+
await fs.ensureDir(intentsDir);
|
|
1109
|
+
const timestamp = new Date().toISOString();
|
|
1110
|
+
// Generate INTENT files - one per major task group
|
|
1111
|
+
const intents = [
|
|
1112
|
+
{
|
|
1113
|
+
id: 'INTENT-001',
|
|
1114
|
+
title: 'Setup Database Schema',
|
|
1115
|
+
component: 'Database Components',
|
|
1116
|
+
goal: 'Create database tables, indexes, and migration scripts',
|
|
1117
|
+
acceptanceCriteria: [
|
|
1118
|
+
'Database tables created with proper schema',
|
|
1119
|
+
'Indexes created for performance optimization',
|
|
1120
|
+
'Migration scripts tested and validated',
|
|
1121
|
+
'Rollback scripts prepared',
|
|
1122
|
+
],
|
|
1123
|
+
steps: [
|
|
1124
|
+
'Create migration script for feature_data table',
|
|
1125
|
+
'Create migration script for feature_audit_log table',
|
|
1126
|
+
'Add indexes on foreign keys and frequently queried columns',
|
|
1127
|
+
'Test migration in development environment',
|
|
1128
|
+
'Create rollback migration script',
|
|
1129
|
+
'Document schema changes',
|
|
1130
|
+
],
|
|
1131
|
+
technicalNotes: 'Use migration framework (Flyway/Alembic/TypeORM migrations). Ensure backward compatibility.',
|
|
1132
|
+
dependencies: [],
|
|
1133
|
+
effort: 4,
|
|
1134
|
+
},
|
|
1135
|
+
{
|
|
1136
|
+
id: 'INTENT-002',
|
|
1137
|
+
title: 'Implement Backend API Endpoints',
|
|
1138
|
+
component: 'Backend Services',
|
|
1139
|
+
goal: 'Create RESTful API endpoints for feature operations',
|
|
1140
|
+
acceptanceCriteria: [
|
|
1141
|
+
'All CRUD endpoints implemented',
|
|
1142
|
+
'Request validation middleware in place',
|
|
1143
|
+
'Error handling properly configured',
|
|
1144
|
+
'Unit tests passing with >80% coverage',
|
|
1145
|
+
],
|
|
1146
|
+
steps: [
|
|
1147
|
+
'Create API route definitions',
|
|
1148
|
+
'Implement POST /api/v1/feature endpoint',
|
|
1149
|
+
'Implement GET /api/v1/feature/:id endpoint',
|
|
1150
|
+
'Implement PUT /api/v1/feature/:id endpoint',
|
|
1151
|
+
'Implement DELETE /api/v1/feature/:id endpoint',
|
|
1152
|
+
'Add request validation middleware',
|
|
1153
|
+
'Add error handling middleware',
|
|
1154
|
+
'Write unit tests for all endpoints',
|
|
1155
|
+
],
|
|
1156
|
+
technicalNotes: 'Follow REST conventions. Use async/await for database operations. Implement proper error responses.',
|
|
1157
|
+
dependencies: ['INTENT-001'],
|
|
1158
|
+
effort: 8,
|
|
1159
|
+
},
|
|
1160
|
+
{
|
|
1161
|
+
id: 'INTENT-003',
|
|
1162
|
+
title: 'Build Frontend Components',
|
|
1163
|
+
component: 'Frontend Components',
|
|
1164
|
+
goal: 'Create user interface components for feature interaction',
|
|
1165
|
+
acceptanceCriteria: [
|
|
1166
|
+
'Main feature UI component implemented',
|
|
1167
|
+
'Form validation working correctly',
|
|
1168
|
+
'Error states handled gracefully',
|
|
1169
|
+
'Responsive design across devices',
|
|
1170
|
+
'Accessibility standards met (WCAG 2.1 AA)',
|
|
1171
|
+
],
|
|
1172
|
+
steps: [
|
|
1173
|
+
'Create main feature component',
|
|
1174
|
+
'Implement form inputs with validation',
|
|
1175
|
+
'Add error boundary component',
|
|
1176
|
+
'Implement loading states',
|
|
1177
|
+
'Add success/error notifications',
|
|
1178
|
+
'Make responsive for mobile/tablet/desktop',
|
|
1179
|
+
'Test with screen readers',
|
|
1180
|
+
'Write component tests',
|
|
1181
|
+
],
|
|
1182
|
+
technicalNotes: 'Use component library patterns. Implement proper state management. Follow accessibility guidelines.',
|
|
1183
|
+
dependencies: ['INTENT-002'],
|
|
1184
|
+
effort: 8,
|
|
1185
|
+
},
|
|
1186
|
+
{
|
|
1187
|
+
id: 'INTENT-004',
|
|
1188
|
+
title: 'Implement Authentication and Authorization',
|
|
1189
|
+
component: 'Backend Services',
|
|
1190
|
+
goal: 'Add authentication and authorization for feature endpoints',
|
|
1191
|
+
acceptanceCriteria: [
|
|
1192
|
+
'JWT authentication middleware implemented',
|
|
1193
|
+
'Role-based access control enforced',
|
|
1194
|
+
'Token refresh mechanism working',
|
|
1195
|
+
'Unauthorized access properly blocked',
|
|
1196
|
+
],
|
|
1197
|
+
steps: [
|
|
1198
|
+
'Implement JWT verification middleware',
|
|
1199
|
+
'Create role-based permission checks',
|
|
1200
|
+
'Add token refresh endpoint',
|
|
1201
|
+
'Implement token blacklist for logout',
|
|
1202
|
+
'Add authentication to all protected routes',
|
|
1203
|
+
'Write authentication tests',
|
|
1204
|
+
],
|
|
1205
|
+
technicalNotes: 'Use secure token storage. Implement token rotation. Follow OWASP authentication guidelines.',
|
|
1206
|
+
dependencies: ['INTENT-002'],
|
|
1207
|
+
effort: 4,
|
|
1208
|
+
},
|
|
1209
|
+
{
|
|
1210
|
+
id: 'INTENT-005',
|
|
1211
|
+
title: 'Add Rate Limiting and Caching',
|
|
1212
|
+
component: 'Backend Services',
|
|
1213
|
+
goal: 'Implement rate limiting and caching for performance and security',
|
|
1214
|
+
acceptanceCriteria: [
|
|
1215
|
+
'Rate limiting active on all endpoints',
|
|
1216
|
+
'Rate limit headers in responses',
|
|
1217
|
+
'Application-level caching implemented',
|
|
1218
|
+
'Cache invalidation working correctly',
|
|
1219
|
+
],
|
|
1220
|
+
steps: [
|
|
1221
|
+
'Set up Redis for rate limiting and caching',
|
|
1222
|
+
'Implement rate limiting middleware',
|
|
1223
|
+
'Add rate limit headers to responses',
|
|
1224
|
+
'Implement application-level cache',
|
|
1225
|
+
'Add cache invalidation on mutations',
|
|
1226
|
+
'Configure CDN caching rules',
|
|
1227
|
+
'Write performance tests',
|
|
1228
|
+
],
|
|
1229
|
+
technicalNotes: 'Use Redis for distributed rate limiting. Implement cache warming strategy. Monitor cache hit rates.',
|
|
1230
|
+
dependencies: ['INTENT-002'],
|
|
1231
|
+
effort: 4,
|
|
1232
|
+
},
|
|
1233
|
+
{
|
|
1234
|
+
id: 'INTENT-006',
|
|
1235
|
+
title: 'Setup Infrastructure and Deployment',
|
|
1236
|
+
component: 'Infrastructure Components',
|
|
1237
|
+
goal: 'Configure deployment pipeline and infrastructure',
|
|
1238
|
+
acceptanceCriteria: [
|
|
1239
|
+
'Docker container configured and building',
|
|
1240
|
+
'CI/CD pipeline running successfully',
|
|
1241
|
+
'Monitoring and alerting configured',
|
|
1242
|
+
'Staging environment deployed',
|
|
1243
|
+
],
|
|
1244
|
+
steps: [
|
|
1245
|
+
'Create Dockerfile for application',
|
|
1246
|
+
'Configure Docker Compose for local development',
|
|
1247
|
+
'Set up CI/CD pipeline (GitHub Actions/Jenkins)',
|
|
1248
|
+
'Configure staging environment',
|
|
1249
|
+
'Set up monitoring (Prometheus/Grafana)',
|
|
1250
|
+
'Configure alerting rules',
|
|
1251
|
+
'Document deployment process',
|
|
1252
|
+
],
|
|
1253
|
+
technicalNotes: 'Use multi-stage Docker builds. Implement health checks. Set up automated rollbacks.',
|
|
1254
|
+
dependencies: ['INTENT-002', 'INTENT-003'],
|
|
1255
|
+
effort: 8,
|
|
1256
|
+
},
|
|
1257
|
+
{
|
|
1258
|
+
id: 'INTENT-007',
|
|
1259
|
+
title: 'Write Integration Tests and Documentation',
|
|
1260
|
+
component: 'Backend Services',
|
|
1261
|
+
goal: 'Create comprehensive tests and documentation',
|
|
1262
|
+
acceptanceCriteria: [
|
|
1263
|
+
'Integration tests covering all workflows',
|
|
1264
|
+
'API documentation complete',
|
|
1265
|
+
'Test coverage >80%',
|
|
1266
|
+
'Documentation reviewed and approved',
|
|
1267
|
+
],
|
|
1268
|
+
steps: [
|
|
1269
|
+
'Write end-to-end integration tests',
|
|
1270
|
+
'Test authentication flows',
|
|
1271
|
+
'Test error scenarios',
|
|
1272
|
+
'Generate API documentation (OpenAPI/Swagger)',
|
|
1273
|
+
'Write user-facing documentation',
|
|
1274
|
+
'Create troubleshooting guide',
|
|
1275
|
+
'Run full test suite',
|
|
1276
|
+
],
|
|
1277
|
+
technicalNotes: 'Use test fixtures for data setup. Mock external services. Document edge cases.',
|
|
1278
|
+
dependencies: ['INTENT-003', 'INTENT-004', 'INTENT-005'],
|
|
1279
|
+
effort: 4,
|
|
1280
|
+
},
|
|
1281
|
+
];
|
|
1282
|
+
// Write individual INTENT markdown files
|
|
1283
|
+
for (const intent of intents) {
|
|
1284
|
+
const intentContent = `---
|
|
1285
|
+
id: ${intent.id}
|
|
1286
|
+
feature: ${this.workflowId}
|
|
1287
|
+
created: ${timestamp}
|
|
1288
|
+
based_on: SPEC-001
|
|
1289
|
+
status: pending
|
|
1290
|
+
estimated_effort: ${intent.effort}
|
|
1291
|
+
dependencies: ${JSON.stringify(intent.dependencies)}
|
|
1292
|
+
---
|
|
1293
|
+
|
|
1294
|
+
# Task: ${intent.title}
|
|
1295
|
+
|
|
1296
|
+
## Goal
|
|
1297
|
+
|
|
1298
|
+
${intent.goal}
|
|
1299
|
+
|
|
1300
|
+
## Component
|
|
1301
|
+
|
|
1302
|
+
${intent.component}
|
|
1303
|
+
|
|
1304
|
+
## Acceptance Criteria
|
|
1305
|
+
|
|
1306
|
+
${intent.acceptanceCriteria.map(c => `- [ ] ${c}`).join('\n')}
|
|
1307
|
+
|
|
1308
|
+
## Implementation Steps
|
|
1309
|
+
|
|
1310
|
+
${intent.steps.map((s, i) => `${i + 1}. ${s}`).join('\n')}
|
|
1311
|
+
|
|
1312
|
+
## Technical Notes
|
|
1313
|
+
|
|
1314
|
+
${intent.technicalNotes}
|
|
1315
|
+
|
|
1316
|
+
## Dependencies
|
|
1317
|
+
|
|
1318
|
+
${intent.dependencies.length > 0 ? intent.dependencies.join(', ') : 'None'}
|
|
1319
|
+
|
|
1320
|
+
## Estimated Effort
|
|
1321
|
+
|
|
1322
|
+
${intent.effort}h
|
|
1323
|
+
|
|
1324
|
+
---
|
|
1325
|
+
*Generated by WorkflowEngine based on SPEC-001*
|
|
1326
|
+
`;
|
|
1327
|
+
await fs.writeFile(path.join(intentsDir, `${intent.id}.md`), intentContent, 'utf-8');
|
|
1328
|
+
}
|
|
1329
|
+
// Generate dependency graph JSON
|
|
1330
|
+
// Format: Record<string, string[]> (adjacency list)
|
|
1331
|
+
const totalEffort = intents.reduce((sum, intent) => sum + intent.effort, 0);
|
|
1332
|
+
const dependencyGraph = {};
|
|
1333
|
+
for (const intent of intents) {
|
|
1334
|
+
dependencyGraph[intent.id] = intent.dependencies;
|
|
1335
|
+
}
|
|
1336
|
+
await fs.writeFile(path.join(intentsDir, 'dependency-graph.json'), JSON.stringify(dependencyGraph, null, 2), 'utf-8');
|
|
1337
|
+
console.log(`[WorkflowEngine] Generated ${intents.length} INTENT files`);
|
|
1338
|
+
console.log(`[WorkflowEngine] Total estimated effort: ${totalEffort}h`);
|
|
1339
|
+
// Validate the generated artifacts against SPEC
|
|
1340
|
+
console.log(`[WorkflowEngine] Validating INTENTS against SPEC at: ${specPath}`);
|
|
1341
|
+
const validationResult = await validateTasks(intentsDir, specPath);
|
|
1342
|
+
// Store validation result in checkpoint
|
|
1343
|
+
checkpoint.validation_results.intents = validationResult;
|
|
1344
|
+
if (!validationResult.passed) {
|
|
1345
|
+
console.log('[WorkflowEngine] INTENTS validation failed:', validationResult.blocking_issues);
|
|
1346
|
+
console.log(`[WorkflowEngine] Coverage: ${validationResult.coverage_percentage}%`);
|
|
1347
|
+
}
|
|
1348
|
+
else {
|
|
1349
|
+
console.log('[WorkflowEngine] INTENTS validation passed');
|
|
1350
|
+
console.log(`[WorkflowEngine] Coverage: ${validationResult.coverage_percentage}%`);
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1354
|
+
//# sourceMappingURL=engine.js.map
|