@unrdf/kgc-runtime 26.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/IMPLEMENTATION_SUMMARY.json +150 -0
- package/PLUGIN_SYSTEM_SUMMARY.json +149 -0
- package/README.md +98 -0
- package/TRANSACTION_IMPLEMENTATION.json +119 -0
- package/capability-map.md +93 -0
- package/docs/api-stability.md +269 -0
- package/docs/extensions/plugin-development.md +382 -0
- package/package.json +40 -0
- package/plugins/registry.json +35 -0
- package/src/admission-gate.mjs +414 -0
- package/src/api-version.mjs +373 -0
- package/src/atomic-admission.mjs +310 -0
- package/src/bounds.mjs +289 -0
- package/src/bulkhead-manager.mjs +280 -0
- package/src/capsule.mjs +524 -0
- package/src/crdt.mjs +361 -0
- package/src/enhanced-bounds.mjs +614 -0
- package/src/executor.mjs +73 -0
- package/src/freeze-restore.mjs +521 -0
- package/src/index.mjs +62 -0
- package/src/materialized-views.mjs +371 -0
- package/src/merge.mjs +472 -0
- package/src/plugin-isolation.mjs +392 -0
- package/src/plugin-manager.mjs +441 -0
- package/src/projections-api.mjs +336 -0
- package/src/projections-cli.mjs +238 -0
- package/src/projections-docs.mjs +300 -0
- package/src/projections-ide.mjs +278 -0
- package/src/receipt.mjs +340 -0
- package/src/rollback.mjs +258 -0
- package/src/saga-orchestrator.mjs +355 -0
- package/src/schemas.mjs +1330 -0
- package/src/storage-optimization.mjs +359 -0
- package/src/tool-registry.mjs +272 -0
- package/src/transaction.mjs +466 -0
- package/src/validators.mjs +485 -0
- package/src/work-item.mjs +449 -0
- package/templates/plugin-template/README.md +58 -0
- package/templates/plugin-template/index.mjs +162 -0
- package/templates/plugin-template/plugin.json +19 -0
- package/test/admission-gate.test.mjs +583 -0
- package/test/api-version.test.mjs +74 -0
- package/test/atomic-admission.test.mjs +155 -0
- package/test/bounds.test.mjs +341 -0
- package/test/bulkhead-manager.test.mjs +236 -0
- package/test/capsule.test.mjs +625 -0
- package/test/crdt.test.mjs +215 -0
- package/test/enhanced-bounds.test.mjs +487 -0
- package/test/freeze-restore.test.mjs +472 -0
- package/test/materialized-views.test.mjs +243 -0
- package/test/merge.test.mjs +665 -0
- package/test/plugin-isolation.test.mjs +109 -0
- package/test/plugin-manager.test.mjs +208 -0
- package/test/projections-api.test.mjs +293 -0
- package/test/projections-cli.test.mjs +204 -0
- package/test/projections-docs.test.mjs +173 -0
- package/test/projections-ide.test.mjs +230 -0
- package/test/receipt.test.mjs +295 -0
- package/test/rollback.test.mjs +132 -0
- package/test/saga-orchestrator.test.mjs +279 -0
- package/test/schemas.test.mjs +716 -0
- package/test/storage-optimization.test.mjs +503 -0
- package/test/tool-registry.test.mjs +341 -0
- package/test/transaction.test.mjs +189 -0
- package/test/validators.test.mjs +463 -0
- package/test/work-item.test.mjs +548 -0
- package/test/work-item.test.mjs.bak +548 -0
- package/var/kgc/test-atomic-log.json +519 -0
- package/var/kgc/test-cascading-log.json +145 -0
- package/vitest.config.mjs +18 -0
package/src/schemas.mjs
ADDED
|
@@ -0,0 +1,1330 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file KGC Runtime Schemas - Comprehensive Zod validation for governance substrate
|
|
3
|
+
* @module @unrdf/kgc-runtime/schemas
|
|
4
|
+
*
|
|
5
|
+
* @description
|
|
6
|
+
* Type-safe Zod schemas for KGC (Knowledge Graph Computation) governance runtime:
|
|
7
|
+
* - Receipt: Versioned, immutable audit records with cryptographic anchoring
|
|
8
|
+
* - RunCapsule: Δ_run representation capturing input/output/trace/artifacts
|
|
9
|
+
* - ToolTraceEntry: Atomic tool call records for deterministic replay
|
|
10
|
+
* - Bounds: Capacity limits enforcing resource constraints
|
|
11
|
+
* - WorkItem: Async task node states for distributed execution
|
|
12
|
+
* - ProjectionManifest: Surface definitions for CLI/docs/IDE integration
|
|
13
|
+
* - KGCMarkdown AST: Front matter + fenced block structured documents
|
|
14
|
+
*
|
|
15
|
+
* All schemas are v1 format with strict validation and comprehensive examples.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* import { ReceiptSchema, RunCapsuleSchema } from '@unrdf/kgc-runtime/schemas';
|
|
19
|
+
*
|
|
20
|
+
* const receipt = ReceiptSchema.parse({
|
|
21
|
+
* version: '1.0.0',
|
|
22
|
+
* id: crypto.randomUUID(),
|
|
23
|
+
* timestamp: Date.now(),
|
|
24
|
+
* runId: 'run-001',
|
|
25
|
+
* actor: 'agent:orchestrator',
|
|
26
|
+
* action: 'execute',
|
|
27
|
+
* payload: { command: 'test' },
|
|
28
|
+
* });
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
import { z } from 'zod';
|
|
32
|
+
|
|
33
|
+
// =============================================================================
|
|
34
|
+
// Core Type Definitions
|
|
35
|
+
// =============================================================================
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* ISO 8601 timestamp string schema
|
|
39
|
+
* @constant
|
|
40
|
+
*/
|
|
41
|
+
const TimestampSchema = z.coerce.date();
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Semantic version schema (semver)
|
|
45
|
+
* @constant
|
|
46
|
+
*/
|
|
47
|
+
const SemanticVersionSchema = z
|
|
48
|
+
.string()
|
|
49
|
+
.regex(/^\d+\.\d+\.\d+$/, 'Must be semantic version format (x.y.z)');
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* UUID v4 schema
|
|
53
|
+
* @constant
|
|
54
|
+
*/
|
|
55
|
+
const UUIDSchema = z.string().uuid('Must be a valid UUID v4');
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Content-addressable hash schema (SHA-256)
|
|
59
|
+
* @constant
|
|
60
|
+
*/
|
|
61
|
+
const SHA256HashSchema = z
|
|
62
|
+
.string()
|
|
63
|
+
.length(64)
|
|
64
|
+
.regex(/^[a-f0-9]{64}$/, 'Must be a valid SHA-256 hash (64 hex chars)');
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Actor identifier schema (agent:name, user:id, system:component)
|
|
68
|
+
* @constant
|
|
69
|
+
*/
|
|
70
|
+
const ActorIdSchema = z
|
|
71
|
+
.string()
|
|
72
|
+
.regex(/^(agent|user|system):[a-zA-Z0-9_-]+$/, 'Must be formatted as type:identifier');
|
|
73
|
+
|
|
74
|
+
// =============================================================================
|
|
75
|
+
// Receipt Schema - Versioned Immutable Audit Records
|
|
76
|
+
// =============================================================================
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Receipt schema for versioned, immutable audit records
|
|
80
|
+
*
|
|
81
|
+
* Captures complete execution trace with cryptographic anchoring:
|
|
82
|
+
* - Immutable event log (never modified, only appended)
|
|
83
|
+
* - Content-addressable storage (hash-based retrieval)
|
|
84
|
+
* - Cryptographic verification (signatures + merkle proofs)
|
|
85
|
+
* - Version-aware format (v1.0.0 schema)
|
|
86
|
+
* - Actor attribution (who executed what when)
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* {
|
|
90
|
+
* version: '1.0.0',
|
|
91
|
+
* id: '550e8400-e29b-41d4-a716-446655440000',
|
|
92
|
+
* timestamp: 1703001600000,
|
|
93
|
+
* runId: 'run-2024-001',
|
|
94
|
+
* actor: 'agent:orchestrator',
|
|
95
|
+
* action: 'execute_workflow',
|
|
96
|
+
* payload: { workflowId: 'wf-001', input: { x: 42 } },
|
|
97
|
+
* result: { success: true, output: { y: 84 } },
|
|
98
|
+
* contentHash: 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
|
|
99
|
+
* previousHash: 'a1b2c3d4...',
|
|
100
|
+
* signature: {
|
|
101
|
+
* algorithm: 'ed25519',
|
|
102
|
+
* publicKey: '0x1234...',
|
|
103
|
+
* value: '0xabcd...'
|
|
104
|
+
* }
|
|
105
|
+
* }
|
|
106
|
+
*
|
|
107
|
+
* @constant
|
|
108
|
+
* @type {z.ZodObject}
|
|
109
|
+
*/
|
|
110
|
+
export const ReceiptSchema = z.object({
|
|
111
|
+
/** Schema version for forward compatibility */
|
|
112
|
+
version: SemanticVersionSchema.default('1.0.0'),
|
|
113
|
+
/** Unique receipt identifier (UUID v4) */
|
|
114
|
+
id: UUIDSchema,
|
|
115
|
+
/** Receipt creation timestamp (Unix epoch ms) */
|
|
116
|
+
timestamp: z.number().int().positive(),
|
|
117
|
+
/** Associated run/execution identifier */
|
|
118
|
+
runId: z.string().min(1).max(200),
|
|
119
|
+
/** Actor who initiated the action */
|
|
120
|
+
actor: ActorIdSchema,
|
|
121
|
+
/** Action performed (execute, validate, commit, rollback, etc.) */
|
|
122
|
+
action: z.enum([
|
|
123
|
+
'execute',
|
|
124
|
+
'validate',
|
|
125
|
+
'commit',
|
|
126
|
+
'rollback',
|
|
127
|
+
'checkpoint',
|
|
128
|
+
'snapshot',
|
|
129
|
+
'merge',
|
|
130
|
+
'fork',
|
|
131
|
+
]),
|
|
132
|
+
/** Action-specific payload (flexible structure) */
|
|
133
|
+
payload: z.record(z.string(), z.any()),
|
|
134
|
+
/** Execution result (success/failure + output) */
|
|
135
|
+
result: z
|
|
136
|
+
.object({
|
|
137
|
+
success: z.boolean(),
|
|
138
|
+
output: z.any().optional(),
|
|
139
|
+
error: z.string().optional(),
|
|
140
|
+
duration: z.number().nonnegative().optional(),
|
|
141
|
+
})
|
|
142
|
+
.optional(),
|
|
143
|
+
/** SHA-256 hash of receipt content (for integrity) */
|
|
144
|
+
contentHash: SHA256HashSchema.optional(),
|
|
145
|
+
/** Hash of previous receipt (blockchain-style linking) */
|
|
146
|
+
previousHash: SHA256HashSchema.optional().nullable(),
|
|
147
|
+
/** Cryptographic signature for authenticity */
|
|
148
|
+
signature: z
|
|
149
|
+
.object({
|
|
150
|
+
algorithm: z.enum(['ed25519', 'ecdsa', 'rsa']),
|
|
151
|
+
publicKey: z.string().min(1),
|
|
152
|
+
value: z.string().min(1),
|
|
153
|
+
})
|
|
154
|
+
.optional(),
|
|
155
|
+
/** Merkle tree proof for batch verification */
|
|
156
|
+
merkleProof: z
|
|
157
|
+
.object({
|
|
158
|
+
root: SHA256HashSchema,
|
|
159
|
+
path: z.array(SHA256HashSchema),
|
|
160
|
+
index: z.number().int().nonnegative(),
|
|
161
|
+
})
|
|
162
|
+
.optional(),
|
|
163
|
+
/** External anchoring references (git commit, blockchain tx, etc.) */
|
|
164
|
+
anchors: z
|
|
165
|
+
.array(
|
|
166
|
+
z.object({
|
|
167
|
+
type: z.enum(['git', 'blockchain', 'timestamp', 'ipfs']),
|
|
168
|
+
reference: z.string().min(1),
|
|
169
|
+
timestamp: z.number().int().positive().optional(),
|
|
170
|
+
})
|
|
171
|
+
)
|
|
172
|
+
.optional(),
|
|
173
|
+
/** Additional metadata */
|
|
174
|
+
metadata: z.record(z.string(), z.any()).optional(),
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
// =============================================================================
|
|
178
|
+
// ToolTraceEntry Schema - Atomic Tool Call Records
|
|
179
|
+
// =============================================================================
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Tool trace entry schema for atomic tool call records
|
|
183
|
+
*
|
|
184
|
+
* Captures individual tool invocations for:
|
|
185
|
+
* - Deterministic replay (recreate exact execution)
|
|
186
|
+
* - Debugging/audit trails (what happened when)
|
|
187
|
+
* - Performance profiling (tool-level metrics)
|
|
188
|
+
* - Causality tracking (input → output chains)
|
|
189
|
+
*
|
|
190
|
+
* @example
|
|
191
|
+
* {
|
|
192
|
+
* id: '123e4567-e89b-12d3-a456-426614174000',
|
|
193
|
+
* timestamp: 1703001600000,
|
|
194
|
+
* toolName: 'Bash',
|
|
195
|
+
* input: { command: 'npm test', timeout: 5000 },
|
|
196
|
+
* output: { stdout: '✅ All tests passed', stderr: '', exitCode: 0 },
|
|
197
|
+
* duration: 2314,
|
|
198
|
+
* status: 'success',
|
|
199
|
+
* parentId: 'parent-trace-001'
|
|
200
|
+
* }
|
|
201
|
+
*
|
|
202
|
+
* @constant
|
|
203
|
+
* @type {z.ZodObject}
|
|
204
|
+
*/
|
|
205
|
+
export const ToolTraceEntrySchema = z.object({
|
|
206
|
+
/** Unique trace entry identifier */
|
|
207
|
+
id: UUIDSchema,
|
|
208
|
+
/** Tool invocation timestamp (Unix epoch ms) */
|
|
209
|
+
timestamp: z.number().int().positive(),
|
|
210
|
+
/** Tool name (Bash, Read, Write, Grep, etc.) */
|
|
211
|
+
toolName: z.string().min(1).max(100),
|
|
212
|
+
/** Tool input parameters (preserves exact call signature) */
|
|
213
|
+
input: z.record(z.string(), z.any()),
|
|
214
|
+
/** Tool output/result */
|
|
215
|
+
output: z.any().optional(),
|
|
216
|
+
/** Execution duration in milliseconds */
|
|
217
|
+
duration: z.number().nonnegative(),
|
|
218
|
+
/** Execution status */
|
|
219
|
+
status: z.enum(['success', 'error', 'timeout', 'cancelled']),
|
|
220
|
+
/** Error details if status is 'error' */
|
|
221
|
+
error: z
|
|
222
|
+
.object({
|
|
223
|
+
message: z.string(),
|
|
224
|
+
code: z.string().optional(),
|
|
225
|
+
stack: z.string().optional(),
|
|
226
|
+
})
|
|
227
|
+
.optional(),
|
|
228
|
+
/** Parent trace entry (for nested calls) */
|
|
229
|
+
parentId: UUIDSchema.optional().nullable(),
|
|
230
|
+
/** Causal dependencies (trace IDs this call depends on) */
|
|
231
|
+
dependencies: z.array(UUIDSchema).optional(),
|
|
232
|
+
/** Resource usage metrics */
|
|
233
|
+
resources: z
|
|
234
|
+
.object({
|
|
235
|
+
cpuTime: z.number().nonnegative().optional(),
|
|
236
|
+
memoryPeak: z.number().nonnegative().optional(),
|
|
237
|
+
ioBytes: z.number().nonnegative().optional(),
|
|
238
|
+
})
|
|
239
|
+
.optional(),
|
|
240
|
+
/** Metadata (tags, annotations, etc.) */
|
|
241
|
+
metadata: z.record(z.string(), z.any()).optional(),
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
// =============================================================================
|
|
245
|
+
// RunCapsule Schema - Δ_run Representation
|
|
246
|
+
// =============================================================================
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Run capsule schema for complete execution snapshot (Δ_run)
|
|
250
|
+
*
|
|
251
|
+
* Encapsulates entire run lifecycle:
|
|
252
|
+
* - Input: Initial state + parameters
|
|
253
|
+
* - Output: Final results + artifacts
|
|
254
|
+
* - Trace: Execution path (tool calls, decisions)
|
|
255
|
+
* - Artifacts: Generated files, data, proofs
|
|
256
|
+
* - Provenance: Who/what/when/why attribution
|
|
257
|
+
*
|
|
258
|
+
* Enables:
|
|
259
|
+
* - Reproducibility: Re-execute from capsule
|
|
260
|
+
* - Auditing: Complete execution history
|
|
261
|
+
* - Caching: Reuse results for identical inputs
|
|
262
|
+
* - Debugging: Replay with full context
|
|
263
|
+
*
|
|
264
|
+
* @example
|
|
265
|
+
* {
|
|
266
|
+
* id: 'run-2024-12-26-001',
|
|
267
|
+
* version: '1.0.0',
|
|
268
|
+
* startTime: 1703001600000,
|
|
269
|
+
* endTime: 1703001620000,
|
|
270
|
+
* status: 'completed',
|
|
271
|
+
* input: {
|
|
272
|
+
* task: 'implement feature X',
|
|
273
|
+
* parameters: { timeout: 5000 },
|
|
274
|
+
* context: { workingDir: '/home/user/project' }
|
|
275
|
+
* },
|
|
276
|
+
* output: {
|
|
277
|
+
* success: true,
|
|
278
|
+
* results: { filesChanged: 5, testsAdded: 12 },
|
|
279
|
+
* artifacts: [
|
|
280
|
+
* { type: 'file', path: '/home/user/project/src/feature.mjs', hash: 'abc123...' }
|
|
281
|
+
* ]
|
|
282
|
+
* },
|
|
283
|
+
* trace: [
|
|
284
|
+
* { id: 'trace-001', toolName: 'Bash', input: { command: 'npm test' }, ... },
|
|
285
|
+
* { id: 'trace-002', toolName: 'Write', input: { file_path: '...' }, ... }
|
|
286
|
+
* ],
|
|
287
|
+
* bounds: {
|
|
288
|
+
* maxFiles: 100,
|
|
289
|
+
* maxBytes: 10485760,
|
|
290
|
+
* maxOps: 1000,
|
|
291
|
+
* maxRuntime: 300000
|
|
292
|
+
* },
|
|
293
|
+
* actor: 'agent:backend-dev',
|
|
294
|
+
* receipt: { id: 'receipt-001', ... }
|
|
295
|
+
* }
|
|
296
|
+
*
|
|
297
|
+
* @constant
|
|
298
|
+
* @type {z.ZodObject}
|
|
299
|
+
*/
|
|
300
|
+
export const RunCapsuleSchema = z.object({
|
|
301
|
+
/** Unique run identifier */
|
|
302
|
+
id: z.string().min(1).max(200),
|
|
303
|
+
/** Schema version */
|
|
304
|
+
version: SemanticVersionSchema.default('1.0.0'),
|
|
305
|
+
/** Run start timestamp (Unix epoch ms) */
|
|
306
|
+
startTime: z.number().int().positive(),
|
|
307
|
+
/** Run end timestamp (Unix epoch ms, null if in progress) */
|
|
308
|
+
endTime: z.number().int().positive().optional().nullable(),
|
|
309
|
+
/** Run execution status */
|
|
310
|
+
status: z.enum(['pending', 'running', 'completed', 'failed', 'cancelled', 'timeout']),
|
|
311
|
+
/** Input specification */
|
|
312
|
+
input: z.object({
|
|
313
|
+
/** Task description/objective */
|
|
314
|
+
task: z.string().min(1).max(10000),
|
|
315
|
+
/** Execution parameters */
|
|
316
|
+
parameters: z.record(z.string(), z.any()).optional(),
|
|
317
|
+
/** Initial context (env vars, working dir, etc.) */
|
|
318
|
+
context: z.record(z.string(), z.any()).optional(),
|
|
319
|
+
/** Input artifacts/files */
|
|
320
|
+
artifacts: z
|
|
321
|
+
.array(
|
|
322
|
+
z.object({
|
|
323
|
+
type: z.enum(['file', 'directory', 'url', 'inline']),
|
|
324
|
+
path: z.string().optional(),
|
|
325
|
+
content: z.string().optional(),
|
|
326
|
+
hash: SHA256HashSchema.optional(),
|
|
327
|
+
metadata: z.record(z.string(), z.any()).optional(),
|
|
328
|
+
})
|
|
329
|
+
)
|
|
330
|
+
.optional(),
|
|
331
|
+
}),
|
|
332
|
+
/** Output results */
|
|
333
|
+
output: z
|
|
334
|
+
.object({
|
|
335
|
+
/** Whether run succeeded */
|
|
336
|
+
success: z.boolean(),
|
|
337
|
+
/** Structured results */
|
|
338
|
+
results: z.record(z.string(), z.any()).optional(),
|
|
339
|
+
/** Generated artifacts */
|
|
340
|
+
artifacts: z
|
|
341
|
+
.array(
|
|
342
|
+
z.object({
|
|
343
|
+
type: z.enum(['file', 'directory', 'url', 'inline', 'proof', 'receipt']),
|
|
344
|
+
path: z.string().optional(),
|
|
345
|
+
content: z.string().optional(),
|
|
346
|
+
hash: SHA256HashSchema.optional(),
|
|
347
|
+
size: z.number().nonnegative().optional(),
|
|
348
|
+
metadata: z.record(z.string(), z.any()).optional(),
|
|
349
|
+
})
|
|
350
|
+
)
|
|
351
|
+
.optional(),
|
|
352
|
+
/** Error information if failed */
|
|
353
|
+
error: z
|
|
354
|
+
.object({
|
|
355
|
+
message: z.string(),
|
|
356
|
+
code: z.string().optional(),
|
|
357
|
+
stack: z.string().optional(),
|
|
358
|
+
recoverable: z.boolean().optional(),
|
|
359
|
+
})
|
|
360
|
+
.optional(),
|
|
361
|
+
})
|
|
362
|
+
.optional(),
|
|
363
|
+
/** Execution trace (ordered tool calls) */
|
|
364
|
+
trace: z.array(ToolTraceEntrySchema).optional(),
|
|
365
|
+
/** Resource bounds enforced during execution */
|
|
366
|
+
bounds: z
|
|
367
|
+
.object({
|
|
368
|
+
maxFiles: z.number().int().positive().optional(),
|
|
369
|
+
maxBytes: z.number().int().positive().optional(),
|
|
370
|
+
maxOps: z.number().int().positive().optional(),
|
|
371
|
+
maxRuntime: z.number().int().positive().optional(),
|
|
372
|
+
maxGraphRewrites: z.number().int().positive().optional(),
|
|
373
|
+
})
|
|
374
|
+
.optional(),
|
|
375
|
+
/** Actor who initiated the run */
|
|
376
|
+
actor: ActorIdSchema,
|
|
377
|
+
/** Associated receipt */
|
|
378
|
+
receipt: ReceiptSchema.optional(),
|
|
379
|
+
/** Provenance chain (parent runs, dependencies) */
|
|
380
|
+
provenance: z
|
|
381
|
+
.object({
|
|
382
|
+
parentRunId: z.string().optional(),
|
|
383
|
+
dependencies: z.array(z.string()).optional(),
|
|
384
|
+
derivedFrom: z.array(z.string()).optional(),
|
|
385
|
+
})
|
|
386
|
+
.optional(),
|
|
387
|
+
/** Checkpoints for long-running tasks */
|
|
388
|
+
checkpoints: z
|
|
389
|
+
.array(
|
|
390
|
+
z.object({
|
|
391
|
+
id: UUIDSchema,
|
|
392
|
+
timestamp: z.number().int().positive(),
|
|
393
|
+
state: z.record(z.string(), z.any()),
|
|
394
|
+
progress: z.number().min(0).max(1).optional(),
|
|
395
|
+
})
|
|
396
|
+
)
|
|
397
|
+
.optional(),
|
|
398
|
+
/** Metadata */
|
|
399
|
+
metadata: z.record(z.string(), z.any()).optional(),
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
// =============================================================================
|
|
403
|
+
// Bounds Schema - Capacity Limits
|
|
404
|
+
// =============================================================================
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* Bounds schema for resource capacity limits
|
|
408
|
+
*
|
|
409
|
+
* Enforces governance constraints:
|
|
410
|
+
* - File limits: Max number of files created/modified
|
|
411
|
+
* - Byte limits: Max storage used
|
|
412
|
+
* - Operation limits: Max tool calls/graph operations
|
|
413
|
+
* - Runtime limits: Max execution time
|
|
414
|
+
* - Graph rewrite limits: Max structural changes to knowledge graph
|
|
415
|
+
*
|
|
416
|
+
* Prevents:
|
|
417
|
+
* - Resource exhaustion attacks
|
|
418
|
+
* - Runaway processes
|
|
419
|
+
* - Storage abuse
|
|
420
|
+
* - Performance degradation
|
|
421
|
+
*
|
|
422
|
+
* @example
|
|
423
|
+
* {
|
|
424
|
+
* maxFiles: 100,
|
|
425
|
+
* maxBytes: 10485760, // 10 MB
|
|
426
|
+
* maxOps: 1000,
|
|
427
|
+
* maxRuntime: 300000, // 5 minutes
|
|
428
|
+
* maxGraphRewrites: 50,
|
|
429
|
+
* enforcementPolicy: 'strict',
|
|
430
|
+
* warnings: {
|
|
431
|
+
* filesThreshold: 0.8,
|
|
432
|
+
* bytesThreshold: 0.9,
|
|
433
|
+
* opsThreshold: 0.75,
|
|
434
|
+
* runtimeThreshold: 0.9
|
|
435
|
+
* }
|
|
436
|
+
* }
|
|
437
|
+
*
|
|
438
|
+
* @constant
|
|
439
|
+
* @type {z.ZodObject}
|
|
440
|
+
*/
|
|
441
|
+
export const BoundsSchema = z.object({
|
|
442
|
+
/** Maximum number of files that can be created/modified */
|
|
443
|
+
maxFiles: z.number().int().positive().max(10000).default(100),
|
|
444
|
+
/** Maximum total bytes that can be written */
|
|
445
|
+
maxBytes: z
|
|
446
|
+
.number()
|
|
447
|
+
.int()
|
|
448
|
+
.positive()
|
|
449
|
+
.max(1024 * 1024 * 1024)
|
|
450
|
+
.default(10 * 1024 * 1024), // 10 MB
|
|
451
|
+
/** Maximum number of operations/tool calls */
|
|
452
|
+
maxOps: z.number().int().positive().max(100000).default(1000),
|
|
453
|
+
/** Maximum runtime in milliseconds */
|
|
454
|
+
maxRuntime: z.number().int().positive().max(3600000).default(300000), // 5 minutes
|
|
455
|
+
/** Maximum graph structure rewrites */
|
|
456
|
+
maxGraphRewrites: z.number().int().positive().max(1000).default(50),
|
|
457
|
+
/** Enforcement policy */
|
|
458
|
+
enforcementPolicy: z.enum(['strict', 'soft', 'monitor']).default('strict'),
|
|
459
|
+
/** Warning thresholds (0.0-1.0 as fraction of limit) */
|
|
460
|
+
warnings: z
|
|
461
|
+
.object({
|
|
462
|
+
filesThreshold: z.number().min(0).max(1).default(0.8),
|
|
463
|
+
bytesThreshold: z.number().min(0).max(1).default(0.9),
|
|
464
|
+
opsThreshold: z.number().min(0).max(1).default(0.75),
|
|
465
|
+
runtimeThreshold: z.number().min(0).max(1).default(0.9),
|
|
466
|
+
graphRewritesThreshold: z.number().min(0).max(1).default(0.8),
|
|
467
|
+
})
|
|
468
|
+
.optional(),
|
|
469
|
+
/** Current usage (for monitoring) */
|
|
470
|
+
currentUsage: z
|
|
471
|
+
.object({
|
|
472
|
+
files: z.number().int().nonnegative().default(0),
|
|
473
|
+
bytes: z.number().int().nonnegative().default(0),
|
|
474
|
+
ops: z.number().int().nonnegative().default(0),
|
|
475
|
+
runtime: z.number().nonnegative().default(0),
|
|
476
|
+
graphRewrites: z.number().int().nonnegative().default(0),
|
|
477
|
+
})
|
|
478
|
+
.optional(),
|
|
479
|
+
/** Metadata */
|
|
480
|
+
metadata: z.record(z.string(), z.any()).optional(),
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
// =============================================================================
|
|
484
|
+
// WorkItem Schema - Async Task Node States
|
|
485
|
+
// =============================================================================
|
|
486
|
+
|
|
487
|
+
/**
|
|
488
|
+
* Work item schema for async task node states
|
|
489
|
+
*
|
|
490
|
+
* Represents distributed task execution:
|
|
491
|
+
* - State machine: queued → running → succeeded/failed/denied
|
|
492
|
+
* - Priority queue: Higher priority = earlier execution
|
|
493
|
+
* - Dependencies: Task dependencies graph (DAG)
|
|
494
|
+
* - Retries: Automatic retry with exponential backoff
|
|
495
|
+
* - Timeout: Per-task execution time limits
|
|
496
|
+
*
|
|
497
|
+
* State transitions:
|
|
498
|
+
* - queued: Waiting for execution slot
|
|
499
|
+
* - running: Currently executing
|
|
500
|
+
* - succeeded: Completed successfully
|
|
501
|
+
* - failed: Failed (may retry if retries remain)
|
|
502
|
+
* - denied: Governance policy denied execution
|
|
503
|
+
*
|
|
504
|
+
* @example
|
|
505
|
+
* {
|
|
506
|
+
* id: 'work-001',
|
|
507
|
+
* type: 'file_operation',
|
|
508
|
+
* state: 'running',
|
|
509
|
+
* priority: 75,
|
|
510
|
+
* createdAt: 1703001600000,
|
|
511
|
+
* startedAt: 1703001605000,
|
|
512
|
+
* payload: {
|
|
513
|
+
* operation: 'write',
|
|
514
|
+
* path: '/home/user/file.txt',
|
|
515
|
+
* content: 'Hello World'
|
|
516
|
+
* },
|
|
517
|
+
* dependencies: ['work-000'],
|
|
518
|
+
* retries: { max: 3, current: 0, backoff: 'exponential' },
|
|
519
|
+
* timeout: 30000,
|
|
520
|
+
* assignedTo: 'agent:worker-01'
|
|
521
|
+
* }
|
|
522
|
+
*
|
|
523
|
+
* @constant
|
|
524
|
+
* @type {z.ZodObject}
|
|
525
|
+
*/
|
|
526
|
+
export const WorkItemSchema = z.object({
|
|
527
|
+
/** Unique work item identifier */
|
|
528
|
+
id: UUIDSchema,
|
|
529
|
+
/** Work item type/category */
|
|
530
|
+
type: z.string().min(1).max(100),
|
|
531
|
+
/** Current state */
|
|
532
|
+
state: z.enum(['queued', 'running', 'succeeded', 'failed', 'denied', 'cancelled']),
|
|
533
|
+
/** Priority (0-100, higher = more important) */
|
|
534
|
+
priority: z.number().int().min(0).max(100).default(50),
|
|
535
|
+
/** Creation timestamp (Unix epoch ms) */
|
|
536
|
+
createdAt: z.number().int().positive(),
|
|
537
|
+
/** Start timestamp (when state became 'running') */
|
|
538
|
+
startedAt: z.number().int().positive().optional().nullable(),
|
|
539
|
+
/** Completion timestamp (when state became terminal) */
|
|
540
|
+
completedAt: z.number().int().positive().optional().nullable(),
|
|
541
|
+
/** Work item payload (task-specific data) */
|
|
542
|
+
payload: z.record(z.string(), z.any()),
|
|
543
|
+
/** Work item result (populated on completion) */
|
|
544
|
+
result: z.any().optional(),
|
|
545
|
+
/** Error information if failed */
|
|
546
|
+
error: z
|
|
547
|
+
.object({
|
|
548
|
+
message: z.string(),
|
|
549
|
+
code: z.string().optional(),
|
|
550
|
+
stack: z.string().optional(),
|
|
551
|
+
retryable: z.boolean().default(true),
|
|
552
|
+
})
|
|
553
|
+
.optional(),
|
|
554
|
+
/** Dependency work item IDs (must complete before this can run) */
|
|
555
|
+
dependencies: z.array(UUIDSchema).optional(),
|
|
556
|
+
/** Retry configuration */
|
|
557
|
+
retries: z
|
|
558
|
+
.object({
|
|
559
|
+
max: z.number().int().nonnegative().max(10).default(3),
|
|
560
|
+
current: z.number().int().nonnegative().default(0),
|
|
561
|
+
backoff: z.enum(['constant', 'linear', 'exponential']).default('exponential'),
|
|
562
|
+
delay: z.number().int().positive().default(1000), // Base delay in ms
|
|
563
|
+
})
|
|
564
|
+
.optional(),
|
|
565
|
+
/** Execution timeout (milliseconds) */
|
|
566
|
+
timeout: z.number().int().positive().max(3600000).default(30000),
|
|
567
|
+
/** Agent/worker assigned to execute this work item */
|
|
568
|
+
assignedTo: ActorIdSchema.optional().nullable(),
|
|
569
|
+
/** Governance policy evaluation result */
|
|
570
|
+
policyEvaluation: z
|
|
571
|
+
.object({
|
|
572
|
+
allowed: z.boolean(),
|
|
573
|
+
reason: z.string().optional(),
|
|
574
|
+
constraints: z.record(z.string(), z.any()).optional(),
|
|
575
|
+
})
|
|
576
|
+
.optional(),
|
|
577
|
+
/** Progress tracking (0.0-1.0) */
|
|
578
|
+
progress: z.number().min(0).max(1).optional(),
|
|
579
|
+
/** Metadata */
|
|
580
|
+
metadata: z.record(z.string(), z.any()).optional(),
|
|
581
|
+
});
|
|
582
|
+
|
|
583
|
+
// =============================================================================
|
|
584
|
+
// ProjectionManifest Schema - Surface Definitions
|
|
585
|
+
// =============================================================================
|
|
586
|
+
|
|
587
|
+
/**
|
|
588
|
+
* Projection manifest schema for surface definitions
|
|
589
|
+
*
|
|
590
|
+
* Defines how KGC runtime projects to different surfaces:
|
|
591
|
+
* - CLI: Command-line interface configuration
|
|
592
|
+
* - Docs: Documentation generation settings
|
|
593
|
+
* - IDE: Editor integration (LSP, snippets, etc.)
|
|
594
|
+
* - API: HTTP/GraphQL endpoints
|
|
595
|
+
* - UI: Web dashboard configuration
|
|
596
|
+
*
|
|
597
|
+
* Enables multi-surface governance:
|
|
598
|
+
* - Consistent UX across interfaces
|
|
599
|
+
* - Auto-generated integrations
|
|
600
|
+
* - Policy-driven access control
|
|
601
|
+
* - Version-aware compatibility
|
|
602
|
+
*
|
|
603
|
+
* @example
|
|
604
|
+
* {
|
|
605
|
+
* version: '1.0.0',
|
|
606
|
+
* surfaces: {
|
|
607
|
+
* cli: {
|
|
608
|
+
* commands: [
|
|
609
|
+
* {
|
|
610
|
+
* name: 'run',
|
|
611
|
+
* description: 'Execute a workflow',
|
|
612
|
+
* options: [{ name: 'file', required: true, type: 'string' }]
|
|
613
|
+
* }
|
|
614
|
+
* ]
|
|
615
|
+
* },
|
|
616
|
+
* docs: {
|
|
617
|
+
* generator: 'typedoc',
|
|
618
|
+
* outputDir: './docs',
|
|
619
|
+
* includes: ['**\/*.mjs'],
|
|
620
|
+
* theme: 'default'
|
|
621
|
+
* },
|
|
622
|
+
* ide: {
|
|
623
|
+
* lsp: { enabled: true, port: 9000 },
|
|
624
|
+
* snippets: [
|
|
625
|
+
* { prefix: 'run', body: 'RunCapsuleSchema.parse({ ... })' }
|
|
626
|
+
* ]
|
|
627
|
+
* }
|
|
628
|
+
* }
|
|
629
|
+
* }
|
|
630
|
+
*
|
|
631
|
+
* @constant
|
|
632
|
+
* @type {z.ZodObject}
|
|
633
|
+
*/
|
|
634
|
+
export const ProjectionManifestSchema = z.object({
|
|
635
|
+
/** Schema version */
|
|
636
|
+
version: SemanticVersionSchema.default('1.0.0'),
|
|
637
|
+
/** Surface definitions */
|
|
638
|
+
surfaces: z.object({
|
|
639
|
+
/** CLI surface configuration */
|
|
640
|
+
cli: z
|
|
641
|
+
.object({
|
|
642
|
+
commands: z
|
|
643
|
+
.array(
|
|
644
|
+
z.object({
|
|
645
|
+
name: z.string().min(1).max(100),
|
|
646
|
+
description: z.string().max(500).optional(),
|
|
647
|
+
aliases: z.array(z.string()).optional(),
|
|
648
|
+
options: z
|
|
649
|
+
.array(
|
|
650
|
+
z.object({
|
|
651
|
+
name: z.string().min(1),
|
|
652
|
+
type: z.enum(['string', 'number', 'boolean', 'array']),
|
|
653
|
+
required: z.boolean().default(false),
|
|
654
|
+
default: z.any().optional(),
|
|
655
|
+
description: z.string().optional(),
|
|
656
|
+
})
|
|
657
|
+
)
|
|
658
|
+
.optional(),
|
|
659
|
+
examples: z.array(z.string()).optional(),
|
|
660
|
+
})
|
|
661
|
+
)
|
|
662
|
+
.optional(),
|
|
663
|
+
globalOptions: z.record(z.string(), z.any()).optional(),
|
|
664
|
+
})
|
|
665
|
+
.optional(),
|
|
666
|
+
/** Documentation surface configuration */
|
|
667
|
+
docs: z
|
|
668
|
+
.object({
|
|
669
|
+
generator: z.enum(['typedoc', 'jsdoc', 'docusaurus', 'mkdocs']).optional(),
|
|
670
|
+
outputDir: z.string().default('./docs'),
|
|
671
|
+
includes: z.array(z.string()).optional(),
|
|
672
|
+
excludes: z.array(z.string()).optional(),
|
|
673
|
+
theme: z.string().optional(),
|
|
674
|
+
navigation: z
|
|
675
|
+
.array(
|
|
676
|
+
z.object({
|
|
677
|
+
title: z.string(),
|
|
678
|
+
path: z.string(),
|
|
679
|
+
children: z.array(z.any()).optional(),
|
|
680
|
+
})
|
|
681
|
+
)
|
|
682
|
+
.optional(),
|
|
683
|
+
})
|
|
684
|
+
.optional(),
|
|
685
|
+
/** IDE surface configuration */
|
|
686
|
+
ide: z
|
|
687
|
+
.object({
|
|
688
|
+
lsp: z
|
|
689
|
+
.object({
|
|
690
|
+
enabled: z.boolean().default(true),
|
|
691
|
+
port: z.number().int().positive().default(9000),
|
|
692
|
+
features: z
|
|
693
|
+
.array(z.enum(['completion', 'hover', 'goto', 'diagnostics', 'formatting']))
|
|
694
|
+
.optional(),
|
|
695
|
+
})
|
|
696
|
+
.optional(),
|
|
697
|
+
snippets: z
|
|
698
|
+
.array(
|
|
699
|
+
z.object({
|
|
700
|
+
prefix: z.string().min(1),
|
|
701
|
+
body: z.string().min(1),
|
|
702
|
+
description: z.string().optional(),
|
|
703
|
+
scope: z.string().optional(),
|
|
704
|
+
})
|
|
705
|
+
)
|
|
706
|
+
.optional(),
|
|
707
|
+
schemas: z
|
|
708
|
+
.array(
|
|
709
|
+
z.object({
|
|
710
|
+
fileMatch: z.array(z.string()),
|
|
711
|
+
schema: z.record(z.string(), z.any()),
|
|
712
|
+
})
|
|
713
|
+
)
|
|
714
|
+
.optional(),
|
|
715
|
+
})
|
|
716
|
+
.optional(),
|
|
717
|
+
/** API surface configuration */
|
|
718
|
+
api: z
|
|
719
|
+
.object({
|
|
720
|
+
type: z.enum(['rest', 'graphql', 'grpc']).default('rest'),
|
|
721
|
+
baseUrl: z.string().url().optional(),
|
|
722
|
+
endpoints: z
|
|
723
|
+
.array(
|
|
724
|
+
z.object({
|
|
725
|
+
path: z.string(),
|
|
726
|
+
method: z.enum(['GET', 'POST', 'PUT', 'DELETE', 'PATCH']).optional(),
|
|
727
|
+
schema: z.record(z.string(), z.any()).optional(),
|
|
728
|
+
auth: z.enum(['none', 'bearer', 'api-key', 'oauth2']).optional(),
|
|
729
|
+
})
|
|
730
|
+
)
|
|
731
|
+
.optional(),
|
|
732
|
+
versioning: z
|
|
733
|
+
.object({
|
|
734
|
+
strategy: z.enum(['url', 'header', 'query']),
|
|
735
|
+
current: z.string(),
|
|
736
|
+
})
|
|
737
|
+
.optional(),
|
|
738
|
+
})
|
|
739
|
+
.optional(),
|
|
740
|
+
/** UI surface configuration */
|
|
741
|
+
ui: z
|
|
742
|
+
.object({
|
|
743
|
+
type: z.enum(['web', 'desktop', 'mobile']).default('web'),
|
|
744
|
+
framework: z.string().optional(),
|
|
745
|
+
routes: z
|
|
746
|
+
.array(
|
|
747
|
+
z.object({
|
|
748
|
+
path: z.string(),
|
|
749
|
+
component: z.string(),
|
|
750
|
+
title: z.string().optional(),
|
|
751
|
+
})
|
|
752
|
+
)
|
|
753
|
+
.optional(),
|
|
754
|
+
theme: z.record(z.string(), z.any()).optional(),
|
|
755
|
+
})
|
|
756
|
+
.optional(),
|
|
757
|
+
}),
|
|
758
|
+
/** Access control per surface */
|
|
759
|
+
accessControl: z
|
|
760
|
+
.object({
|
|
761
|
+
default: z.enum(['allow', 'deny']).default('allow'),
|
|
762
|
+
rules: z
|
|
763
|
+
.array(
|
|
764
|
+
z.object({
|
|
765
|
+
surface: z.string(),
|
|
766
|
+
action: z.string(),
|
|
767
|
+
allowed: z.boolean(),
|
|
768
|
+
roles: z.array(z.string()).optional(),
|
|
769
|
+
})
|
|
770
|
+
)
|
|
771
|
+
.optional(),
|
|
772
|
+
})
|
|
773
|
+
.optional(),
|
|
774
|
+
/** Metadata */
|
|
775
|
+
metadata: z.record(z.string(), z.any()).optional(),
|
|
776
|
+
});
|
|
777
|
+
|
|
778
|
+
// =============================================================================
|
|
779
|
+
// KGCMarkdown AST Schema - Front Matter + Fenced Blocks
|
|
780
|
+
// =============================================================================
|
|
781
|
+
|
|
782
|
+
/**
|
|
783
|
+
* KGC Markdown AST node schema
|
|
784
|
+
*
|
|
785
|
+
* Structured representation of KGC-flavored markdown:
|
|
786
|
+
* - Front matter: YAML metadata block
|
|
787
|
+
* - Fenced blocks: Code blocks with type annotations
|
|
788
|
+
* - Content blocks: Prose, lists, tables
|
|
789
|
+
* - Semantic annotations: RDF/semantic web metadata
|
|
790
|
+
*
|
|
791
|
+
* Supports:
|
|
792
|
+
* - Literate programming (code + docs interleaved)
|
|
793
|
+
* - Executable notebooks (runnable code blocks)
|
|
794
|
+
* - Semantic documentation (RDF-annotated content)
|
|
795
|
+
* - Multi-format export (HTML, PDF, slides)
|
|
796
|
+
*
|
|
797
|
+
* @example
|
|
798
|
+
* {
|
|
799
|
+
* type: 'document',
|
|
800
|
+
* frontMatter: {
|
|
801
|
+
* title: 'KGC Example',
|
|
802
|
+
* version: '1.0.0',
|
|
803
|
+
* ontology: ['http://schema.org/']
|
|
804
|
+
* },
|
|
805
|
+
* children: [
|
|
806
|
+
* {
|
|
807
|
+
* type: 'heading',
|
|
808
|
+
* level: 1,
|
|
809
|
+
* content: 'Introduction',
|
|
810
|
+
* id: 'intro',
|
|
811
|
+
* metadata: {}
|
|
812
|
+
* },
|
|
813
|
+
* {
|
|
814
|
+
* type: 'fenced-block',
|
|
815
|
+
* language: 'javascript',
|
|
816
|
+
* attributes: { executable: true, output: 'inline' },
|
|
817
|
+
* content: 'console.log("Hello KGC");',
|
|
818
|
+
* metadata: { runId: 'run-001' }
|
|
819
|
+
* },
|
|
820
|
+
* {
|
|
821
|
+
* type: 'paragraph',
|
|
822
|
+
* content: 'This is a paragraph with **bold** text.',
|
|
823
|
+
* semanticAnnotations: [
|
|
824
|
+
* {
|
|
825
|
+
* predicate: 'http://schema.org/description',
|
|
826
|
+
* object: 'Introduction paragraph'
|
|
827
|
+
* }
|
|
828
|
+
* ]
|
|
829
|
+
* }
|
|
830
|
+
* ],
|
|
831
|
+
* metadata: {}
|
|
832
|
+
* }
|
|
833
|
+
*
|
|
834
|
+
* @constant
|
|
835
|
+
* @type {z.ZodObject}
|
|
836
|
+
*/
|
|
837
|
+
|
|
838
|
+
// Define base node schema (all AST nodes share these properties)
|
|
839
|
+
const BaseASTNodeSchema = z.object({
|
|
840
|
+
/** Node type */
|
|
841
|
+
type: z.string().min(1),
|
|
842
|
+
/** Node metadata */
|
|
843
|
+
metadata: z.record(z.string(), z.any()).optional(),
|
|
844
|
+
});
|
|
845
|
+
|
|
846
|
+
// Recursive AST node schema (allows nested children)
|
|
847
|
+
const ASTNodeSchema = BaseASTNodeSchema.extend({
|
|
848
|
+
/** Text content (for leaf nodes) */
|
|
849
|
+
content: z.string().optional(),
|
|
850
|
+
/** Child nodes (for container nodes) */
|
|
851
|
+
children: z.lazy(() => z.array(ASTNodeSchema).optional()),
|
|
852
|
+
});
|
|
853
|
+
|
|
854
|
+
/**
|
|
855
|
+
* KGC Markdown document AST schema
|
|
856
|
+
*/
|
|
857
|
+
export const KGCMarkdownSchema = z.object({
|
|
858
|
+
/** Root node type */
|
|
859
|
+
type: z.literal('document'),
|
|
860
|
+
/** Front matter (YAML metadata) */
|
|
861
|
+
frontMatter: z
|
|
862
|
+
.object({
|
|
863
|
+
title: z.string().max(200).optional(),
|
|
864
|
+
version: SemanticVersionSchema.optional(),
|
|
865
|
+
author: z.string().max(100).optional(),
|
|
866
|
+
date: TimestampSchema.optional(),
|
|
867
|
+
ontology: z.array(z.string().url()).optional(),
|
|
868
|
+
tags: z.array(z.string()).optional(),
|
|
869
|
+
custom: z.record(z.string(), z.any()).optional(),
|
|
870
|
+
})
|
|
871
|
+
.optional(),
|
|
872
|
+
/** Document child nodes */
|
|
873
|
+
children: z.array(
|
|
874
|
+
z.discriminatedUnion('type', [
|
|
875
|
+
// Heading node
|
|
876
|
+
BaseASTNodeSchema.extend({
|
|
877
|
+
type: z.literal('heading'),
|
|
878
|
+
level: z.number().int().min(1).max(6),
|
|
879
|
+
content: z.string().min(1),
|
|
880
|
+
id: z.string().optional(),
|
|
881
|
+
}),
|
|
882
|
+
// Paragraph node
|
|
883
|
+
BaseASTNodeSchema.extend({
|
|
884
|
+
type: z.literal('paragraph'),
|
|
885
|
+
content: z.string(),
|
|
886
|
+
semanticAnnotations: z
|
|
887
|
+
.array(
|
|
888
|
+
z.object({
|
|
889
|
+
predicate: z.string().url(),
|
|
890
|
+
object: z.string(),
|
|
891
|
+
datatype: z.string().optional(),
|
|
892
|
+
})
|
|
893
|
+
)
|
|
894
|
+
.optional(),
|
|
895
|
+
}),
|
|
896
|
+
// Fenced block node (code blocks)
|
|
897
|
+
BaseASTNodeSchema.extend({
|
|
898
|
+
type: z.literal('fenced-block'),
|
|
899
|
+
language: z.string().max(50).optional(),
|
|
900
|
+
attributes: z.record(z.string(), z.any()).optional(),
|
|
901
|
+
content: z.string(),
|
|
902
|
+
output: z.string().optional(),
|
|
903
|
+
executable: z.boolean().default(false),
|
|
904
|
+
}),
|
|
905
|
+
// List node
|
|
906
|
+
BaseASTNodeSchema.extend({
|
|
907
|
+
type: z.literal('list'),
|
|
908
|
+
ordered: z.boolean().default(false),
|
|
909
|
+
items: z.array(z.string()),
|
|
910
|
+
}),
|
|
911
|
+
// Table node
|
|
912
|
+
BaseASTNodeSchema.extend({
|
|
913
|
+
type: z.literal('table'),
|
|
914
|
+
headers: z.array(z.string()).optional(),
|
|
915
|
+
rows: z.array(z.array(z.string())),
|
|
916
|
+
alignment: z.array(z.enum(['left', 'center', 'right'])).optional(),
|
|
917
|
+
}),
|
|
918
|
+
// Link node
|
|
919
|
+
BaseASTNodeSchema.extend({
|
|
920
|
+
type: z.literal('link'),
|
|
921
|
+
url: z.string().url(),
|
|
922
|
+
text: z.string(),
|
|
923
|
+
title: z.string().optional(),
|
|
924
|
+
}),
|
|
925
|
+
// Image node
|
|
926
|
+
BaseASTNodeSchema.extend({
|
|
927
|
+
type: z.literal('image'),
|
|
928
|
+
url: z.string().url(),
|
|
929
|
+
alt: z.string().optional(),
|
|
930
|
+
title: z.string().optional(),
|
|
931
|
+
width: z.number().int().positive().optional(),
|
|
932
|
+
height: z.number().int().positive().optional(),
|
|
933
|
+
}),
|
|
934
|
+
// Blockquote node
|
|
935
|
+
BaseASTNodeSchema.extend({
|
|
936
|
+
type: z.literal('blockquote'),
|
|
937
|
+
content: z.string(),
|
|
938
|
+
}),
|
|
939
|
+
])
|
|
940
|
+
),
|
|
941
|
+
/** Document metadata */
|
|
942
|
+
metadata: z.record(z.string(), z.any()).optional(),
|
|
943
|
+
});
|
|
944
|
+
|
|
945
|
+
// =============================================================================
|
|
946
|
+
// Validation Helper Functions
|
|
947
|
+
// =============================================================================
|
|
948
|
+
|
|
949
|
+
/**
|
|
950
|
+
* Validate a receipt
|
|
951
|
+
* @param {any} receipt - The receipt to validate
|
|
952
|
+
* @returns {Object} Validation result { success, data, errors }
|
|
953
|
+
*/
|
|
954
|
+
export function validateReceipt(receipt) {
|
|
955
|
+
try {
|
|
956
|
+
const validated = ReceiptSchema.parse(receipt);
|
|
957
|
+
return { success: true, data: validated, errors: [] };
|
|
958
|
+
} catch (error) {
|
|
959
|
+
if (error instanceof z.ZodError) {
|
|
960
|
+
return {
|
|
961
|
+
success: false,
|
|
962
|
+
data: null,
|
|
963
|
+
errors: (error.issues || error.errors || []).map(err => ({
|
|
964
|
+
path: err.path?.join('.') || 'unknown',
|
|
965
|
+
message: err.message || 'Unknown error',
|
|
966
|
+
code: err.code || 'unknown',
|
|
967
|
+
})),
|
|
968
|
+
};
|
|
969
|
+
}
|
|
970
|
+
throw error;
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
/**
|
|
975
|
+
* Validate a run capsule
|
|
976
|
+
* @param {any} capsule - The run capsule to validate
|
|
977
|
+
* @returns {Object} Validation result { success, data, errors }
|
|
978
|
+
*/
|
|
979
|
+
export function validateRunCapsule(capsule) {
|
|
980
|
+
try {
|
|
981
|
+
const validated = RunCapsuleSchema.parse(capsule);
|
|
982
|
+
return { success: true, data: validated, errors: [] };
|
|
983
|
+
} catch (error) {
|
|
984
|
+
if (error instanceof z.ZodError) {
|
|
985
|
+
return {
|
|
986
|
+
success: false,
|
|
987
|
+
data: null,
|
|
988
|
+
errors: (error.issues || error.errors || []).map(err => ({
|
|
989
|
+
path: err.path?.join('.') || 'unknown',
|
|
990
|
+
message: err.message || 'Unknown error',
|
|
991
|
+
code: err.code || 'unknown',
|
|
992
|
+
})),
|
|
993
|
+
};
|
|
994
|
+
}
|
|
995
|
+
throw error;
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
/**
|
|
1000
|
+
* Validate a tool trace entry
|
|
1001
|
+
* @param {any} entry - The tool trace entry to validate
|
|
1002
|
+
* @returns {Object} Validation result { success, data, errors }
|
|
1003
|
+
*/
|
|
1004
|
+
export function validateToolTraceEntry(entry) {
|
|
1005
|
+
try {
|
|
1006
|
+
const validated = ToolTraceEntrySchema.parse(entry);
|
|
1007
|
+
return { success: true, data: validated, errors: [] };
|
|
1008
|
+
} catch (error) {
|
|
1009
|
+
if (error instanceof z.ZodError) {
|
|
1010
|
+
return {
|
|
1011
|
+
success: false,
|
|
1012
|
+
data: null,
|
|
1013
|
+
errors: (error.issues || error.errors || []).map(err => ({
|
|
1014
|
+
path: err.path?.join('.') || 'unknown',
|
|
1015
|
+
message: err.message || 'Unknown error',
|
|
1016
|
+
code: err.code || 'unknown',
|
|
1017
|
+
})),
|
|
1018
|
+
};
|
|
1019
|
+
}
|
|
1020
|
+
throw error;
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
/**
|
|
1025
|
+
* Validate bounds
|
|
1026
|
+
* @param {any} bounds - The bounds to validate
|
|
1027
|
+
* @returns {Object} Validation result { success, data, errors }
|
|
1028
|
+
*/
|
|
1029
|
+
export function validateBounds(bounds) {
|
|
1030
|
+
try {
|
|
1031
|
+
const validated = BoundsSchema.parse(bounds);
|
|
1032
|
+
return { success: true, data: validated, errors: [] };
|
|
1033
|
+
} catch (error) {
|
|
1034
|
+
if (error instanceof z.ZodError) {
|
|
1035
|
+
return {
|
|
1036
|
+
success: false,
|
|
1037
|
+
data: null,
|
|
1038
|
+
errors: (error.issues || error.errors || []).map(err => ({
|
|
1039
|
+
path: err.path?.join('.') || 'unknown',
|
|
1040
|
+
message: err.message || 'Unknown error',
|
|
1041
|
+
code: err.code || 'unknown',
|
|
1042
|
+
})),
|
|
1043
|
+
};
|
|
1044
|
+
}
|
|
1045
|
+
throw error;
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
/**
|
|
1050
|
+
* Validate a work item
|
|
1051
|
+
* @param {any} workItem - The work item to validate
|
|
1052
|
+
* @returns {Object} Validation result { success, data, errors }
|
|
1053
|
+
*/
|
|
1054
|
+
export function validateWorkItem(workItem) {
|
|
1055
|
+
try {
|
|
1056
|
+
const validated = WorkItemSchema.parse(workItem);
|
|
1057
|
+
return { success: true, data: validated, errors: [] };
|
|
1058
|
+
} catch (error) {
|
|
1059
|
+
if (error instanceof z.ZodError) {
|
|
1060
|
+
return {
|
|
1061
|
+
success: false,
|
|
1062
|
+
data: null,
|
|
1063
|
+
errors: (error.issues || error.errors || []).map(err => ({
|
|
1064
|
+
path: err.path?.join('.') || 'unknown',
|
|
1065
|
+
message: err.message || 'Unknown error',
|
|
1066
|
+
code: err.code || 'unknown',
|
|
1067
|
+
})),
|
|
1068
|
+
};
|
|
1069
|
+
}
|
|
1070
|
+
throw error;
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
/**
|
|
1075
|
+
* Validate a projection manifest
|
|
1076
|
+
* @param {any} manifest - The projection manifest to validate
|
|
1077
|
+
* @returns {Object} Validation result { success, data, errors }
|
|
1078
|
+
*/
|
|
1079
|
+
export function validateProjectionManifest(manifest) {
|
|
1080
|
+
try {
|
|
1081
|
+
const validated = ProjectionManifestSchema.parse(manifest);
|
|
1082
|
+
return { success: true, data: validated, errors: [] };
|
|
1083
|
+
} catch (error) {
|
|
1084
|
+
if (error instanceof z.ZodError) {
|
|
1085
|
+
return {
|
|
1086
|
+
success: false,
|
|
1087
|
+
data: null,
|
|
1088
|
+
errors: (error.issues || error.errors || []).map(err => ({
|
|
1089
|
+
path: err.path?.join('.') || 'unknown',
|
|
1090
|
+
message: err.message || 'Unknown error',
|
|
1091
|
+
code: err.code || 'unknown',
|
|
1092
|
+
})),
|
|
1093
|
+
};
|
|
1094
|
+
}
|
|
1095
|
+
throw error;
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
/**
|
|
1100
|
+
* Validate a KGC Markdown AST
|
|
1101
|
+
* @param {any} ast - The AST to validate
|
|
1102
|
+
* @returns {Object} Validation result { success, data, errors }
|
|
1103
|
+
*/
|
|
1104
|
+
export function validateKGCMarkdown(ast) {
|
|
1105
|
+
try {
|
|
1106
|
+
const validated = KGCMarkdownSchema.parse(ast);
|
|
1107
|
+
return { success: true, data: validated, errors: [] };
|
|
1108
|
+
} catch (error) {
|
|
1109
|
+
if (error instanceof z.ZodError) {
|
|
1110
|
+
return {
|
|
1111
|
+
success: false,
|
|
1112
|
+
data: null,
|
|
1113
|
+
errors: (error.issues || error.errors || []).map(err => ({
|
|
1114
|
+
path: err.path?.join('.') || 'unknown',
|
|
1115
|
+
message: err.message || 'Unknown error',
|
|
1116
|
+
code: err.code || 'unknown',
|
|
1117
|
+
})),
|
|
1118
|
+
};
|
|
1119
|
+
}
|
|
1120
|
+
throw error;
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
// =============================================================================
|
|
1125
|
+
// Plugin System Schemas
|
|
1126
|
+
// =============================================================================
|
|
1127
|
+
|
|
1128
|
+
/**
|
|
1129
|
+
* Plugin manifest schema
|
|
1130
|
+
*
|
|
1131
|
+
* Defines plugin metadata, capabilities, and API requirements:
|
|
1132
|
+
* - Name and version (semver)
|
|
1133
|
+
* - Entry point and dependencies
|
|
1134
|
+
* - Required capabilities
|
|
1135
|
+
* - API version compatibility
|
|
1136
|
+
*
|
|
1137
|
+
* @example
|
|
1138
|
+
* {
|
|
1139
|
+
* name: 'custom-receipt',
|
|
1140
|
+
* version: '1.0.0',
|
|
1141
|
+
* description: 'Custom receipt type plugin',
|
|
1142
|
+
* entryPoint: './plugin.mjs',
|
|
1143
|
+
* capabilities: ['custom-receipt', 'receipt:validate'],
|
|
1144
|
+
* api_version: '5.0.1',
|
|
1145
|
+
* author: 'Plugin Developer',
|
|
1146
|
+
* license: 'MIT'
|
|
1147
|
+
* }
|
|
1148
|
+
*
|
|
1149
|
+
* @constant
|
|
1150
|
+
* @type {z.ZodObject}
|
|
1151
|
+
*/
|
|
1152
|
+
export const PluginManifestSchema = z.object({
|
|
1153
|
+
/** Plugin name (unique identifier) */
|
|
1154
|
+
name: z.string().min(1).max(100).regex(/^[a-z0-9-]+$/),
|
|
1155
|
+
/** Plugin version (semver) */
|
|
1156
|
+
version: SemanticVersionSchema,
|
|
1157
|
+
/** Plugin description */
|
|
1158
|
+
description: z.string().max(500).optional(),
|
|
1159
|
+
/** Entry point module path */
|
|
1160
|
+
entryPoint: z.string().min(1),
|
|
1161
|
+
/** Required capabilities */
|
|
1162
|
+
capabilities: z.array(z.string()).default([]),
|
|
1163
|
+
/** Required API version */
|
|
1164
|
+
api_version: SemanticVersionSchema,
|
|
1165
|
+
/** Plugin author */
|
|
1166
|
+
author: z.string().optional(),
|
|
1167
|
+
/** Plugin license */
|
|
1168
|
+
license: z.string().optional(),
|
|
1169
|
+
/** Dependencies (other plugins) */
|
|
1170
|
+
dependencies: z.record(z.string(), z.string()).optional(),
|
|
1171
|
+
/** Plugin metadata */
|
|
1172
|
+
metadata: z.record(z.string(), z.any()).optional(),
|
|
1173
|
+
});
|
|
1174
|
+
|
|
1175
|
+
/**
|
|
1176
|
+
* Plugin state schema
|
|
1177
|
+
*
|
|
1178
|
+
* Tracks plugin lifecycle state:
|
|
1179
|
+
* - registered: Plugin manifest registered
|
|
1180
|
+
* - loaded: Plugin code loaded into memory
|
|
1181
|
+
* - executing: Plugin actively executing
|
|
1182
|
+
* - unloaded: Plugin unloaded from memory
|
|
1183
|
+
* - failed: Plugin failed to load/execute
|
|
1184
|
+
*
|
|
1185
|
+
* @constant
|
|
1186
|
+
* @type {z.ZodEnum}
|
|
1187
|
+
*/
|
|
1188
|
+
export const PluginStateSchema = z.enum([
|
|
1189
|
+
'registered',
|
|
1190
|
+
'loaded',
|
|
1191
|
+
'executing',
|
|
1192
|
+
'unloaded',
|
|
1193
|
+
'failed',
|
|
1194
|
+
]);
|
|
1195
|
+
|
|
1196
|
+
/**
|
|
1197
|
+
* Plugin capability schema
|
|
1198
|
+
*
|
|
1199
|
+
* Defines capability format: "category:action"
|
|
1200
|
+
*
|
|
1201
|
+
* Examples:
|
|
1202
|
+
* - receipt:generate
|
|
1203
|
+
* - receipt:validate
|
|
1204
|
+
* - schema:validate
|
|
1205
|
+
* - custom:my-action
|
|
1206
|
+
*
|
|
1207
|
+
* @constant
|
|
1208
|
+
* @type {z.ZodString}
|
|
1209
|
+
*/
|
|
1210
|
+
export const PluginCapabilitySchema = z
|
|
1211
|
+
.string()
|
|
1212
|
+
.regex(/^[a-z_-]+:[a-z_-]+$/, 'Must be format "category:action"');
|
|
1213
|
+
|
|
1214
|
+
/**
|
|
1215
|
+
* Plugin receipt schema
|
|
1216
|
+
*
|
|
1217
|
+
* Extended receipt schema for plugin-generated receipts
|
|
1218
|
+
* Includes plugin metadata and custom receipt types
|
|
1219
|
+
*
|
|
1220
|
+
* @example
|
|
1221
|
+
* {
|
|
1222
|
+
* version: '1.0.0',
|
|
1223
|
+
* id: '550e8400-e29b-41d4-a716-446655440000',
|
|
1224
|
+
* timestamp: 1703001600000,
|
|
1225
|
+
* runId: 'run-001',
|
|
1226
|
+
* actor: 'plugin:custom-receipt@1.0.0',
|
|
1227
|
+
* action: 'custom_action',
|
|
1228
|
+
* payload: { customData: 'value' },
|
|
1229
|
+
* result: { success: true },
|
|
1230
|
+
* pluginMetadata: {
|
|
1231
|
+
* pluginName: 'custom-receipt',
|
|
1232
|
+
* pluginVersion: '1.0.0',
|
|
1233
|
+
* receiptType: 'custom'
|
|
1234
|
+
* }
|
|
1235
|
+
* }
|
|
1236
|
+
*
|
|
1237
|
+
* @constant
|
|
1238
|
+
* @type {z.ZodObject}
|
|
1239
|
+
*/
|
|
1240
|
+
export const PluginReceiptSchema = ReceiptSchema.extend({
|
|
1241
|
+
/** Plugin-specific metadata */
|
|
1242
|
+
pluginMetadata: z
|
|
1243
|
+
.object({
|
|
1244
|
+
pluginName: z.string(),
|
|
1245
|
+
pluginVersion: SemanticVersionSchema,
|
|
1246
|
+
receiptType: z.string().default('standard'),
|
|
1247
|
+
customFields: z.record(z.string(), z.any()).optional(),
|
|
1248
|
+
})
|
|
1249
|
+
.optional(),
|
|
1250
|
+
});
|
|
1251
|
+
|
|
1252
|
+
/**
|
|
1253
|
+
* Validate a plugin manifest
|
|
1254
|
+
* @param {any} manifest - The manifest to validate
|
|
1255
|
+
* @returns {Object} Validation result { success, data, errors }
|
|
1256
|
+
*/
|
|
1257
|
+
export function validatePluginManifest(manifest) {
|
|
1258
|
+
try {
|
|
1259
|
+
const validated = PluginManifestSchema.parse(manifest);
|
|
1260
|
+
return { success: true, data: validated, errors: [] };
|
|
1261
|
+
} catch (error) {
|
|
1262
|
+
if (error instanceof z.ZodError) {
|
|
1263
|
+
return {
|
|
1264
|
+
success: false,
|
|
1265
|
+
data: null,
|
|
1266
|
+
errors: (error.issues || error.errors || []).map(err => ({
|
|
1267
|
+
path: err.path?.join('.') || 'unknown',
|
|
1268
|
+
message: err.message || 'Unknown error',
|
|
1269
|
+
code: err.code || 'unknown',
|
|
1270
|
+
})),
|
|
1271
|
+
};
|
|
1272
|
+
}
|
|
1273
|
+
throw error;
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1277
|
+
/**
|
|
1278
|
+
* Validate a plugin receipt
|
|
1279
|
+
* @param {any} receipt - The receipt to validate
|
|
1280
|
+
* @returns {Object} Validation result { success, data, errors }
|
|
1281
|
+
*/
|
|
1282
|
+
export function validatePluginReceipt(receipt) {
|
|
1283
|
+
try {
|
|
1284
|
+
const validated = PluginReceiptSchema.parse(receipt);
|
|
1285
|
+
return { success: true, data: validated, errors: [] };
|
|
1286
|
+
} catch (error) {
|
|
1287
|
+
if (error instanceof z.ZodError) {
|
|
1288
|
+
return {
|
|
1289
|
+
success: false,
|
|
1290
|
+
data: null,
|
|
1291
|
+
errors: (error.issues || error.errors || []).map(err => ({
|
|
1292
|
+
path: err.path?.join('.') || 'unknown',
|
|
1293
|
+
message: err.message || 'Unknown error',
|
|
1294
|
+
code: err.code || 'unknown',
|
|
1295
|
+
})),
|
|
1296
|
+
};
|
|
1297
|
+
}
|
|
1298
|
+
throw error;
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
// =============================================================================
|
|
1303
|
+
// Module Exports
|
|
1304
|
+
// =============================================================================
|
|
1305
|
+
|
|
1306
|
+
export default {
|
|
1307
|
+
// Schemas
|
|
1308
|
+
ReceiptSchema,
|
|
1309
|
+
RunCapsuleSchema,
|
|
1310
|
+
ToolTraceEntrySchema,
|
|
1311
|
+
BoundsSchema,
|
|
1312
|
+
WorkItemSchema,
|
|
1313
|
+
ProjectionManifestSchema,
|
|
1314
|
+
KGCMarkdownSchema,
|
|
1315
|
+
PluginManifestSchema,
|
|
1316
|
+
PluginStateSchema,
|
|
1317
|
+
PluginCapabilitySchema,
|
|
1318
|
+
PluginReceiptSchema,
|
|
1319
|
+
|
|
1320
|
+
// Validation functions
|
|
1321
|
+
validateReceipt,
|
|
1322
|
+
validateRunCapsule,
|
|
1323
|
+
validateToolTraceEntry,
|
|
1324
|
+
validateBounds,
|
|
1325
|
+
validateWorkItem,
|
|
1326
|
+
validateProjectionManifest,
|
|
1327
|
+
validateKGCMarkdown,
|
|
1328
|
+
validatePluginManifest,
|
|
1329
|
+
validatePluginReceipt,
|
|
1330
|
+
};
|