@abhinav2203/codeflow-core 0.1.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.
@@ -0,0 +1,720 @@
1
+ import { z } from "zod";
2
+ export const executionModeSchema = z.enum(["essential", "yolo"]);
3
+ export const blueprintPhaseSchema = z.enum(["spec", "implementation", "integration"]);
4
+ export const nodeStatusSchema = z.enum(["spec_only", "implemented", "verified", "connected"]);
5
+ export const nodeKindSchema = z.enum([
6
+ "module",
7
+ "api",
8
+ "class",
9
+ "function",
10
+ "ui-screen"
11
+ ]);
12
+ export const edgeKindSchema = z.enum([
13
+ "imports",
14
+ "calls",
15
+ "inherits",
16
+ "renders",
17
+ "emits",
18
+ "consumes",
19
+ "reads-state",
20
+ "writes-state"
21
+ ]);
22
+ export const traceStatusSchema = z.enum(["idle", "success", "warning", "error"]);
23
+ export const outputProvenanceSchema = z.enum([
24
+ "deterministic",
25
+ "ai",
26
+ "heuristic",
27
+ "simulated",
28
+ "observed"
29
+ ]);
30
+ export const featureMaturitySchema = z.enum([
31
+ "production",
32
+ "preview",
33
+ "experimental",
34
+ "scaffold"
35
+ ]);
36
+ export const contractFieldSchema = z.object({
37
+ name: z.string(),
38
+ type: z.string(),
39
+ description: z.string().optional()
40
+ });
41
+ export const designCallSchema = z.object({
42
+ target: z.string(),
43
+ kind: z.enum(["calls", "imports", "inherits", "renders", "emits", "consumes", "reads-state", "writes-state"]).optional(),
44
+ description: z.string().optional()
45
+ });
46
+ export const methodSpecSchema = z.object({
47
+ name: z.string(),
48
+ signature: z.string().optional(),
49
+ summary: z.string(),
50
+ inputs: z.array(contractFieldSchema),
51
+ outputs: z.array(contractFieldSchema),
52
+ sideEffects: z.array(z.string()),
53
+ calls: z.array(designCallSchema)
54
+ });
55
+ export const codeContractSchema = z.object({
56
+ summary: z.string(),
57
+ responsibilities: z.array(z.string()),
58
+ inputs: z.array(contractFieldSchema),
59
+ outputs: z.array(contractFieldSchema),
60
+ attributes: z.array(contractFieldSchema),
61
+ methods: z.array(methodSpecSchema),
62
+ sideEffects: z.array(z.string()),
63
+ errors: z.array(z.string()),
64
+ dependencies: z.array(z.string()),
65
+ calls: z.array(designCallSchema),
66
+ uiAccess: z.array(z.string()),
67
+ backendAccess: z.array(z.string()),
68
+ notes: z.array(z.string())
69
+ });
70
+ export const sourceRefSchema = z.object({
71
+ kind: z.enum(["prd", "repo", "generated", "trace"]),
72
+ path: z.string().optional(),
73
+ symbol: z.string().optional(),
74
+ section: z.string().optional(),
75
+ detail: z.string().optional()
76
+ });
77
+ export const traceStateSchema = z.object({
78
+ status: traceStatusSchema,
79
+ count: z.number().int().nonnegative(),
80
+ errors: z.number().int().nonnegative(),
81
+ totalDurationMs: z.number().nonnegative(),
82
+ lastSpanIds: z.array(z.string())
83
+ });
84
+ export const nodeVerificationSchema = z.object({
85
+ verifiedAt: z.string(),
86
+ status: z.enum(["success", "failure"]),
87
+ stdout: z.string(),
88
+ stderr: z.string(),
89
+ exitCode: z.number().optional()
90
+ });
91
+ export const mcpToolSchema = z.object({
92
+ name: z.string(),
93
+ description: z.string().optional(),
94
+ inputSchema: z.record(z.string(), z.unknown()).optional()
95
+ });
96
+ export const mcpServerConfigSchema = z.object({
97
+ serverUrl: z.string().min(1),
98
+ label: z.string().optional(),
99
+ // Reference or label for headers/credentials configuration.
100
+ // Actual secret header values must be managed outside persisted blueprints.
101
+ headersRef: z.string().optional(),
102
+ enabledTools: z.array(z.string()).optional()
103
+ });
104
+ export const mcpToolResultContentSchema = z.object({
105
+ type: z.string(),
106
+ text: z.string().optional()
107
+ });
108
+ export const mcpToolResultSchema = z.object({
109
+ content: z.array(mcpToolResultContentSchema),
110
+ isError: z.boolean().optional()
111
+ });
112
+ export const blueprintNodeSchema = z.object({
113
+ id: z.string(),
114
+ kind: nodeKindSchema,
115
+ name: z.string(),
116
+ summary: z.string(),
117
+ path: z.string().optional(),
118
+ ownerId: z.string().optional(),
119
+ signature: z.string().optional(),
120
+ contract: codeContractSchema,
121
+ sourceRefs: z.array(sourceRefSchema),
122
+ generatedRefs: z.array(z.string()),
123
+ traceRefs: z.array(z.string()),
124
+ traceState: traceStateSchema.optional(),
125
+ status: nodeStatusSchema.default("spec_only"),
126
+ specDraft: z.string().optional(),
127
+ implementationDraft: z.string().optional(),
128
+ lastVerification: nodeVerificationSchema.optional(),
129
+ mcpServers: z.array(mcpServerConfigSchema).optional()
130
+ });
131
+ export const blueprintEdgeSchema = z.object({
132
+ from: z.string(),
133
+ to: z.string(),
134
+ kind: edgeKindSchema,
135
+ label: z.string().optional(),
136
+ required: z.boolean(),
137
+ confidence: z.number().min(0).max(1)
138
+ });
139
+ export const workflowPathSchema = z.object({
140
+ name: z.string(),
141
+ steps: z.array(z.string())
142
+ });
143
+ export const blueprintGraphSchema = z.object({
144
+ projectName: z.string(),
145
+ mode: executionModeSchema,
146
+ phase: blueprintPhaseSchema.default("spec"),
147
+ generatedAt: z.string(),
148
+ nodes: z.array(blueprintNodeSchema),
149
+ edges: z.array(blueprintEdgeSchema),
150
+ workflows: z.array(workflowPathSchema),
151
+ warnings: z.array(z.string())
152
+ });
153
+ export const executionTaskSchema = z.object({
154
+ id: z.string(),
155
+ nodeId: z.string(),
156
+ title: z.string(),
157
+ kind: nodeKindSchema,
158
+ dependsOn: z.array(z.string()),
159
+ ownerPath: z.string().optional(),
160
+ batchIndex: z.number().int().nonnegative()
161
+ });
162
+ export const executionBatchSchema = z.object({
163
+ index: z.number().int().nonnegative(),
164
+ taskIds: z.array(z.string())
165
+ });
166
+ export const executionTaskStatusSchema = z.enum(["pending", "completed", "skipped", "blocked"]);
167
+ export const executionStepKindSchema = z.enum(["node", "method", "edge", "test"]);
168
+ export const executionStepStatusSchema = z.enum([
169
+ "pending",
170
+ "running",
171
+ "passed",
172
+ "failed",
173
+ "blocked",
174
+ "skipped",
175
+ "warning"
176
+ ]);
177
+ export const contractCheckStageSchema = z.enum([
178
+ "input",
179
+ "output",
180
+ "handoff",
181
+ "side-effect",
182
+ "test"
183
+ ]);
184
+ export const contractCheckSchema = z.object({
185
+ stage: contractCheckStageSchema,
186
+ status: z.enum(["passed", "failed", "warning", "skipped"]),
187
+ expected: z.string().optional(),
188
+ actualPreview: z.string().optional(),
189
+ message: z.string()
190
+ });
191
+ export const executionArtifactSchema = z.object({
192
+ id: z.string(),
193
+ sourceNodeId: z.string(),
194
+ targetNodeId: z.string().optional(),
195
+ edgeId: z.string().optional(),
196
+ declaredType: z.string().optional(),
197
+ actualType: z.string().optional(),
198
+ preview: z.string(),
199
+ serializedValue: z.string().optional()
200
+ });
201
+ export const executionStepSchema = z.object({
202
+ id: z.string(),
203
+ runId: z.string(),
204
+ taskId: z.string().optional(),
205
+ kind: executionStepKindSchema,
206
+ nodeId: z.string(),
207
+ parentNodeId: z.string().optional(),
208
+ methodName: z.string().optional(),
209
+ edgeId: z.string().optional(),
210
+ status: executionStepStatusSchema,
211
+ startedAt: z.string(),
212
+ completedAt: z.string(),
213
+ durationMs: z.number().nonnegative(),
214
+ stdout: z.string().default(""),
215
+ stderr: z.string().default(""),
216
+ message: z.string(),
217
+ blockedByStepId: z.string().optional(),
218
+ inputPreview: z.string().optional(),
219
+ outputPreview: z.string().optional(),
220
+ artifactIds: z.array(z.string()).default([]),
221
+ contractChecks: z.array(contractCheckSchema).default([])
222
+ });
223
+ export const executionSummarySchema = z.object({
224
+ passed: z.number().int().nonnegative(),
225
+ failed: z.number().int().nonnegative(),
226
+ blocked: z.number().int().nonnegative(),
227
+ skipped: z.number().int().nonnegative(),
228
+ warning: z.number().int().nonnegative()
229
+ });
230
+ export const runtimeTestCaseSchema = z.object({
231
+ id: z.string(),
232
+ nodeId: z.string(),
233
+ title: z.string(),
234
+ kind: z.enum(["happy-path", "edge-case", "invalid-input"]),
235
+ input: z.string(),
236
+ expectation: z.enum(["pass", "fail", "warning"]),
237
+ notes: z.array(z.string()).default([])
238
+ });
239
+ export const runtimeTestResultSchema = z.object({
240
+ caseId: z.string(),
241
+ title: z.string(),
242
+ kind: runtimeTestCaseSchema.shape.kind,
243
+ status: executionStepStatusSchema,
244
+ message: z.string(),
245
+ stepIds: z.array(z.string()).default([])
246
+ });
247
+ export const runPlanSchema = z.object({
248
+ generatedAt: z.string(),
249
+ tasks: z.array(executionTaskSchema),
250
+ batches: z.array(executionBatchSchema),
251
+ warnings: z.array(z.string())
252
+ });
253
+ export const taskExecutionResultSchema = z.object({
254
+ taskId: z.string(),
255
+ nodeId: z.string(),
256
+ status: executionTaskStatusSchema,
257
+ batchIndex: z.number().int().nonnegative(),
258
+ outputPaths: z.array(z.string()),
259
+ managedRegionIds: z.array(z.string()),
260
+ message: z.string()
261
+ });
262
+ export const ownershipRecordSchema = z.object({
263
+ path: z.string(),
264
+ nodeId: z.string(),
265
+ managedRegionIds: z.array(z.string()),
266
+ generatedAt: z.string()
267
+ });
268
+ export const executionReportSchema = z.object({
269
+ startedAt: z.string(),
270
+ completedAt: z.string(),
271
+ results: z.array(taskExecutionResultSchema),
272
+ ownership: z.array(ownershipRecordSchema),
273
+ steps: z.array(executionStepSchema).default([]),
274
+ artifacts: z.array(executionArtifactSchema).default([]),
275
+ summary: executionSummarySchema.optional()
276
+ });
277
+ export const riskFactorSchema = z.object({
278
+ code: z.string(),
279
+ message: z.string(),
280
+ score: z.number().int().nonnegative()
281
+ });
282
+ export const riskReportSchema = z.object({
283
+ score: z.number().int().nonnegative(),
284
+ level: z.enum(["low", "medium", "high"]),
285
+ requiresApproval: z.boolean(),
286
+ factors: z.array(riskFactorSchema)
287
+ });
288
+ export const approvalRecordSchema = z.object({
289
+ id: z.string(),
290
+ action: z.enum(["export"]),
291
+ projectName: z.string(),
292
+ status: z.enum(["pending", "approved"]),
293
+ fingerprint: z.string(),
294
+ requestedAt: z.string(),
295
+ approvedAt: z.string().optional(),
296
+ outputDir: z.string(),
297
+ runPlan: runPlanSchema,
298
+ riskReport: riskReportSchema
299
+ });
300
+ export const artifactValidationStateSchema = z.enum(["validated", "draft", "scaffold"]);
301
+ export const exportArtifactSchema = z.object({
302
+ nodeId: z.string().optional(),
303
+ nodeName: z.string().optional(),
304
+ nodeKind: nodeKindSchema.optional(),
305
+ relativePath: z.string(),
306
+ artifactType: z.enum(["documentation", "code", "integration", "ownership", "blueprint", "canvas"]),
307
+ validationState: artifactValidationStateSchema,
308
+ provenance: outputProvenanceSchema,
309
+ maturity: featureMaturitySchema,
310
+ generatedAt: z.string(),
311
+ notes: z.array(z.string()).default([])
312
+ });
313
+ export const exportResultSchema = z.object({
314
+ rootDir: z.string(),
315
+ blueprintPath: z.string(),
316
+ canvasPath: z.string(),
317
+ docsDir: z.string(),
318
+ stubsDir: z.string(),
319
+ artifactManifestPath: z.string().optional(),
320
+ artifactSummary: z
321
+ .object({
322
+ total: z.number().int().nonnegative(),
323
+ validated: z.number().int().nonnegative(),
324
+ draft: z.number().int().nonnegative(),
325
+ scaffold: z.number().int().nonnegative()
326
+ })
327
+ .optional(),
328
+ phaseManifestPath: z.string().optional(),
329
+ integrationEntrypointPath: z.string().optional(),
330
+ ownershipPath: z.string().optional(),
331
+ obsidianIndexPath: z.string().optional(),
332
+ diffPath: z.string().optional(),
333
+ sandboxDir: z.string().optional(),
334
+ checkpointDir: z.string().optional()
335
+ });
336
+ export const persistedSessionSchema = z.object({
337
+ sessionId: z.string(),
338
+ projectName: z.string(),
339
+ updatedAt: z.string(),
340
+ graph: blueprintGraphSchema,
341
+ runPlan: runPlanSchema,
342
+ lastRiskReport: riskReportSchema.optional(),
343
+ lastExportResult: exportResultSchema.optional(),
344
+ lastExecutionReport: executionReportSchema.optional(),
345
+ approvalIds: z.array(z.string())
346
+ });
347
+ export const runRecordSchema = z.object({
348
+ id: z.string(),
349
+ projectName: z.string(),
350
+ action: z.enum(["build", "export"]),
351
+ createdAt: z.string(),
352
+ runPlan: runPlanSchema,
353
+ riskReport: riskReportSchema.optional(),
354
+ approvalId: z.string().optional(),
355
+ executionReport: executionReportSchema.optional(),
356
+ exportResult: exportResultSchema.optional()
357
+ });
358
+ export const traceSpanSchema = z.object({
359
+ spanId: z.string(),
360
+ traceId: z.string(),
361
+ name: z.string(),
362
+ blueprintNodeId: z.string().optional(),
363
+ path: z.string().optional(),
364
+ status: z.enum(["success", "warning", "error"]),
365
+ durationMs: z.number().nonnegative(),
366
+ runtime: z.string().default("unknown"),
367
+ provenance: outputProvenanceSchema.default("observed"),
368
+ timestamp: z.string().optional()
369
+ });
370
+ export const observabilityLogSchema = z.object({
371
+ id: z.string(),
372
+ level: z.enum(["debug", "info", "warn", "error"]),
373
+ message: z.string(),
374
+ blueprintNodeId: z.string().optional(),
375
+ path: z.string().optional(),
376
+ runtime: z.string().default("unknown"),
377
+ timestamp: z.string()
378
+ });
379
+ export const observabilityIngestRequestSchema = z.object({
380
+ projectName: z.string().min(1),
381
+ spans: z.array(traceSpanSchema).default([]),
382
+ logs: z.array(observabilityLogSchema).default([])
383
+ });
384
+ export const observabilitySnapshotSchema = z.object({
385
+ projectName: z.string(),
386
+ updatedAt: z.string(),
387
+ spans: z.array(traceSpanSchema),
388
+ logs: z.array(observabilityLogSchema),
389
+ graph: blueprintGraphSchema.optional()
390
+ });
391
+ export const conflictKindSchema = z.enum([
392
+ "missing-in-repo",
393
+ "missing-in-blueprint",
394
+ "signature-mismatch",
395
+ "summary-mismatch"
396
+ ]);
397
+ export const conflictRecordSchema = z.object({
398
+ kind: conflictKindSchema,
399
+ nodeId: z.string().optional(),
400
+ path: z.string().optional(),
401
+ blueprintValue: z.string().optional(),
402
+ repoValue: z.string().optional(),
403
+ message: z.string(),
404
+ suggestedAction: z.string()
405
+ });
406
+ export const conflictReportSchema = z.object({
407
+ checkedAt: z.string(),
408
+ repoPath: z.string(),
409
+ conflicts: z.array(conflictRecordSchema)
410
+ });
411
+ export const conflictCheckRequestSchema = z.object({
412
+ graph: blueprintGraphSchema,
413
+ repoPath: z.string().min(1)
414
+ });
415
+ export const buildBlueprintRequestSchema = z.object({
416
+ projectName: z.string().min(1),
417
+ repoPath: z.string().trim().optional(),
418
+ prdText: z.string().trim().optional(),
419
+ mode: executionModeSchema
420
+ });
421
+ export const exportBlueprintRequestSchema = z.object({
422
+ graph: blueprintGraphSchema,
423
+ outputDir: z.string().trim().optional(),
424
+ approvalId: z.string().trim().optional(),
425
+ codeDrafts: z.record(z.string(), z.string()).optional()
426
+ });
427
+ export const approvalActionRequestSchema = z.object({
428
+ approvalId: z.string().min(1)
429
+ });
430
+ export const runtimeExecutionRequestSchema = z.object({
431
+ graph: blueprintGraphSchema,
432
+ targetNodeId: z.string().optional(), // If running a single node
433
+ input: z.string(), // User prompt/input
434
+ codeDrafts: z.record(z.string(), z.string()).optional(), // For Phase 2, we might pass drafts
435
+ includeGeneratedTests: z.boolean().optional()
436
+ });
437
+ export const runtimeExecutionResultSchema = z.object({
438
+ success: z.boolean(),
439
+ stdout: z.string(),
440
+ stderr: z.string(),
441
+ exitCode: z.number().nullable(),
442
+ durationMs: z.number(),
443
+ executedPath: z.string().optional(),
444
+ error: z.string().optional(),
445
+ runId: z.string().optional(),
446
+ entryNodeId: z.string().optional(),
447
+ steps: z.array(executionStepSchema).default([]),
448
+ artifacts: z.array(executionArtifactSchema).default([]),
449
+ summary: executionSummarySchema.optional(),
450
+ testCases: z.array(runtimeTestCaseSchema).default([]),
451
+ testResults: z.array(runtimeTestResultSchema).default([])
452
+ });
453
+ export const runtimeTestRequestSchema = z.object({
454
+ graph: blueprintGraphSchema,
455
+ nodeId: z.string().min(1),
456
+ seedInput: z.string().optional(),
457
+ codeDrafts: z.record(z.string(), z.string()).optional()
458
+ });
459
+ export const runtimeTestResponseSchema = z.object({
460
+ nodeId: z.string(),
461
+ testCases: z.array(runtimeTestCaseSchema),
462
+ results: z.array(runtimeTestResultSchema).default([]),
463
+ runId: z.string().optional(),
464
+ steps: z.array(executionStepSchema).default([]),
465
+ artifacts: z.array(executionArtifactSchema).default([]),
466
+ summary: executionSummarySchema.optional()
467
+ });
468
+ export const ghostNodeSchema = z.object({
469
+ id: z.string(),
470
+ kind: nodeKindSchema,
471
+ name: z.string(),
472
+ summary: z.string(),
473
+ reason: z.string(),
474
+ provenance: outputProvenanceSchema.default("heuristic"),
475
+ maturity: featureMaturitySchema.default("preview"),
476
+ suggestedEdge: z
477
+ .object({
478
+ from: z.string(),
479
+ to: z.string(),
480
+ kind: edgeKindSchema
481
+ })
482
+ .optional()
483
+ });
484
+ export const ghostSuggestionsResponseSchema = z.object({
485
+ suggestions: z.array(ghostNodeSchema)
486
+ });
487
+ export const emptyContract = () => ({
488
+ summary: "",
489
+ responsibilities: [],
490
+ inputs: [],
491
+ outputs: [],
492
+ attributes: [],
493
+ methods: [],
494
+ sideEffects: [],
495
+ errors: [],
496
+ dependencies: [],
497
+ calls: [],
498
+ uiAccess: [],
499
+ backendAccess: [],
500
+ notes: []
501
+ });
502
+ export const idleTraceState = () => ({
503
+ status: "idle",
504
+ count: 0,
505
+ errors: 0,
506
+ totalDurationMs: 0,
507
+ lastSpanIds: []
508
+ });
509
+ // ── Time-Travel Branching ──────────────────────────────────────────────────
510
+ export const graphBranchSchema = z.object({
511
+ id: z.string(),
512
+ name: z.string().min(1),
513
+ description: z.string().optional(),
514
+ projectName: z.string(),
515
+ parentBranchId: z.string().optional(),
516
+ createdAt: z.string(),
517
+ graph: blueprintGraphSchema
518
+ });
519
+ export const nodeDiffKindSchema = z.enum(["added", "removed", "modified", "unchanged"]);
520
+ export const edgeDiffKindSchema = z.enum(["added", "removed", "unchanged"]);
521
+ export const nodeDiffSchema = z.object({
522
+ nodeId: z.string(),
523
+ name: z.string(),
524
+ kind: nodeDiffKindSchema,
525
+ before: blueprintNodeSchema.optional(),
526
+ after: blueprintNodeSchema.optional(),
527
+ impactedEdgeCount: z.number().int().nonnegative()
528
+ });
529
+ export const edgeDiffSchema = z.object({
530
+ from: z.string(),
531
+ to: z.string(),
532
+ edgeKind: edgeKindSchema,
533
+ diffKind: edgeDiffKindSchema
534
+ });
535
+ export const branchDiffSchema = z.object({
536
+ baseId: z.string(),
537
+ compareId: z.string(),
538
+ addedNodes: z.number().int().nonnegative(),
539
+ removedNodes: z.number().int().nonnegative(),
540
+ modifiedNodes: z.number().int().nonnegative(),
541
+ addedEdges: z.number().int().nonnegative(),
542
+ removedEdges: z.number().int().nonnegative(),
543
+ impactedNodeIds: z.array(z.string()),
544
+ nodeDiffs: z.array(nodeDiffSchema),
545
+ edgeDiffs: z.array(edgeDiffSchema)
546
+ });
547
+ // ── VCR Time-Travel Debugging ─────────────────────────────────────────────────
548
+ /**
549
+ * A single frame in a VCR recording, representing the cumulative state of the
550
+ * architecture graph immediately after a particular trace span was processed.
551
+ */
552
+ export const vcrFrameSchema = z.object({
553
+ /** Zero-based position in the recording timeline. */
554
+ frameIndex: z.number().int().nonnegative(),
555
+ /** The span that produced this frame. */
556
+ spanId: z.string(),
557
+ /** Display label derived from the span name. */
558
+ label: z.string(),
559
+ /** ISO-8601 timestamp when the span occurred (if available). */
560
+ timestamp: z.string().optional(),
561
+ /** The node this span was attributed to (if any). */
562
+ nodeId: z.string().optional(),
563
+ /** Human-readable node name for the UI. */
564
+ nodeName: z.string().optional(),
565
+ /** Status of the span that triggered this frame. */
566
+ status: traceStatusSchema,
567
+ /** Duration of the triggering span in milliseconds. */
568
+ durationMs: z.number().nonnegative(),
569
+ /**
570
+ * Cumulative TraceState for every node at this point in time.
571
+ * Keys are node IDs; absent nodes have idle state.
572
+ */
573
+ nodeStates: z.record(z.string(), traceStateSchema)
574
+ });
575
+ /** A complete VCR recording derived from an observability snapshot. */
576
+ export const vcrRecordingSchema = z.object({
577
+ projectName: z.string(),
578
+ recordedAt: z.string(),
579
+ /** Ordered frames — one per trace span, earliest first. */
580
+ frames: z.array(vcrFrameSchema),
581
+ /** Total number of spans that were processed. */
582
+ totalSpans: z.number().int().nonnegative()
583
+ });
584
+ // ── Digital Twin: Real-Time Production Mirroring ──────────────────────────────
585
+ /**
586
+ * A single named user journey inferred from a group of trace spans that share
587
+ * the same traceId. The steps are the node IDs visited in chronological order.
588
+ */
589
+ export const userFlowSchema = z.object({
590
+ /** The traceId that groups all spans belonging to this flow. */
591
+ traceId: z.string(),
592
+ /** Human-readable name derived from the first span in the flow. */
593
+ name: z.string(),
594
+ /** Ordered list of node IDs visited during this flow. */
595
+ nodeIds: z.array(z.string()),
596
+ /** ISO-8601 timestamp of the first span in the flow. */
597
+ startedAt: z.string().optional(),
598
+ /** ISO-8601 timestamp of the last span in the flow. */
599
+ endedAt: z.string().optional(),
600
+ /** Aggregate status of the flow (worst-case across all spans). */
601
+ status: traceSpanSchema.shape.status,
602
+ /** The dominant provenance across all spans in the flow. */
603
+ provenance: outputProvenanceSchema,
604
+ /** Total wall-clock duration across all spans in the flow, in milliseconds. */
605
+ totalDurationMs: z.number().nonnegative(),
606
+ /** Number of spans in this flow. */
607
+ spanCount: z.number().int().nonnegative()
608
+ });
609
+ /**
610
+ * A point-in-time snapshot of the Digital Twin state: which nodes are active
611
+ * right now and what user flows have been observed.
612
+ */
613
+ export const digitalTwinSnapshotSchema = z.object({
614
+ projectName: z.string(),
615
+ /** ISO-8601 timestamp when this snapshot was computed. */
616
+ computedAt: z.string(),
617
+ /** Digital Twin is a preview surface even when it includes observed traffic. */
618
+ maturity: featureMaturitySchema,
619
+ /**
620
+ * Node IDs that had at least one span within the active time window.
621
+ * The graph itself carries the full trace state; this is the "lit-up" set
622
+ * for the live mirroring overlay.
623
+ */
624
+ activeNodeIds: z.array(z.string()),
625
+ /** All user flows inferred from the current observability snapshot. */
626
+ flows: z.array(userFlowSchema),
627
+ observedSpanCount: z.number().int().nonnegative(),
628
+ simulatedSpanCount: z.number().int().nonnegative(),
629
+ observedFlowCount: z.number().int().nonnegative(),
630
+ simulatedFlowCount: z.number().int().nonnegative(),
631
+ /** The number of seconds used for the "active" time window. */
632
+ activeWindowSecs: z.number().int().positive()
633
+ });
634
+ /**
635
+ * Request body for POST /api/digital-twin/simulate.
636
+ * Describes a user action that should be simulated in the Digital Twin.
637
+ */
638
+ export const simulateActionRequestSchema = z.object({
639
+ projectName: z.string().min(1),
640
+ /**
641
+ * The node IDs to touch in order. Synthetic trace spans are generated for
642
+ * each node and ingested into the observability snapshot so that the live
643
+ * overlay lights up.
644
+ */
645
+ nodeIds: z.array(z.string().min(1)).min(1),
646
+ /** Optional label for the synthetic trace (shown in the VCR/span list). */
647
+ label: z.string().optional(),
648
+ /** Runtime tag applied to the synthetic spans. Defaults to "simulation". */
649
+ runtime: z.string().optional()
650
+ });
651
+ // ── Architectural Genetic Algorithms ─────────────────────────────────────────
652
+ /** The architectural style applied to a generated variant. */
653
+ export const architectureStyleSchema = z.enum(["monolith", "microservices", "serverless"]);
654
+ /** Benchmark scores (0–100, higher is better) for a single architecture variant. */
655
+ export const variantBenchmarkSchema = z.object({
656
+ /** How well the architecture scales under increasing load. */
657
+ scalability: z.number().min(0).max(100),
658
+ /**
659
+ * Cost-efficiency score: 100 = lowest infrastructure cost,
660
+ * 0 = highest infrastructure cost.
661
+ */
662
+ estimatedCostScore: z.number().min(0).max(100),
663
+ /** Predicted runtime performance (latency, throughput). */
664
+ performance: z.number().min(0).max(100),
665
+ /** How easy the codebase is to maintain and extend. */
666
+ maintainability: z.number().min(0).max(100),
667
+ /** Weighted aggregate fitness used for tournament ranking. */
668
+ fitness: z.number().min(0).max(100)
669
+ });
670
+ /** A single architecture variant produced during the evolutionary tournament. */
671
+ export const architectureVariantSchema = z.object({
672
+ /** Unique identifier for this variant. */
673
+ id: z.string(),
674
+ /** The architectural style this variant represents. */
675
+ style: architectureStyleSchema,
676
+ /** Zero-based generation index in which this variant was created. */
677
+ generation: z.number().int().nonnegative(),
678
+ /**
679
+ * The blueprint graph for this variant.
680
+ * Validated using the standard blueprintGraphSchema so structure and
681
+ * defaults (e.g., phase) are consistently applied.
682
+ */
683
+ graph: blueprintGraphSchema,
684
+ /** Computed benchmark scores. */
685
+ benchmark: variantBenchmarkSchema,
686
+ provenance: outputProvenanceSchema,
687
+ maturity: featureMaturitySchema,
688
+ /** 1-based rank within the final ranked population (1 = best). */
689
+ rank: z.number().int().positive()
690
+ });
691
+ /** Complete result of a genetic architecture tournament. */
692
+ export const tournamentResultSchema = z.object({
693
+ projectName: z.string(),
694
+ /** ISO-8601 timestamp when the tournament completed. */
695
+ evolvedAt: z.string(),
696
+ provenance: outputProvenanceSchema,
697
+ maturity: featureMaturitySchema,
698
+ /** Total number of generations that were run. */
699
+ generationCount: z.number().int().positive(),
700
+ /** Number of variants that competed in the tournament. */
701
+ populationSize: z.number().int().positive(),
702
+ /** All variants in the final ranked population, sorted by rank (best first). */
703
+ variants: z.array(architectureVariantSchema),
704
+ /** ID of the winning variant. */
705
+ winnerId: z.string(),
706
+ /** Human-readable summary describing the winning architecture. */
707
+ summary: z.string()
708
+ });
709
+ /** Request body for POST /api/genetic/evolve. */
710
+ export const evolveArchitectureRequestSchema = z.object({
711
+ /** The source blueprint graph to evolve from. */
712
+ graph: blueprintGraphSchema,
713
+ /** Number of evolutionary generations to simulate (default 3, max 10). */
714
+ generations: z.number().int().min(1).max(10).default(3),
715
+ /**
716
+ * Number of variants in the population.
717
+ * Must be at least 3 (one per architectural style) and at most 12.
718
+ */
719
+ populationSize: z.number().int().min(3).max(12).default(6)
720
+ });