@unrdf/kgc-tools 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/package.json +49 -0
- package/src/freeze.mjs +37 -0
- package/src/index.mjs +29 -0
- package/src/list.mjs +30 -0
- package/src/replay.mjs +38 -0
- package/src/tool-wrapper.mjs +156 -0
- package/src/verify.mjs +64 -0
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@unrdf/kgc-tools",
|
|
3
|
+
"version": "26.4.2",
|
|
4
|
+
"description": "KGC Tools - Verification, freeze, and replay utilities for KGC capsules",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": "./src/index.mjs",
|
|
8
|
+
"./verify": "./src/verify.mjs",
|
|
9
|
+
"./freeze": "./src/freeze.mjs",
|
|
10
|
+
"./replay": "./src/replay.mjs",
|
|
11
|
+
"./list": "./src/list.mjs",
|
|
12
|
+
"./tool-wrapper": "./src/tool-wrapper.mjs"
|
|
13
|
+
},
|
|
14
|
+
"main": "./src/index.mjs",
|
|
15
|
+
"files": [
|
|
16
|
+
"src"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"test": "vitest",
|
|
20
|
+
"test:watch": "vitest --watch"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@unrdf/kgc-4d": "workspace:*",
|
|
24
|
+
"@unrdf/kgc-runtime": "workspace:*",
|
|
25
|
+
"@unrdf/core": "workspace:*",
|
|
26
|
+
"hash-wasm": "^4.12.0",
|
|
27
|
+
"zod": "^4.1.13"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"vitest": "^4.0.15"
|
|
31
|
+
},
|
|
32
|
+
"keywords": [
|
|
33
|
+
"kgc",
|
|
34
|
+
"tools",
|
|
35
|
+
"verify",
|
|
36
|
+
"freeze",
|
|
37
|
+
"replay"
|
|
38
|
+
],
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=18.0.0",
|
|
41
|
+
"pnpm": ">=7.0.0"
|
|
42
|
+
},
|
|
43
|
+
"sideEffects": false,
|
|
44
|
+
"author": "UNRDF Contributors",
|
|
45
|
+
"license": "MIT",
|
|
46
|
+
"publishConfig": {
|
|
47
|
+
"access": "public"
|
|
48
|
+
}
|
|
49
|
+
}
|
package/src/freeze.mjs
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Universe freeze operations
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { freezeUniverse } from '@unrdf/kgc-4d';
|
|
6
|
+
import { generateReceipt } from '@unrdf/kgc-runtime';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Freeze the current universe state
|
|
10
|
+
* @param {string} [reason] - Reason for freeze
|
|
11
|
+
* @returns {Promise<{freezeId: string, receipt: any}>}
|
|
12
|
+
*/
|
|
13
|
+
export async function freeze(reason = 'manual-freeze') {
|
|
14
|
+
const timestamp = new Date().toISOString();
|
|
15
|
+
const freezeId = `freeze-${timestamp}`;
|
|
16
|
+
|
|
17
|
+
// Generate receipt for freeze operation
|
|
18
|
+
const receipt = await generateReceipt(
|
|
19
|
+
'freeze',
|
|
20
|
+
{ reason, timestamp },
|
|
21
|
+
{ freezeId }
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
freezeId,
|
|
26
|
+
receipt,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* List all freeze snapshots
|
|
32
|
+
* @returns {Promise<Array<{id: string, timestamp: string, capsules: number}>>}
|
|
33
|
+
*/
|
|
34
|
+
export async function listFreezes() {
|
|
35
|
+
// Stub implementation
|
|
36
|
+
return [];
|
|
37
|
+
}
|
package/src/index.mjs
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview KGC Tools - Verification, freeze, and replay utilities
|
|
3
|
+
* @module @unrdf/kgc-tools
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export {
|
|
7
|
+
verifyAllReceipts,
|
|
8
|
+
verifyFreeze,
|
|
9
|
+
verifyDocs,
|
|
10
|
+
verifyAll,
|
|
11
|
+
} from './verify.mjs';
|
|
12
|
+
|
|
13
|
+
export {
|
|
14
|
+
freeze,
|
|
15
|
+
listFreezes,
|
|
16
|
+
} from './freeze.mjs';
|
|
17
|
+
|
|
18
|
+
export {
|
|
19
|
+
replayCapsule,
|
|
20
|
+
replayBatch,
|
|
21
|
+
} from './replay.mjs';
|
|
22
|
+
|
|
23
|
+
export {
|
|
24
|
+
listCapsules,
|
|
25
|
+
listWorkItems,
|
|
26
|
+
listSnapshots,
|
|
27
|
+
} from './list.mjs';
|
|
28
|
+
|
|
29
|
+
export { Wrap, validateReceipt } from './tool-wrapper.mjs';
|
package/src/list.mjs
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview List KGC entities (capsules, work items, snapshots)
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* List all capsules
|
|
7
|
+
* @returns {Promise<Array<{id: string, timestamp: string, hash: string}>>}
|
|
8
|
+
*/
|
|
9
|
+
export async function listCapsules() {
|
|
10
|
+
// Stub implementation
|
|
11
|
+
return [];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* List work items
|
|
16
|
+
* @returns {Promise<Array<{id: string, status: string, created: string}>>}
|
|
17
|
+
*/
|
|
18
|
+
export async function listWorkItems() {
|
|
19
|
+
// Stub implementation
|
|
20
|
+
return [];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* List snapshots
|
|
25
|
+
* @returns {Promise<Array<{id: string, timestamp: string, capsules: number}>>}
|
|
26
|
+
*/
|
|
27
|
+
export async function listSnapshots() {
|
|
28
|
+
// Stub implementation
|
|
29
|
+
return [];
|
|
30
|
+
}
|
package/src/replay.mjs
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Capsule replay and verification
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { verifyReceiptHash } from '@unrdf/kgc-runtime';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Replay a capsule and verify output hash
|
|
9
|
+
* @param {string} capsuleId - Capsule ID to replay
|
|
10
|
+
* @returns {Promise<{success: boolean, outputHash: string, verified: boolean}>}
|
|
11
|
+
*/
|
|
12
|
+
export async function replayCapsule(capsuleId) {
|
|
13
|
+
// Stub implementation
|
|
14
|
+
return {
|
|
15
|
+
success: true,
|
|
16
|
+
outputHash: 'stub-hash',
|
|
17
|
+
verified: true,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Replay multiple capsules
|
|
23
|
+
* @param {string[]} capsuleIds - Capsule IDs
|
|
24
|
+
* @returns {Promise<{total: number, verified: number, failed: number}>}
|
|
25
|
+
*/
|
|
26
|
+
export async function replayBatch(capsuleIds) {
|
|
27
|
+
const results = await Promise.all(
|
|
28
|
+
capsuleIds.map(id => replayCapsule(id))
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
const verified = results.filter(r => r.verified).length;
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
total: capsuleIds.length,
|
|
35
|
+
verified,
|
|
36
|
+
failed: capsuleIds.length - verified,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Tool Wrapper - Contract Enforcement Layer
|
|
3
|
+
* @module @unrdf/kgc-tools/tool-wrapper
|
|
4
|
+
* @description Wraps tools to enforce input/output contracts and generate execution receipts
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Receipt schema for tool execution
|
|
11
|
+
*/
|
|
12
|
+
const ReceiptSchema = z.object({
|
|
13
|
+
tool_name: z.string(),
|
|
14
|
+
version: z.string(),
|
|
15
|
+
inputs: z.any(),
|
|
16
|
+
outputs: z.any().nullable(),
|
|
17
|
+
status: z.enum(['success', 'error']),
|
|
18
|
+
timestamp: z.number(),
|
|
19
|
+
execution_time_ms: z.number(),
|
|
20
|
+
error: z.string().optional(),
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Wraps a tool function to enforce contracts and generate receipts
|
|
25
|
+
*
|
|
26
|
+
* @param {Function} tool - The tool function to wrap
|
|
27
|
+
* @param {Object} manifest - Tool manifest with schema and metadata
|
|
28
|
+
* @param {string} manifest.name - Tool name
|
|
29
|
+
* @param {string} manifest.version - Tool version
|
|
30
|
+
* @param {z.ZodSchema} manifest.schema_in - Input validation schema
|
|
31
|
+
* @param {z.ZodSchema} manifest.schema_out - Output validation schema
|
|
32
|
+
* @param {string[]} manifest.capabilities - Tool capabilities
|
|
33
|
+
* @returns {Function} Wrapped tool function
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* const readTool = async (inputs) => ({
|
|
37
|
+
* content: 'file content',
|
|
38
|
+
* size: 100
|
|
39
|
+
* });
|
|
40
|
+
*
|
|
41
|
+
* const manifest = {
|
|
42
|
+
* name: 'Read',
|
|
43
|
+
* version: '1.0.0',
|
|
44
|
+
* schema_in: z.object({ path: z.string() }),
|
|
45
|
+
* schema_out: z.object({ content: z.string(), size: z.number() }),
|
|
46
|
+
* capabilities: ['file-read']
|
|
47
|
+
* };
|
|
48
|
+
*
|
|
49
|
+
* const wrapped = Wrap(readTool, manifest);
|
|
50
|
+
* const result = await wrapped({ path: '/test.txt' });
|
|
51
|
+
* // Returns: { delta: {...}, receipt: {...} }
|
|
52
|
+
*/
|
|
53
|
+
export function Wrap(tool, manifest) {
|
|
54
|
+
// Validate manifest structure (basic validation)
|
|
55
|
+
if (!manifest || typeof manifest !== 'object') {
|
|
56
|
+
throw new Error('Manifest must be an object');
|
|
57
|
+
}
|
|
58
|
+
if (!manifest.name || typeof manifest.name !== 'string') {
|
|
59
|
+
throw new Error('Manifest must have a name string');
|
|
60
|
+
}
|
|
61
|
+
if (!manifest.version || typeof manifest.version !== 'string') {
|
|
62
|
+
throw new Error('Manifest must have a version string');
|
|
63
|
+
}
|
|
64
|
+
if (!manifest.schema_in || typeof manifest.schema_in.parse !== 'function') {
|
|
65
|
+
throw new Error('Manifest must have a schema_in with parse method');
|
|
66
|
+
}
|
|
67
|
+
if (!manifest.schema_out || typeof manifest.schema_out.parse !== 'function') {
|
|
68
|
+
throw new Error('Manifest must have a schema_out with parse method');
|
|
69
|
+
}
|
|
70
|
+
if (!Array.isArray(manifest.capabilities)) {
|
|
71
|
+
throw new Error('Manifest must have capabilities array');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Wrapped tool function
|
|
76
|
+
* @param {*} inputs - Tool inputs to validate
|
|
77
|
+
* @returns {Promise<{delta: *, receipt: Object}>} Execution result with delta and receipt
|
|
78
|
+
*/
|
|
79
|
+
return async function wrappedTool(inputs) {
|
|
80
|
+
const startTime = performance.now();
|
|
81
|
+
const timestamp = Date.now();
|
|
82
|
+
|
|
83
|
+
let validatedInputs;
|
|
84
|
+
let outputs = null;
|
|
85
|
+
let delta = null;
|
|
86
|
+
let status = 'success';
|
|
87
|
+
let errorMessage;
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
// Validate inputs against schema_in
|
|
91
|
+
validatedInputs = manifest.schema_in.parse(inputs);
|
|
92
|
+
|
|
93
|
+
// Execute the tool
|
|
94
|
+
const rawOutputs = await tool(validatedInputs);
|
|
95
|
+
|
|
96
|
+
// Validate outputs against schema_out
|
|
97
|
+
outputs = manifest.schema_out.parse(rawOutputs);
|
|
98
|
+
|
|
99
|
+
// Delta is the validated output
|
|
100
|
+
delta = outputs;
|
|
101
|
+
status = 'success';
|
|
102
|
+
} catch (error) {
|
|
103
|
+
// Handle validation or execution errors
|
|
104
|
+
status = 'error';
|
|
105
|
+
errorMessage = error.message;
|
|
106
|
+
outputs = null;
|
|
107
|
+
delta = null;
|
|
108
|
+
|
|
109
|
+
// Re-validate inputs if they weren't validated yet
|
|
110
|
+
if (!validatedInputs) {
|
|
111
|
+
validatedInputs = inputs;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const endTime = performance.now();
|
|
116
|
+
const executionTimeMs = endTime - startTime;
|
|
117
|
+
|
|
118
|
+
// Build receipt
|
|
119
|
+
const receipt = {
|
|
120
|
+
tool_name: manifest.name,
|
|
121
|
+
version: manifest.version,
|
|
122
|
+
inputs: validatedInputs,
|
|
123
|
+
outputs,
|
|
124
|
+
status,
|
|
125
|
+
timestamp,
|
|
126
|
+
execution_time_ms: executionTimeMs,
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
// Add error field if present
|
|
130
|
+
if (errorMessage) {
|
|
131
|
+
receipt.error = errorMessage;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Validate receipt structure
|
|
135
|
+
ReceiptSchema.parse(receipt);
|
|
136
|
+
|
|
137
|
+
return {
|
|
138
|
+
delta,
|
|
139
|
+
receipt,
|
|
140
|
+
};
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Validates a receipt structure
|
|
146
|
+
* @param {*} receipt - Receipt to validate
|
|
147
|
+
* @returns {boolean} True if valid
|
|
148
|
+
*/
|
|
149
|
+
export function validateReceipt(receipt) {
|
|
150
|
+
try {
|
|
151
|
+
ReceiptSchema.parse(receipt);
|
|
152
|
+
return true;
|
|
153
|
+
} catch {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
}
|
package/src/verify.mjs
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Verification tools for KGC capsules, freezes, and receipts
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { verifyReceiptHash, verifyReceiptChain } from '@unrdf/kgc-runtime';
|
|
6
|
+
import { verifyReceipt as kgc4dVerifyReceipt } from '@unrdf/kgc-4d';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Verify all receipts in a directory
|
|
10
|
+
* @param {string} receiptPath - Path to receipts
|
|
11
|
+
* @returns {Promise<{valid: boolean, verified: number, errors: string[]}>}
|
|
12
|
+
*/
|
|
13
|
+
export async function verifyAllReceipts(receiptPath = '.kgc/receipts') {
|
|
14
|
+
// Stub implementation - would read from filesystem
|
|
15
|
+
return {
|
|
16
|
+
valid: true,
|
|
17
|
+
verified: 0,
|
|
18
|
+
errors: [],
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Verify a freeze snapshot
|
|
24
|
+
* @param {string} freezeId - Freeze snapshot ID
|
|
25
|
+
* @returns {Promise<{valid: boolean, capsules: number, errors: string[]}>}
|
|
26
|
+
*/
|
|
27
|
+
export async function verifyFreeze(freezeId) {
|
|
28
|
+
// Stub implementation
|
|
29
|
+
return {
|
|
30
|
+
valid: true,
|
|
31
|
+
capsules: 0,
|
|
32
|
+
errors: [],
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Verify documentation matches code
|
|
38
|
+
* @param {string} docsPath - Documentation path
|
|
39
|
+
* @returns {Promise<{valid: boolean, verified: number, errors: string[]}>}
|
|
40
|
+
*/
|
|
41
|
+
export async function verifyDocs(docsPath = 'docs') {
|
|
42
|
+
// Stub implementation
|
|
43
|
+
return {
|
|
44
|
+
valid: true,
|
|
45
|
+
verified: 0,
|
|
46
|
+
errors: [],
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Comprehensive verification of all KGC components
|
|
52
|
+
* @returns {Promise<{receipts: any, freezes: any, docs: any, overall: boolean}>}
|
|
53
|
+
*/
|
|
54
|
+
export async function verifyAll() {
|
|
55
|
+
const receipts = await verifyAllReceipts();
|
|
56
|
+
const docs = await verifyDocs();
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
receipts,
|
|
60
|
+
freezes: { valid: true, capsules: 0, errors: [] },
|
|
61
|
+
docs,
|
|
62
|
+
overall: receipts.valid && docs.valid,
|
|
63
|
+
};
|
|
64
|
+
}
|