@unrdf/kgc-probe 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/README.md +414 -0
- package/package.json +81 -0
- package/src/agents/index.mjs +1402 -0
- package/src/artifact.mjs +405 -0
- package/src/cli.mjs +932 -0
- package/src/config.mjs +115 -0
- package/src/guards.mjs +1213 -0
- package/src/index.mjs +347 -0
- package/src/merge.mjs +196 -0
- package/src/observation.mjs +193 -0
- package/src/orchestrator.mjs +315 -0
- package/src/probe.mjs +58 -0
- package/src/probes/CONCURRENCY-PROBE.md +256 -0
- package/src/probes/README.md +275 -0
- package/src/probes/concurrency.mjs +1175 -0
- package/src/probes/filesystem.mjs +731 -0
- package/src/probes/filesystem.test.mjs +244 -0
- package/src/probes/network.mjs +503 -0
- package/src/probes/performance.mjs +816 -0
- package/src/probes/persistence.mjs +785 -0
- package/src/probes/runtime.mjs +589 -0
- package/src/probes/tooling.mjs +454 -0
- package/src/probes/tooling.test.mjs +372 -0
- package/src/probes/verify-execution.mjs +131 -0
- package/src/probes/verify-guards.mjs +73 -0
- package/src/probes/wasm.mjs +715 -0
- package/src/receipt.mjs +197 -0
- package/src/receipts/index.mjs +813 -0
- package/src/reporter.example.mjs +223 -0
- package/src/reporter.mjs +555 -0
- package/src/reporters/markdown.mjs +355 -0
- package/src/reporters/rdf.mjs +383 -0
- package/src/storage/index.mjs +827 -0
- package/src/types.mjs +1028 -0
- package/src/utils/errors.mjs +397 -0
- package/src/utils/index.mjs +32 -0
- package/src/utils/logger.mjs +236 -0
- package/src/vocabulary.ttl +169 -0
package/src/types.mjs
ADDED
|
@@ -0,0 +1,1028 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview KGC Probe - Type definitions and Zod schemas
|
|
3
|
+
*
|
|
4
|
+
* Runtime-validatable schemas for:
|
|
5
|
+
* - KGC Markdown Frontmatter (o_hash, policy_id, receipts, bounds, etc.)
|
|
6
|
+
* - Block Metadata (query, extract, render, proof blocks)
|
|
7
|
+
* - Receipts (cryptographic proofs)
|
|
8
|
+
* - Observations (agent outputs)
|
|
9
|
+
* - Artifacts (scan results)
|
|
10
|
+
* - Configuration objects
|
|
11
|
+
*
|
|
12
|
+
* @module @unrdf/kgc-probe/types
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { z } from 'zod';
|
|
16
|
+
|
|
17
|
+
// ============================================================================
|
|
18
|
+
// CONSTANTS & REGEXES (per SPARC spec)
|
|
19
|
+
// ============================================================================
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* SHA-256 hash pattern (64 lowercase hex characters)
|
|
23
|
+
* @type {RegExp}
|
|
24
|
+
*/
|
|
25
|
+
export const SHA256_REGEX = /^[a-f0-9]{64}$/;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* UUID v4 pattern
|
|
29
|
+
* @type {RegExp}
|
|
30
|
+
*/
|
|
31
|
+
export const UUID_V4_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Semver pattern (e.g., 1.0.0, 2.1.3-beta.1+build.123)
|
|
35
|
+
* @type {RegExp}
|
|
36
|
+
*/
|
|
37
|
+
export const SEMVER_REGEX = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;
|
|
38
|
+
|
|
39
|
+
// ============================================================================
|
|
40
|
+
// KGC MARKDOWN FRONTMATTER SCHEMAS (SPARC Domain 1, 4, 8)
|
|
41
|
+
// ============================================================================
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Source file reference schema
|
|
45
|
+
* References a specific range of lines in a source file with hash
|
|
46
|
+
* @type {z.ZodSchema}
|
|
47
|
+
*/
|
|
48
|
+
export const SourceSchema = z.object({
|
|
49
|
+
path: z.string().min(1).describe('Path to source file (no ../ allowed)'),
|
|
50
|
+
lineStart: z.number().int().min(1).describe('Starting line number'),
|
|
51
|
+
lineEnd: z.number().int().min(1).describe('Ending line number'),
|
|
52
|
+
hash: z.string().regex(SHA256_REGEX, 'Must be 64-char hex SHA-256').describe('SHA-256 hash of source content')
|
|
53
|
+
}).refine(
|
|
54
|
+
(data) => data.lineEnd >= data.lineStart,
|
|
55
|
+
{ message: 'lineEnd must be >= lineStart', path: ['lineEnd'] }
|
|
56
|
+
).refine(
|
|
57
|
+
(data) => !data.path.includes('..'),
|
|
58
|
+
{ message: 'Path must not contain directory traversal (..)', path: ['path'] }
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Resource bounds schema
|
|
63
|
+
* Limits for queries, runtime, and file scans
|
|
64
|
+
* @type {z.ZodSchema}
|
|
65
|
+
*/
|
|
66
|
+
export const BoundsSchema = z.object({
|
|
67
|
+
maxQueries: z.number().int().min(1).max(10000).describe('Maximum query result count [1, 10000]'),
|
|
68
|
+
maxRuntime: z.number().int().min(100).max(60000).describe('Maximum runtime in ms [100, 60000]'),
|
|
69
|
+
maxFileScans: z.number().int().min(1).max(1000).describe('Maximum file scans [1, 1000]')
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Author schema
|
|
74
|
+
* @type {z.ZodSchema}
|
|
75
|
+
*/
|
|
76
|
+
export const AuthorSchema = z.object({
|
|
77
|
+
name: z.string().min(1).describe('Author name'),
|
|
78
|
+
role: z.string().optional().describe('Author role (optional)')
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Diataxis view types
|
|
83
|
+
* @type {z.ZodEnum}
|
|
84
|
+
*/
|
|
85
|
+
export const DiatasisViewSchema = z.enum(['tutorial', 'how-to', 'reference', 'explanation']);
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* KGC Markdown Frontmatter schema (Domain 1: Frontmatter Parsing)
|
|
89
|
+
* Validates all frontmatter fields per SPARC specification
|
|
90
|
+
* @type {z.ZodSchema}
|
|
91
|
+
*/
|
|
92
|
+
export const FrontmatterSchema = z.object({
|
|
93
|
+
o_hash: z.string()
|
|
94
|
+
.regex(SHA256_REGEX, 'o_hash must be 64-char lowercase hex SHA-256')
|
|
95
|
+
.describe('Universe snapshot hash'),
|
|
96
|
+
policy_id: z.string()
|
|
97
|
+
.regex(UUID_V4_REGEX, 'policy_id must be valid UUID v4')
|
|
98
|
+
.describe('Policy pack UUID'),
|
|
99
|
+
receipts: z.array(
|
|
100
|
+
z.string().regex(SHA256_REGEX, 'Receipt ID must be 64-char hex')
|
|
101
|
+
).min(0).max(1000).describe('Array of receipt IDs [0-1000 items]'),
|
|
102
|
+
bounds: BoundsSchema.describe('Resource limits'),
|
|
103
|
+
views: z.array(DiatasisViewSchema)
|
|
104
|
+
.min(1).max(4)
|
|
105
|
+
.describe('Diataxis view types'),
|
|
106
|
+
sources: z.array(SourceSchema)
|
|
107
|
+
.min(0).max(100)
|
|
108
|
+
.describe('Source file references'),
|
|
109
|
+
version: z.string()
|
|
110
|
+
.regex(SEMVER_REGEX, 'version must be valid semver')
|
|
111
|
+
.describe('Document version'),
|
|
112
|
+
createdAt: z.string().datetime({ offset: true }).describe('Creation timestamp (ISO 8601)'),
|
|
113
|
+
lastProved: z.string().datetime({ offset: true }).describe('Last proof timestamp (ISO 8601)'),
|
|
114
|
+
tags: z.array(z.string().min(1).max(50)).max(20).optional().describe('Optional tags'),
|
|
115
|
+
authors: z.array(AuthorSchema).optional().describe('Optional authors')
|
|
116
|
+
}).refine(
|
|
117
|
+
(data) => new Date(data.lastProved) >= new Date(data.createdAt),
|
|
118
|
+
{ message: 'lastProved must be >= createdAt', path: ['lastProved'] }
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
// ============================================================================
|
|
122
|
+
// BLOCK METADATA SCHEMAS (SPARC Domain 2, 5, 8)
|
|
123
|
+
// ============================================================================
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Block types supported by KGC Markdown
|
|
127
|
+
* @type {z.ZodEnum}
|
|
128
|
+
*/
|
|
129
|
+
export const BlockTypeSchema = z.enum(['kgc:query', 'kgc:proof', 'kgc:extract', 'kgc:render']);
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Output format options
|
|
133
|
+
* @type {z.ZodEnum}
|
|
134
|
+
*/
|
|
135
|
+
export const OutputFormatSchema = z.enum(['json', 'markdown', 'text']);
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Determinism level options
|
|
139
|
+
* @type {z.ZodEnum}
|
|
140
|
+
*/
|
|
141
|
+
export const DeterminismLevelSchema = z.enum(['strict', 'lenient', 'best-effort']);
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Base block metadata schema (shared by all block types)
|
|
145
|
+
* @type {z.ZodSchema}
|
|
146
|
+
*/
|
|
147
|
+
export const BlockMetadataSchema = z.object({
|
|
148
|
+
receiptId: z.string()
|
|
149
|
+
.regex(SHA256_REGEX, 'receiptId must be 64-char hex')
|
|
150
|
+
.describe('Receipt ID (SHA-256)'),
|
|
151
|
+
expectedOutputFormat: OutputFormatSchema.describe('Expected output format'),
|
|
152
|
+
determinismLevel: DeterminismLevelSchema.describe('Determinism guarantee level'),
|
|
153
|
+
metadata: z.record(z.any()).optional().describe('Block-type-specific metadata')
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Query type options
|
|
158
|
+
* @type {z.ZodEnum}
|
|
159
|
+
*/
|
|
160
|
+
export const QueryTypeSchema = z.enum(['sparql', 'n3', 'shacl']);
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Result bounds for queries
|
|
164
|
+
* @type {z.ZodSchema}
|
|
165
|
+
*/
|
|
166
|
+
export const ResultBoundsSchema = z.object({
|
|
167
|
+
minResults: z.number().int().min(0).describe('Minimum expected results'),
|
|
168
|
+
maxResults: z.number().int().min(0).describe('Maximum expected results')
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Query block metadata schema (kgc:query)
|
|
173
|
+
* @type {z.ZodSchema}
|
|
174
|
+
*/
|
|
175
|
+
export const QueryMetadataSchema = BlockMetadataSchema.extend({
|
|
176
|
+
queryType: QueryTypeSchema.describe('Query language type'),
|
|
177
|
+
resultBounds: ResultBoundsSchema.describe('Expected result count range'),
|
|
178
|
+
timeout: z.number().int().min(100).max(60000).describe('Query timeout in ms')
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Extraction type options
|
|
183
|
+
* @type {z.ZodEnum}
|
|
184
|
+
*/
|
|
185
|
+
export const ExtractionTypeSchema = z.enum(['exports', 'functions', 'classes', 'types', 'all']);
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Extract block metadata schema (kgc:extract)
|
|
189
|
+
* @type {z.ZodSchema}
|
|
190
|
+
*/
|
|
191
|
+
export const ExtractMetadataSchema = BlockMetadataSchema.extend({
|
|
192
|
+
extractionType: ExtractionTypeSchema.describe('What to extract'),
|
|
193
|
+
fileGlobs: z.array(z.string()).min(1).describe('File patterns to scan'),
|
|
194
|
+
includePrivate: z.boolean().default(false).describe('Include private members'),
|
|
195
|
+
includeDocstrings: z.boolean().default(true).describe('Include documentation')
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Render block metadata schema (kgc:render)
|
|
200
|
+
* @type {z.ZodSchema}
|
|
201
|
+
*/
|
|
202
|
+
export const RenderMetadataSchema = BlockMetadataSchema.extend({
|
|
203
|
+
templateName: z.string().min(1).describe('Template to use'),
|
|
204
|
+
sectionTitle: z.string().min(1).describe('Section heading'),
|
|
205
|
+
includeTableOfContents: z.boolean().default(false).describe('Include TOC')
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Proof type options
|
|
210
|
+
* @type {z.ZodEnum}
|
|
211
|
+
*/
|
|
212
|
+
export const ProofTypeSchema = z.enum(['merkle', 'hash-chain', 'single']);
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Proof block metadata schema (kgc:proof)
|
|
216
|
+
* @type {z.ZodSchema}
|
|
217
|
+
*/
|
|
218
|
+
export const ProofMetadataSchema = BlockMetadataSchema.extend({
|
|
219
|
+
proofType: ProofTypeSchema.describe('Type of cryptographic proof'),
|
|
220
|
+
verifyChain: z.boolean().default(true).describe('Verify dependency chain'),
|
|
221
|
+
validateSignatures: z.boolean().default(false).describe('Validate signatures')
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
// ============================================================================
|
|
225
|
+
// RECEIPT SCHEMAS (SPARC Domain 3, 7)
|
|
226
|
+
// ============================================================================
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Receipt decision options
|
|
230
|
+
* @type {z.ZodEnum}
|
|
231
|
+
*/
|
|
232
|
+
export const DecisionSchema = z.enum(['ADMIT', 'REJECT', 'PARTIAL']);
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Merkle proof schema (optional in receipts)
|
|
236
|
+
* @type {z.ZodSchema}
|
|
237
|
+
*/
|
|
238
|
+
export const MerkleProofSchema = z.object({
|
|
239
|
+
siblings: z.array(z.string().regex(SHA256_REGEX)).describe('Sibling hashes'),
|
|
240
|
+
root: z.string().regex(SHA256_REGEX).describe('Merkle root hash'),
|
|
241
|
+
index: z.number().int().min(0).describe('Leaf index'),
|
|
242
|
+
totalLeaves: z.number().int().min(1).describe('Total leaf count')
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Receipt schema (Domain 3: Receipt Validation)
|
|
247
|
+
* Cryptographic proof of block execution
|
|
248
|
+
* @type {z.ZodSchema}
|
|
249
|
+
*/
|
|
250
|
+
export const ReceiptSchema = z.object({
|
|
251
|
+
id: z.string()
|
|
252
|
+
.regex(SHA256_REGEX, 'Receipt ID must be SHA-256 of canonical body')
|
|
253
|
+
.describe('Receipt ID (SHA-256)'),
|
|
254
|
+
timestamp: z.string().datetime({ offset: true }).describe('Execution timestamp'),
|
|
255
|
+
o_hash: z.string()
|
|
256
|
+
.regex(SHA256_REGEX, 'o_hash must match frontmatter')
|
|
257
|
+
.describe('Universe snapshot hash'),
|
|
258
|
+
block_type: BlockTypeSchema.describe('Block type that produced this receipt'),
|
|
259
|
+
input_hash: z.string()
|
|
260
|
+
.regex(SHA256_REGEX, 'input_hash is SHA-256 of block metadata + body')
|
|
261
|
+
.describe('Hash of block input'),
|
|
262
|
+
output_hash: z.string()
|
|
263
|
+
.regex(SHA256_REGEX, 'output_hash is SHA-256 of generated content (RFC 8785)')
|
|
264
|
+
.describe('Hash of block output'),
|
|
265
|
+
decision: DecisionSchema.describe('Execution decision'),
|
|
266
|
+
metadata: z.record(z.any()).optional().describe('Block-specific metadata'),
|
|
267
|
+
dependencies: z.array(
|
|
268
|
+
z.string().regex(SHA256_REGEX)
|
|
269
|
+
).optional().describe('Receipt IDs this depends on'),
|
|
270
|
+
merkle_proof: MerkleProofSchema.optional().describe('Merkle proof (batch receipts)')
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
// ============================================================================
|
|
274
|
+
// DYNAMIC SECTION SCHEMAS (SPARC Domain 4)
|
|
275
|
+
// ============================================================================
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Dynamic section schema
|
|
279
|
+
* Content between <!-- kgc:dynamic --> markers
|
|
280
|
+
* @type {z.ZodSchema}
|
|
281
|
+
*/
|
|
282
|
+
export const DynamicSectionSchema = z.object({
|
|
283
|
+
name: z.string().min(1).describe('Section identifier'),
|
|
284
|
+
receiptId: z.string().regex(SHA256_REGEX).describe('Associated receipt ID'),
|
|
285
|
+
lineStart: z.number().int().min(1).describe('Opening marker line'),
|
|
286
|
+
lineEnd: z.number().int().min(1).describe('Closing marker line'),
|
|
287
|
+
contentHash: z.string().regex(SHA256_REGEX).optional().describe('Computed content hash')
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
// ============================================================================
|
|
291
|
+
// PROBE ERROR SCHEMAS (SPARC Domain 10)
|
|
292
|
+
// ============================================================================
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Error severity levels
|
|
296
|
+
* @type {z.ZodEnum}
|
|
297
|
+
*/
|
|
298
|
+
export const ErrorSeveritySchema = z.enum(['error', 'warning', 'info']);
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Error type enumeration (all possible probe errors)
|
|
302
|
+
* @type {z.ZodEnum}
|
|
303
|
+
*/
|
|
304
|
+
export const ErrorTypeSchema = z.enum([
|
|
305
|
+
'InvalidFrontmatter',
|
|
306
|
+
'MissingReceipt',
|
|
307
|
+
'MismatchedHash',
|
|
308
|
+
'BoundsExceeded',
|
|
309
|
+
'NonDeterministic',
|
|
310
|
+
'InvalidBlockStructure',
|
|
311
|
+
'CyclicDependency',
|
|
312
|
+
'MissingDependency',
|
|
313
|
+
'TimestampOrderViolation',
|
|
314
|
+
'UniverseHashMismatch',
|
|
315
|
+
'OrphanedSection',
|
|
316
|
+
'UnmappedReceipt',
|
|
317
|
+
'BrokenLink',
|
|
318
|
+
'HeadingHierarchyViolation',
|
|
319
|
+
'DuplicateHeading',
|
|
320
|
+
'SchemaViolation'
|
|
321
|
+
]);
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Probe error schema with location and remediation
|
|
325
|
+
* @type {z.ZodSchema}
|
|
326
|
+
*/
|
|
327
|
+
export const ProbeErrorSchema = z.object({
|
|
328
|
+
type: ErrorTypeSchema.describe('Error classification'),
|
|
329
|
+
severity: ErrorSeveritySchema.describe('Impact severity'),
|
|
330
|
+
message: z.string().min(1).describe('Human-readable message'),
|
|
331
|
+
location: z.object({
|
|
332
|
+
file: z.string().optional().describe('File path'),
|
|
333
|
+
line: z.number().int().min(1).optional().describe('Line number'),
|
|
334
|
+
field: z.string().optional().describe('Field name')
|
|
335
|
+
}).optional().describe('Error location'),
|
|
336
|
+
actual: z.unknown().optional().describe('Actual value observed'),
|
|
337
|
+
expected: z.unknown().optional().describe('Expected value'),
|
|
338
|
+
remediation: z.string().optional().describe('How to fix')
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Probe warning (non-blocking issue)
|
|
343
|
+
* @type {z.ZodSchema}
|
|
344
|
+
*/
|
|
345
|
+
export const ProbeWarningSchema = ProbeErrorSchema.extend({
|
|
346
|
+
severity: z.literal('warning')
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
// ============================================================================
|
|
350
|
+
// PROBE REPORT SCHEMAS (SPARC Success Metrics)
|
|
351
|
+
// ============================================================================
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Domain validation result
|
|
355
|
+
* @type {z.ZodSchema}
|
|
356
|
+
*/
|
|
357
|
+
export const DomainResultSchema = z.object({
|
|
358
|
+
domain: z.string().describe('Domain name'),
|
|
359
|
+
passed: z.boolean().describe('Whether domain checks passed'),
|
|
360
|
+
checks: z.number().int().min(0).describe('Number of checks run'),
|
|
361
|
+
errors: z.array(ProbeErrorSchema).describe('Errors found'),
|
|
362
|
+
warnings: z.array(ProbeWarningSchema).describe('Warnings found')
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Complete probe report schema
|
|
367
|
+
* @type {z.ZodSchema}
|
|
368
|
+
*/
|
|
369
|
+
export const ProbeReportSchema = z.object({
|
|
370
|
+
version: z.literal('1.0').describe('Report schema version'),
|
|
371
|
+
documentPath: z.string().describe('Scanned document path'),
|
|
372
|
+
timestamp: z.string().datetime({ offset: true }).describe('Scan timestamp'),
|
|
373
|
+
status: z.enum(['PASS', 'FAIL', 'PARTIAL']).describe('Overall status'),
|
|
374
|
+
domains: z.array(DomainResultSchema).describe('Results per domain'),
|
|
375
|
+
summary: z.object({
|
|
376
|
+
totalChecks: z.number().int().min(0).describe('Total checks run'),
|
|
377
|
+
totalPassed: z.number().int().min(0).describe('Checks passed'),
|
|
378
|
+
totalErrors: z.number().int().min(0).describe('Error count'),
|
|
379
|
+
totalWarnings: z.number().int().min(0).describe('Warning count'),
|
|
380
|
+
coverage: z.number().min(0).max(1).describe('Document coverage ratio')
|
|
381
|
+
}).describe('Summary statistics'),
|
|
382
|
+
metadata: z.object({
|
|
383
|
+
probeVersion: z.string().describe('Probe version'),
|
|
384
|
+
executionTimeMs: z.number().int().min(0).describe('Execution time'),
|
|
385
|
+
documentSize: z.number().int().min(0).optional().describe('Document size in bytes')
|
|
386
|
+
}).describe('Execution metadata')
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
// ============================================================================
|
|
390
|
+
// OBSERVATION SCHEMA (Agent outputs - existing)
|
|
391
|
+
// ============================================================================
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Individual observation from an agent scan
|
|
395
|
+
* @type {z.ZodSchema}
|
|
396
|
+
*/
|
|
397
|
+
export const ObservationSchema = z.object({
|
|
398
|
+
id: z.string().uuid('Observation must have UUID').describe('Globally unique observation ID'),
|
|
399
|
+
agent: z.string().describe('Agent identifier that produced this observation'),
|
|
400
|
+
timestamp: z.string().datetime().describe('ISO8601 timestamp when observation was made'),
|
|
401
|
+
kind: z.enum([
|
|
402
|
+
'completeness',
|
|
403
|
+
'consistency',
|
|
404
|
+
'conformance',
|
|
405
|
+
'coverage',
|
|
406
|
+
'caching',
|
|
407
|
+
'completeness_level',
|
|
408
|
+
'coherence',
|
|
409
|
+
'clustering',
|
|
410
|
+
'classification',
|
|
411
|
+
'collaboration',
|
|
412
|
+
'guard_violation'
|
|
413
|
+
]).describe('Type of observation (agent-specific)'),
|
|
414
|
+
severity: z.enum(['critical', 'warning', 'info']).default('info').describe('Impact severity'),
|
|
415
|
+
subject: z.string().describe('RDF node under observation'),
|
|
416
|
+
predicate: z.string().optional().describe('RDF property (optional)'),
|
|
417
|
+
object: z.string().optional().describe('RDF value (optional)'),
|
|
418
|
+
evidence: z.object({
|
|
419
|
+
query: z.string().describe('SPARQL query or algorithm used'),
|
|
420
|
+
result: z.unknown().describe('Computation result'),
|
|
421
|
+
witnesses: z.array(z.string()).describe('Confirming triple/node references')
|
|
422
|
+
}).describe('Proof and context for observation'),
|
|
423
|
+
metrics: z.object({
|
|
424
|
+
confidence: z.number().min(0).max(1).describe('Confidence score [0, 1]'),
|
|
425
|
+
coverage: z.number().min(0).max(1).describe('Coverage ratio [0, 1]'),
|
|
426
|
+
latency_ms: z.number().nonnegative().describe('Execution latency in ms')
|
|
427
|
+
}).describe('Quantitative metrics'),
|
|
428
|
+
tags: z.array(z.string()).default([]).describe('Searchable tags'),
|
|
429
|
+
xid: z.string().optional().describe('Correlation ID for tracing')
|
|
430
|
+
}).strict();
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Type representing validated observation
|
|
434
|
+
* @typedef {z.infer<typeof ObservationSchema>} Observation
|
|
435
|
+
*/
|
|
436
|
+
export const ObservationType = ObservationSchema;
|
|
437
|
+
|
|
438
|
+
// ============================================================================
|
|
439
|
+
// ARTIFACT SCHEMA
|
|
440
|
+
// ============================================================================
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* Artifact summary statistics
|
|
444
|
+
* @type {z.ZodSchema}
|
|
445
|
+
*/
|
|
446
|
+
export const ArtifactSummarySchema = z.object({
|
|
447
|
+
total: z.number().nonnegative().describe('Total observation count'),
|
|
448
|
+
by_kind: z.record(z.string(), z.number().nonnegative()).describe('Count per observation kind'),
|
|
449
|
+
by_severity: z.record(z.enum(['critical', 'warning', 'info']), z.number().nonnegative()).describe('Count per severity'),
|
|
450
|
+
confidence_mean: z.number().min(0).max(1).describe('Mean confidence score'),
|
|
451
|
+
coverage_mean: z.number().min(0).max(1).describe('Mean coverage ratio')
|
|
452
|
+
}).describe('Summary statistics for artifact');
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* Complete artifact with observations and metadata
|
|
456
|
+
* @type {z.ZodSchema}
|
|
457
|
+
*/
|
|
458
|
+
export const ArtifactSchema = z.object({
|
|
459
|
+
version: z.literal('1.0').describe('Artifact schema version'),
|
|
460
|
+
universe_id: z.string().describe('4D universe reference'),
|
|
461
|
+
snapshot_id: z.string().describe('KGC-4D snapshot hash'),
|
|
462
|
+
generated_at: z.string().datetime().describe('Generation timestamp'),
|
|
463
|
+
probe_run_id: z.string().uuid().describe('Unique probe run ID'),
|
|
464
|
+
shard_count: z.number().nonnegative().describe('Number of shards merged'),
|
|
465
|
+
shard_hash: z.string().regex(/^[a-f0-9]{64}$/).describe('Blake3 hash of all shards'),
|
|
466
|
+
observations: z.array(ObservationSchema).describe('All observations from this scan'),
|
|
467
|
+
summary: ArtifactSummarySchema.describe('Aggregated statistics'),
|
|
468
|
+
metadata: z.object({
|
|
469
|
+
agents_run: z.array(z.string()).describe('Agent IDs executed'),
|
|
470
|
+
guards_applied: z.array(z.string()).describe('Guard IDs applied'),
|
|
471
|
+
execution_time_ms: z.number().nonnegative().describe('Total execution time'),
|
|
472
|
+
storage_backend: z.string().describe('Storage implementation used'),
|
|
473
|
+
config: z.unknown().optional().describe('Scan configuration')
|
|
474
|
+
}).describe('Execution metadata'),
|
|
475
|
+
integrity: z.object({
|
|
476
|
+
checksum: z.string().regex(/^[a-f0-9]{64}$/).describe('Blake3 hash of observations'),
|
|
477
|
+
signature: z.string().optional().describe('Optional cryptographic signature'),
|
|
478
|
+
verified_at: z.string().datetime().optional().describe('Verification timestamp')
|
|
479
|
+
}).describe('Integrity verification')
|
|
480
|
+
}).strict();
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* Type representing validated artifact
|
|
484
|
+
* @typedef {z.infer<typeof ArtifactSchema>} Artifact
|
|
485
|
+
*/
|
|
486
|
+
export const ArtifactType = ArtifactSchema;
|
|
487
|
+
|
|
488
|
+
// ============================================================================
|
|
489
|
+
// CONFIGURATION SCHEMAS
|
|
490
|
+
// ============================================================================
|
|
491
|
+
|
|
492
|
+
/**
|
|
493
|
+
* Probe scan configuration
|
|
494
|
+
* @type {z.ZodSchema}
|
|
495
|
+
*/
|
|
496
|
+
export const ProbeConfigSchema = z.object({
|
|
497
|
+
universe_id: z.string().describe('Universe to scan'),
|
|
498
|
+
snapshot_id: z.string().optional().describe('Optional snapshot reference'),
|
|
499
|
+
agents: z.array(z.string()).optional().describe('Agent IDs to run (all if omitted)'),
|
|
500
|
+
guards: z.array(z.string()).optional().describe('Guard IDs to apply'),
|
|
501
|
+
distributed: z.boolean().default(false).describe('Enable multi-shard merge'),
|
|
502
|
+
persist: z.boolean().default(true).describe('Save artifact to storage'),
|
|
503
|
+
timeout_ms: z.number().positive().default(300000).describe('Scan timeout'),
|
|
504
|
+
batch_size: z.number().positive().default(100).describe('Observation batch size')
|
|
505
|
+
}).describe('Probe scan configuration');
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* Guard configuration
|
|
509
|
+
* @type {z.ZodSchema}
|
|
510
|
+
*/
|
|
511
|
+
export const GuardConfigSchema = z.object({
|
|
512
|
+
quality_check: z.object({
|
|
513
|
+
critical_observations_threshold: z.number().positive().default(50),
|
|
514
|
+
confidence_min: z.number().min(0).max(1).default(0.6)
|
|
515
|
+
}).optional(),
|
|
516
|
+
completeness_check: z.object({
|
|
517
|
+
coverage_min: z.number().min(0).max(1).default(0.7)
|
|
518
|
+
}).optional(),
|
|
519
|
+
severity_limit: z.object({
|
|
520
|
+
critical_limit: z.number().positive().default(10)
|
|
521
|
+
}).optional()
|
|
522
|
+
}).describe('Guard thresholds and limits');
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* Storage configuration
|
|
526
|
+
* @type {z.ZodSchema}
|
|
527
|
+
*/
|
|
528
|
+
export const StorageConfigSchema = z.object({
|
|
529
|
+
type: z.enum(['memory', 'file', 'database']).describe('Storage backend type'),
|
|
530
|
+
path: z.string().optional().describe('File system path (for file storage)'),
|
|
531
|
+
connectionString: z.string().optional().describe('Database connection (for database storage)')
|
|
532
|
+
}).describe('Storage backend configuration');
|
|
533
|
+
|
|
534
|
+
// ============================================================================
|
|
535
|
+
// AGENT INTERFACE
|
|
536
|
+
// ============================================================================
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* Base agent interface definition
|
|
540
|
+
* @type {z.ZodSchema}
|
|
541
|
+
*/
|
|
542
|
+
export const AgentSchema = z.object({
|
|
543
|
+
id: z.string().describe('Agent identifier'),
|
|
544
|
+
kind: z.string().describe('Observation kind produced'),
|
|
545
|
+
description: z.string().describe('Human-readable description'),
|
|
546
|
+
scan: z.function().describe('Async scan function')
|
|
547
|
+
}).describe('Agent interface specification');
|
|
548
|
+
|
|
549
|
+
// ============================================================================
|
|
550
|
+
// GUARD VIOLATION
|
|
551
|
+
// ============================================================================
|
|
552
|
+
|
|
553
|
+
/**
|
|
554
|
+
* Guard validation violation
|
|
555
|
+
* @type {z.ZodSchema}
|
|
556
|
+
*/
|
|
557
|
+
export const GuardViolationSchema = z.object({
|
|
558
|
+
guard_id: z.string().describe('Guard that detected violation'),
|
|
559
|
+
severity: z.enum(['critical', 'warning', 'info']).describe('Violation severity'),
|
|
560
|
+
details: z.object({
|
|
561
|
+
message: z.string().describe('Human-readable message'),
|
|
562
|
+
actual: z.unknown().describe('Actual value observed'),
|
|
563
|
+
threshold: z.unknown().describe('Expected/threshold value')
|
|
564
|
+
}).describe('Violation details')
|
|
565
|
+
}).describe('Guard validation violation');
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* Type representing guard violation
|
|
569
|
+
* @typedef {z.infer<typeof GuardViolationSchema>} GuardViolation
|
|
570
|
+
*/
|
|
571
|
+
export const GuardViolationType = GuardViolationSchema;
|
|
572
|
+
|
|
573
|
+
// ============================================================================
|
|
574
|
+
// DIFF RESULT
|
|
575
|
+
// ============================================================================
|
|
576
|
+
|
|
577
|
+
/**
|
|
578
|
+
* Diff between two artifacts
|
|
579
|
+
* @type {z.ZodSchema}
|
|
580
|
+
*/
|
|
581
|
+
export const DiffResultSchema = z.object({
|
|
582
|
+
added: z.array(ObservationSchema).describe('Observations in artifact2 but not artifact1'),
|
|
583
|
+
removed: z.array(ObservationSchema).describe('Observations in artifact1 but not artifact2'),
|
|
584
|
+
modified: z.array(z.object({
|
|
585
|
+
original: ObservationSchema,
|
|
586
|
+
updated: ObservationSchema,
|
|
587
|
+
changes: z.record(z.string(), z.unknown()).describe('Field changes')
|
|
588
|
+
})).describe('Observations present in both but with changes'),
|
|
589
|
+
summary: z.object({
|
|
590
|
+
total_changes: z.number().nonnegative(),
|
|
591
|
+
similarity_ratio: z.number().min(0).max(1).describe('Jaccard similarity')
|
|
592
|
+
}).describe('Diff summary')
|
|
593
|
+
}).describe('Artifact comparison result');
|
|
594
|
+
|
|
595
|
+
/**
|
|
596
|
+
* Type representing diff result
|
|
597
|
+
* @typedef {z.infer<typeof DiffResultSchema>} DiffResult
|
|
598
|
+
*/
|
|
599
|
+
export const DiffResultType = DiffResultSchema;
|
|
600
|
+
|
|
601
|
+
// ============================================================================
|
|
602
|
+
// VALIDATION RESULTS
|
|
603
|
+
// ============================================================================
|
|
604
|
+
|
|
605
|
+
/**
|
|
606
|
+
* Scan execution result
|
|
607
|
+
* @type {z.ZodSchema}
|
|
608
|
+
*/
|
|
609
|
+
export const ScanResultSchema = z.object({
|
|
610
|
+
artifact: ArtifactSchema.describe('Generated artifact'),
|
|
611
|
+
status: z.enum(['success', 'partial', 'failed']).describe('Execution status'),
|
|
612
|
+
errors: z.array(z.object({
|
|
613
|
+
agent: z.string().optional(),
|
|
614
|
+
guard: z.string().optional(),
|
|
615
|
+
error: z.string().describe('Error message')
|
|
616
|
+
})).describe('Execution errors')
|
|
617
|
+
}).describe('Complete scan result');
|
|
618
|
+
|
|
619
|
+
/**
|
|
620
|
+
* Type representing scan result
|
|
621
|
+
* @typedef {z.infer<typeof ScanResultSchema>} ScanResult
|
|
622
|
+
*/
|
|
623
|
+
export const ScanResultType = ScanResultSchema;
|
|
624
|
+
|
|
625
|
+
// ============================================================================
|
|
626
|
+
// FACTORY FUNCTIONS (25 factories per SPARC spec)
|
|
627
|
+
// ============================================================================
|
|
628
|
+
|
|
629
|
+
/**
|
|
630
|
+
* Create valid frontmatter object with defaults
|
|
631
|
+
* @param {Partial<z.infer<typeof FrontmatterSchema>>} data - Partial frontmatter
|
|
632
|
+
* @returns {z.infer<typeof FrontmatterSchema>} Complete frontmatter
|
|
633
|
+
* @example
|
|
634
|
+
* const fm = createFrontmatter({
|
|
635
|
+
* o_hash: 'a'.repeat(64),
|
|
636
|
+
* policy_id: '550e8400-e29b-41d4-a716-446655440000'
|
|
637
|
+
* });
|
|
638
|
+
*/
|
|
639
|
+
export function createFrontmatter(data) {
|
|
640
|
+
const now = new Date().toISOString();
|
|
641
|
+
const defaults = {
|
|
642
|
+
o_hash: '0'.repeat(64),
|
|
643
|
+
policy_id: '00000000-0000-4000-8000-000000000000',
|
|
644
|
+
receipts: [],
|
|
645
|
+
bounds: { maxQueries: 100, maxRuntime: 5000, maxFileScans: 50 },
|
|
646
|
+
views: ['reference'],
|
|
647
|
+
sources: [],
|
|
648
|
+
version: '1.0.0',
|
|
649
|
+
createdAt: now,
|
|
650
|
+
lastProved: now
|
|
651
|
+
};
|
|
652
|
+
return FrontmatterSchema.parse({ ...defaults, ...data });
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
/**
|
|
656
|
+
* Create valid bounds object
|
|
657
|
+
* @param {Partial<z.infer<typeof BoundsSchema>>} data - Partial bounds
|
|
658
|
+
* @returns {z.infer<typeof BoundsSchema>} Complete bounds
|
|
659
|
+
*/
|
|
660
|
+
export function createBounds(data = {}) {
|
|
661
|
+
const defaults = { maxQueries: 100, maxRuntime: 5000, maxFileScans: 50 };
|
|
662
|
+
return BoundsSchema.parse({ ...defaults, ...data });
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
/**
|
|
666
|
+
* Create valid source reference
|
|
667
|
+
* @param {Partial<z.infer<typeof SourceSchema>>} data - Partial source
|
|
668
|
+
* @returns {z.infer<typeof SourceSchema>} Complete source
|
|
669
|
+
*/
|
|
670
|
+
export function createSource(data) {
|
|
671
|
+
const defaults = {
|
|
672
|
+
path: 'src/index.mjs',
|
|
673
|
+
lineStart: 1,
|
|
674
|
+
lineEnd: 100,
|
|
675
|
+
hash: '0'.repeat(64)
|
|
676
|
+
};
|
|
677
|
+
return SourceSchema.parse({ ...defaults, ...data });
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
/**
|
|
681
|
+
* Create valid author object
|
|
682
|
+
* @param {Partial<z.infer<typeof AuthorSchema>>} data - Partial author
|
|
683
|
+
* @returns {z.infer<typeof AuthorSchema>} Complete author
|
|
684
|
+
*/
|
|
685
|
+
export function createAuthor(data) {
|
|
686
|
+
const defaults = { name: 'Anonymous' };
|
|
687
|
+
return AuthorSchema.parse({ ...defaults, ...data });
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
/**
|
|
691
|
+
* Create valid block metadata
|
|
692
|
+
* @param {Partial<z.infer<typeof BlockMetadataSchema>>} data - Partial metadata
|
|
693
|
+
* @returns {z.infer<typeof BlockMetadataSchema>} Complete metadata
|
|
694
|
+
*/
|
|
695
|
+
export function createBlockMetadata(data) {
|
|
696
|
+
const defaults = {
|
|
697
|
+
receiptId: '0'.repeat(64),
|
|
698
|
+
expectedOutputFormat: 'json',
|
|
699
|
+
determinismLevel: 'strict'
|
|
700
|
+
};
|
|
701
|
+
return BlockMetadataSchema.parse({ ...defaults, ...data });
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
/**
|
|
705
|
+
* Create valid query metadata
|
|
706
|
+
* @param {Partial<z.infer<typeof QueryMetadataSchema>>} data - Partial metadata
|
|
707
|
+
* @returns {z.infer<typeof QueryMetadataSchema>} Complete metadata
|
|
708
|
+
*/
|
|
709
|
+
export function createQueryMetadata(data) {
|
|
710
|
+
const defaults = {
|
|
711
|
+
receiptId: '0'.repeat(64),
|
|
712
|
+
expectedOutputFormat: 'json',
|
|
713
|
+
determinismLevel: 'strict',
|
|
714
|
+
queryType: 'sparql',
|
|
715
|
+
resultBounds: { minResults: 0, maxResults: 1000 },
|
|
716
|
+
timeout: 5000
|
|
717
|
+
};
|
|
718
|
+
return QueryMetadataSchema.parse({ ...defaults, ...data });
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
/**
|
|
722
|
+
* Create valid extract metadata
|
|
723
|
+
* @param {Partial<z.infer<typeof ExtractMetadataSchema>>} data - Partial metadata
|
|
724
|
+
* @returns {z.infer<typeof ExtractMetadataSchema>} Complete metadata
|
|
725
|
+
*/
|
|
726
|
+
export function createExtractMetadata(data) {
|
|
727
|
+
const defaults = {
|
|
728
|
+
receiptId: '0'.repeat(64),
|
|
729
|
+
expectedOutputFormat: 'json',
|
|
730
|
+
determinismLevel: 'lenient',
|
|
731
|
+
extractionType: 'exports',
|
|
732
|
+
fileGlobs: ['src/**/*.mjs'],
|
|
733
|
+
includePrivate: false,
|
|
734
|
+
includeDocstrings: true
|
|
735
|
+
};
|
|
736
|
+
return ExtractMetadataSchema.parse({ ...defaults, ...data });
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
/**
|
|
740
|
+
* Create valid render metadata
|
|
741
|
+
* @param {Partial<z.infer<typeof RenderMetadataSchema>>} data - Partial metadata
|
|
742
|
+
* @returns {z.infer<typeof RenderMetadataSchema>} Complete metadata
|
|
743
|
+
*/
|
|
744
|
+
export function createRenderMetadata(data) {
|
|
745
|
+
const defaults = {
|
|
746
|
+
receiptId: '0'.repeat(64),
|
|
747
|
+
expectedOutputFormat: 'markdown',
|
|
748
|
+
determinismLevel: 'strict',
|
|
749
|
+
templateName: 'api-reference',
|
|
750
|
+
sectionTitle: 'API Reference',
|
|
751
|
+
includeTableOfContents: true
|
|
752
|
+
};
|
|
753
|
+
return RenderMetadataSchema.parse({ ...defaults, ...data });
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
/**
|
|
757
|
+
* Create valid proof metadata
|
|
758
|
+
* @param {Partial<z.infer<typeof ProofMetadataSchema>>} data - Partial metadata
|
|
759
|
+
* @returns {z.infer<typeof ProofMetadataSchema>} Complete metadata
|
|
760
|
+
*/
|
|
761
|
+
export function createProofMetadata(data) {
|
|
762
|
+
const defaults = {
|
|
763
|
+
receiptId: '0'.repeat(64),
|
|
764
|
+
expectedOutputFormat: 'json',
|
|
765
|
+
determinismLevel: 'strict',
|
|
766
|
+
proofType: 'merkle',
|
|
767
|
+
verifyChain: true,
|
|
768
|
+
validateSignatures: false
|
|
769
|
+
};
|
|
770
|
+
return ProofMetadataSchema.parse({ ...defaults, ...data });
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
/**
|
|
774
|
+
* Create valid receipt object
|
|
775
|
+
* @param {Partial<z.infer<typeof ReceiptSchema>>} data - Partial receipt
|
|
776
|
+
* @returns {z.infer<typeof ReceiptSchema>} Complete receipt
|
|
777
|
+
*/
|
|
778
|
+
export function createReceipt(data) {
|
|
779
|
+
const now = new Date().toISOString();
|
|
780
|
+
const defaults = {
|
|
781
|
+
id: '0'.repeat(64),
|
|
782
|
+
timestamp: now,
|
|
783
|
+
o_hash: '0'.repeat(64),
|
|
784
|
+
block_type: 'kgc:query',
|
|
785
|
+
input_hash: '0'.repeat(64),
|
|
786
|
+
output_hash: '0'.repeat(64),
|
|
787
|
+
decision: 'ADMIT'
|
|
788
|
+
};
|
|
789
|
+
return ReceiptSchema.parse({ ...defaults, ...data });
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
/**
|
|
793
|
+
* Create valid merkle proof
|
|
794
|
+
* @param {Partial<z.infer<typeof MerkleProofSchema>>} data - Partial proof
|
|
795
|
+
* @returns {z.infer<typeof MerkleProofSchema>} Complete proof
|
|
796
|
+
*/
|
|
797
|
+
export function createMerkleProof(data) {
|
|
798
|
+
const defaults = {
|
|
799
|
+
siblings: [],
|
|
800
|
+
root: '0'.repeat(64),
|
|
801
|
+
index: 0,
|
|
802
|
+
totalLeaves: 1
|
|
803
|
+
};
|
|
804
|
+
return MerkleProofSchema.parse({ ...defaults, ...data });
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
/**
|
|
808
|
+
* Create valid dynamic section
|
|
809
|
+
* @param {Partial<z.infer<typeof DynamicSectionSchema>>} data - Partial section
|
|
810
|
+
* @returns {z.infer<typeof DynamicSectionSchema>} Complete section
|
|
811
|
+
*/
|
|
812
|
+
export function createDynamicSection(data) {
|
|
813
|
+
const defaults = {
|
|
814
|
+
name: 'section',
|
|
815
|
+
receiptId: '0'.repeat(64),
|
|
816
|
+
lineStart: 1,
|
|
817
|
+
lineEnd: 100
|
|
818
|
+
};
|
|
819
|
+
return DynamicSectionSchema.parse({ ...defaults, ...data });
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
/**
|
|
823
|
+
* Create valid probe error
|
|
824
|
+
* @param {Partial<z.infer<typeof ProbeErrorSchema>>} data - Partial error
|
|
825
|
+
* @returns {z.infer<typeof ProbeErrorSchema>} Complete error
|
|
826
|
+
*/
|
|
827
|
+
export function createProbeError(data) {
|
|
828
|
+
const defaults = {
|
|
829
|
+
type: 'SchemaViolation',
|
|
830
|
+
severity: 'error',
|
|
831
|
+
message: 'Validation failed'
|
|
832
|
+
};
|
|
833
|
+
return ProbeErrorSchema.parse({ ...defaults, ...data });
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
/**
|
|
837
|
+
* Create valid probe warning
|
|
838
|
+
* @param {Partial<z.infer<typeof ProbeWarningSchema>>} data - Partial warning
|
|
839
|
+
* @returns {z.infer<typeof ProbeWarningSchema>} Complete warning
|
|
840
|
+
*/
|
|
841
|
+
export function createProbeWarning(data) {
|
|
842
|
+
const defaults = {
|
|
843
|
+
type: 'BoundsExceeded',
|
|
844
|
+
severity: 'warning',
|
|
845
|
+
message: 'Resource utilization high'
|
|
846
|
+
};
|
|
847
|
+
return ProbeWarningSchema.parse({ ...defaults, ...data });
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
/**
|
|
851
|
+
* Create valid domain result
|
|
852
|
+
* @param {Partial<z.infer<typeof DomainResultSchema>>} data - Partial result
|
|
853
|
+
* @returns {z.infer<typeof DomainResultSchema>} Complete result
|
|
854
|
+
*/
|
|
855
|
+
export function createDomainResult(data) {
|
|
856
|
+
const defaults = {
|
|
857
|
+
domain: 'frontmatter',
|
|
858
|
+
passed: true,
|
|
859
|
+
checks: 10,
|
|
860
|
+
errors: [],
|
|
861
|
+
warnings: []
|
|
862
|
+
};
|
|
863
|
+
return DomainResultSchema.parse({ ...defaults, ...data });
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
/**
|
|
867
|
+
* Create valid probe report
|
|
868
|
+
* @param {Partial<z.infer<typeof ProbeReportSchema>>} data - Partial report
|
|
869
|
+
* @returns {z.infer<typeof ProbeReportSchema>} Complete report
|
|
870
|
+
*/
|
|
871
|
+
export function createProbeReport(data) {
|
|
872
|
+
const now = new Date().toISOString();
|
|
873
|
+
const defaults = {
|
|
874
|
+
version: '1.0',
|
|
875
|
+
documentPath: 'docs/example.kgcmd',
|
|
876
|
+
timestamp: now,
|
|
877
|
+
status: 'PASS',
|
|
878
|
+
domains: [],
|
|
879
|
+
summary: {
|
|
880
|
+
totalChecks: 0,
|
|
881
|
+
totalPassed: 0,
|
|
882
|
+
totalErrors: 0,
|
|
883
|
+
totalWarnings: 0,
|
|
884
|
+
coverage: 1.0
|
|
885
|
+
},
|
|
886
|
+
metadata: {
|
|
887
|
+
probeVersion: '1.0.0',
|
|
888
|
+
executionTimeMs: 0
|
|
889
|
+
}
|
|
890
|
+
};
|
|
891
|
+
return ProbeReportSchema.parse({ ...defaults, ...data });
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
/**
|
|
895
|
+
* Create probe configuration
|
|
896
|
+
* @param {Partial<z.infer<typeof ProbeConfigSchema>>} data - Partial config
|
|
897
|
+
* @returns {z.infer<typeof ProbeConfigSchema>} Complete config
|
|
898
|
+
*/
|
|
899
|
+
export function createProbeConfig(data) {
|
|
900
|
+
const defaults = {
|
|
901
|
+
universe_id: 'default-universe',
|
|
902
|
+
distributed: false,
|
|
903
|
+
persist: true,
|
|
904
|
+
timeout_ms: 300000,
|
|
905
|
+
batch_size: 100
|
|
906
|
+
};
|
|
907
|
+
return ProbeConfigSchema.parse({ ...defaults, ...data });
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
/**
|
|
911
|
+
* Create valid observation
|
|
912
|
+
* @param {Partial<z.infer<typeof ObservationSchema>>} data - Partial observation
|
|
913
|
+
* @returns {z.infer<typeof ObservationSchema>} Complete observation
|
|
914
|
+
*/
|
|
915
|
+
export function createObservation(data) {
|
|
916
|
+
const now = new Date().toISOString();
|
|
917
|
+
const generateUUID = () => {
|
|
918
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
|
919
|
+
const r = (Math.random() * 16) | 0;
|
|
920
|
+
const v = c === 'x' ? r : (r & 0x3) | 0x8;
|
|
921
|
+
return v.toString(16);
|
|
922
|
+
});
|
|
923
|
+
};
|
|
924
|
+
const defaults = {
|
|
925
|
+
id: generateUUID(),
|
|
926
|
+
agent: 'unknown',
|
|
927
|
+
timestamp: now,
|
|
928
|
+
kind: 'completeness',
|
|
929
|
+
severity: 'info',
|
|
930
|
+
subject: '',
|
|
931
|
+
evidence: {
|
|
932
|
+
query: '',
|
|
933
|
+
result: null,
|
|
934
|
+
witnesses: []
|
|
935
|
+
},
|
|
936
|
+
metrics: {
|
|
937
|
+
confidence: 0.5,
|
|
938
|
+
coverage: 0.5,
|
|
939
|
+
latency_ms: 0
|
|
940
|
+
},
|
|
941
|
+
tags: []
|
|
942
|
+
};
|
|
943
|
+
return ObservationSchema.parse({ ...defaults, ...data });
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
// ============================================================================
|
|
947
|
+
// VALIDATION HELPER FUNCTIONS
|
|
948
|
+
// ============================================================================
|
|
949
|
+
|
|
950
|
+
/**
|
|
951
|
+
* Validate observation against schema
|
|
952
|
+
* @param {unknown} data - Data to validate
|
|
953
|
+
* @returns {z.infer<typeof ObservationSchema>} Validated observation
|
|
954
|
+
* @throws {z.ZodError} If validation fails
|
|
955
|
+
*/
|
|
956
|
+
export function validateObservation(data) {
|
|
957
|
+
return ObservationSchema.parse(data);
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
/**
|
|
961
|
+
* Validate artifact against schema
|
|
962
|
+
* @param {unknown} data - Data to validate
|
|
963
|
+
* @returns {z.infer<typeof ArtifactSchema>} Validated artifact
|
|
964
|
+
* @throws {z.ZodError} If validation fails
|
|
965
|
+
*/
|
|
966
|
+
export function validateArtifact(data) {
|
|
967
|
+
return ArtifactSchema.parse(data);
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
/**
|
|
971
|
+
* Validate probe configuration
|
|
972
|
+
* @param {unknown} data - Data to validate
|
|
973
|
+
* @returns {z.infer<typeof ProbeConfigSchema>} Validated config
|
|
974
|
+
* @throws {z.ZodError} If validation fails
|
|
975
|
+
*/
|
|
976
|
+
export function validateProbeConfig(data) {
|
|
977
|
+
return ProbeConfigSchema.parse(data);
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
/**
|
|
981
|
+
* Validate frontmatter
|
|
982
|
+
* @param {unknown} data - Data to validate
|
|
983
|
+
* @returns {z.infer<typeof FrontmatterSchema>} Validated frontmatter
|
|
984
|
+
* @throws {z.ZodError} If validation fails
|
|
985
|
+
*/
|
|
986
|
+
export function validateFrontmatter(data) {
|
|
987
|
+
return FrontmatterSchema.parse(data);
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
/**
|
|
991
|
+
* Validate receipt
|
|
992
|
+
* @param {unknown} data - Data to validate
|
|
993
|
+
* @returns {z.infer<typeof ReceiptSchema>} Validated receipt
|
|
994
|
+
* @throws {z.ZodError} If validation fails
|
|
995
|
+
*/
|
|
996
|
+
export function validateReceipt(data) {
|
|
997
|
+
return ReceiptSchema.parse(data);
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
/**
|
|
1001
|
+
* Safe validation (returns null instead of throwing)
|
|
1002
|
+
* @param {unknown} data - Data to validate
|
|
1003
|
+
* @returns {z.infer<typeof ObservationSchema> | null} Validated observation or null
|
|
1004
|
+
*/
|
|
1005
|
+
export function tryValidateObservation(data) {
|
|
1006
|
+
const result = ObservationSchema.safeParse(data);
|
|
1007
|
+
return result.success ? result.data : null;
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
/**
|
|
1011
|
+
* Safe frontmatter validation
|
|
1012
|
+
* @param {unknown} data - Data to validate
|
|
1013
|
+
* @returns {z.infer<typeof FrontmatterSchema> | null} Validated or null
|
|
1014
|
+
*/
|
|
1015
|
+
export function tryValidateFrontmatter(data) {
|
|
1016
|
+
const result = FrontmatterSchema.safeParse(data);
|
|
1017
|
+
return result.success ? result.data : null;
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
/**
|
|
1021
|
+
* Safe receipt validation
|
|
1022
|
+
* @param {unknown} data - Data to validate
|
|
1023
|
+
* @returns {z.infer<typeof ReceiptSchema> | null} Validated or null
|
|
1024
|
+
*/
|
|
1025
|
+
export function tryValidateReceipt(data) {
|
|
1026
|
+
const result = ReceiptSchema.safeParse(data);
|
|
1027
|
+
return result.success ? result.data : null;
|
|
1028
|
+
}
|