@aikdna/kdna-core 0.18.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +128 -94
- package/README.md +109 -215
- package/package.json +7 -2
- package/schema/agent-host-capabilities.schema.json +62 -0
- package/schema/agent-host-receipt.schema.json +371 -0
- package/schema/agent-host-request.schema.json +223 -0
- package/schema/{bundle-profile-v1.schema.json → bundle-profile.schema.json} +9 -5
- package/schema/checksums.schema.json +8 -8
- package/schema/consumption-plan.schema.json +428 -0
- package/schema/digest-evidence.schema.json +115 -26
- package/schema/{kdna-envelope-external-grant-v1.schema.json → external-grant-envelope.schema.json} +17 -4
- package/schema/{kdna-key-grant-v1.schema.json → external-key-grant.schema.json} +39 -7
- package/schema/judgment-trace.schema.json +1251 -0
- package/schema/load-plan.schema.json +5 -3
- package/schema/manifest.schema.json +70 -10
- package/schema/{payload-profile-v1.schema.json → payload-profile.schema.json} +30 -6
- package/schema/{runtime-capsule-2.schema.json → runtime-capsule.schema.json} +7 -31
- package/src/asset-reader.js +8 -2
- package/src/{v1 → container}/index.js +385 -198
- package/src/container/index.mjs +20 -0
- package/src/container-dispatcher.js +6 -6
- package/src/crypto-profile.js +37 -107
- package/src/external-key-grant.js +41 -15
- package/src/index.js +11 -8
- package/src/index.mjs +49 -45
- package/src/loader-compatibility.js +59 -0
- package/src/loader.js +1 -1
- package/src/public-api.js +5 -5
- package/src/remote-runtime.d.ts +13 -0
- package/src/remote-runtime.js +27 -0
- package/src/remote-runtime.mjs +3 -0
- package/src/runtime-api.js +5 -5
- package/src/{capsule-v2.js → runtime-capsule.js} +96 -254
- package/src/{execution-contract-v1.js → runtime-contract.js} +184 -152
- package/src/types.d.ts +200 -277
- package/src/workpack-pure.js +1 -1
- package/schema/agent-host-2-receipt.schema.json +0 -206
- package/schema/agent-host-2-request.schema.json +0 -135
- package/schema/agent-host-capabilities-1.schema.json +0 -40
- package/schema/consumption-plan-1.schema.json +0 -280
- package/schema/judgment-trace-1.schema.json +0 -748
- package/schema/runtime-capsule-1.schema.json +0 -68
- package/src/lint-pure.js +0 -433
- package/src/v1/index.mjs +0 -21
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { version: KDNA_LOADER_VERSION } = require('../package.json');
|
|
4
|
+
|
|
5
|
+
const STRICT_LOADER_VERSION = /^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$/u;
|
|
6
|
+
|
|
7
|
+
function parseLoaderVersion(value) {
|
|
8
|
+
if (typeof value !== 'string') return null;
|
|
9
|
+
const match = STRICT_LOADER_VERSION.exec(value);
|
|
10
|
+
return match ? Object.freeze(match.slice(1)) : null;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function compareNumericIdentifier(left, right) {
|
|
14
|
+
if (left.length !== right.length) return left.length < right.length ? -1 : 1;
|
|
15
|
+
if (left === right) return 0;
|
|
16
|
+
return left < right ? -1 : 1;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function compareLoaderVersions(leftVersion, rightVersion) {
|
|
20
|
+
const left = parseLoaderVersion(leftVersion);
|
|
21
|
+
const right = parseLoaderVersion(rightVersion);
|
|
22
|
+
if (!left || !right) {
|
|
23
|
+
throw new TypeError('loader versions must use strict x.y.z SemVer without leading zeros');
|
|
24
|
+
}
|
|
25
|
+
for (let index = 0; index < 3; index += 1) {
|
|
26
|
+
const comparison = compareNumericIdentifier(left[index], right[index]);
|
|
27
|
+
if (comparison !== 0) return comparison;
|
|
28
|
+
}
|
|
29
|
+
return 0;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (!parseLoaderVersion(KDNA_LOADER_VERSION)) {
|
|
33
|
+
throw new Error(`@aikdna/kdna-core package version is not a strict loader coordinate: ${KDNA_LOADER_VERSION}`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function assessLoaderCompatibility(manifest) {
|
|
37
|
+
const requiredValue = manifest?.compatibility?.min_loader_version;
|
|
38
|
+
const required = parseLoaderVersion(requiredValue);
|
|
39
|
+
return Object.freeze({
|
|
40
|
+
loader_version: KDNA_LOADER_VERSION,
|
|
41
|
+
min_loader_version: typeof requiredValue === 'string' ? requiredValue : null,
|
|
42
|
+
loader_compatible: required
|
|
43
|
+
? compareLoaderVersions(requiredValue, KDNA_LOADER_VERSION) <= 0
|
|
44
|
+
: null,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function loaderVersionUnsupportedMessage(requiredVersion) {
|
|
49
|
+
return `KDNA_LOADER_VERSION_UNSUPPORTED: asset requires loader ${requiredVersion}, current loader is ${KDNA_LOADER_VERSION}`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
module.exports = {
|
|
53
|
+
KDNA_LOADER_VERSION,
|
|
54
|
+
STRICT_LOADER_VERSION,
|
|
55
|
+
parseLoaderVersion,
|
|
56
|
+
compareLoaderVersions,
|
|
57
|
+
assessLoaderCompatibility,
|
|
58
|
+
loaderVersionUnsupportedMessage,
|
|
59
|
+
};
|
package/src/loader.js
CHANGED
|
@@ -157,7 +157,7 @@ function detectOldFieldNames(obj, path = '', warnings = []) {
|
|
|
157
157
|
for (const key of Object.keys(obj)) {
|
|
158
158
|
if (FIELD_ALIASES[key]) {
|
|
159
159
|
warnings.push(
|
|
160
|
-
`[KDNA LOADER] ${path}.${key}: field "${key}" is not in spec
|
|
160
|
+
`[KDNA LOADER] ${path}.${key}: field "${key}" is not in spec 0.4. Use "${FIELD_ALIASES[key]}" instead. See docs/authoring-guide.md §0.`,
|
|
161
161
|
);
|
|
162
162
|
}
|
|
163
163
|
if (typeof obj[key] === 'object' && obj[key] !== null) {
|
package/src/public-api.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
const fs = require('fs');
|
|
11
11
|
const { createKdnaAssetReader } = require('./asset-reader');
|
|
12
|
-
const
|
|
12
|
+
const container = require('./container');
|
|
13
13
|
const runtimeApi = require('./runtime-api');
|
|
14
14
|
|
|
15
15
|
function readerFrom(options = {}) {
|
|
@@ -53,7 +53,7 @@ function openKDNASync(input, options = {}) {
|
|
|
53
53
|
async function inspectKDNA(input, options = {}) {
|
|
54
54
|
const reader = readerFrom(options);
|
|
55
55
|
const asset = await asAsset(input, { ...options, reader });
|
|
56
|
-
const current =
|
|
56
|
+
const current = container.inspect(canonicalBytes(asset), options);
|
|
57
57
|
const manifest = await reader.readManifest(asset);
|
|
58
58
|
const entries = await reader.listEntries(asset);
|
|
59
59
|
const contentDigest = await reader.contentDigest(asset);
|
|
@@ -74,7 +74,7 @@ async function inspectKDNA(input, options = {}) {
|
|
|
74
74
|
function inspectKDNASync(input, options = {}) {
|
|
75
75
|
const reader = readerFrom(options);
|
|
76
76
|
const asset = asAssetSync(input, { ...options, reader });
|
|
77
|
-
const current =
|
|
77
|
+
const current = container.inspect(canonicalBytes(asset), options);
|
|
78
78
|
const manifest = reader.readManifestSync(asset);
|
|
79
79
|
const entries = reader.listEntriesSync(asset);
|
|
80
80
|
const contentDigest = reader.contentDigestSync(asset);
|
|
@@ -101,11 +101,11 @@ function loadKDNASync(input, options = {}) {
|
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
async function validateKDNA(input, options = {}) {
|
|
104
|
-
return
|
|
104
|
+
return container.validate(isAsset(input) ? canonicalBytes(input) : input, options);
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
function validateKDNASync(input, options = {}) {
|
|
108
|
-
return
|
|
108
|
+
return container.validate(isAsset(input) ? canonicalBytes(input) : input, options);
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
async function renderForAgent(input, options = {}) {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { KDNARuntimeCapsule } from './types';
|
|
2
|
+
|
|
3
|
+
/** A final packaged `.kdna` file path or its immutable packaged bytes. */
|
|
4
|
+
export type KDNARemoteRuntimeInput = string | Uint8Array;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Load one deployer-controlled `access: "remote"` asset for server-side
|
|
8
|
+
* projection. The function always returns a full JSON Runtime Capsule and
|
|
9
|
+
* accepts no caller policy options.
|
|
10
|
+
*/
|
|
11
|
+
export function loadRemoteRuntimeAsset(
|
|
12
|
+
input: KDNARemoteRuntimeInput,
|
|
13
|
+
): KDNARuntimeCapsule;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const container = require('./container');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Load one deployer-controlled `access: "remote"` packaged asset for a
|
|
7
|
+
* server-side projection Runtime.
|
|
8
|
+
*
|
|
9
|
+
* This API intentionally accepts no caller policy options. Physical control
|
|
10
|
+
* of the packaged remote asset is the deployment authorization boundary; the
|
|
11
|
+
* embedding server remains responsible for request authentication,
|
|
12
|
+
* entitlement checks, projection minimization, and audit policy.
|
|
13
|
+
*/
|
|
14
|
+
function loadRemoteRuntimeAsset(input) {
|
|
15
|
+
if (arguments.length !== 1) {
|
|
16
|
+
const error = new Error(
|
|
17
|
+
'loadRemoteRuntimeAsset accepts exactly one packaged asset input and no caller policy options.',
|
|
18
|
+
);
|
|
19
|
+
error.code = 'KDNA_REMOTE_RUNTIME_OPTIONS_FORBIDDEN';
|
|
20
|
+
throw error;
|
|
21
|
+
}
|
|
22
|
+
return container.loadRemoteRuntimeAssetForServer(input);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
module.exports = {
|
|
26
|
+
loadRemoteRuntimeAsset,
|
|
27
|
+
};
|
package/src/runtime-api.js
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
const fs = require('node:fs');
|
|
4
4
|
const path = require('node:path');
|
|
5
|
-
const
|
|
5
|
+
const container = require('./container');
|
|
6
6
|
|
|
7
7
|
function invalidDirectoryPlan(inputPath) {
|
|
8
8
|
const resolved = path.resolve(inputPath);
|
|
9
9
|
return {
|
|
10
|
-
|
|
10
|
+
format_version: null,
|
|
11
11
|
asset: { asset_id: null, asset_uid: null, title: null, version: null, judgment_version: null },
|
|
12
12
|
access: null,
|
|
13
13
|
access_alias: null,
|
|
@@ -64,7 +64,7 @@ function guardResolver(options = {}) {
|
|
|
64
64
|
|
|
65
65
|
function planLoad(inputPath, options = {}) {
|
|
66
66
|
if (isDirectory(inputPath)) return invalidDirectoryPlan(inputPath);
|
|
67
|
-
return
|
|
67
|
+
return container.planLoad(inputPath, guardResolver(options));
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
function loadAuthorized(inputPath, options = {}) {
|
|
@@ -77,9 +77,9 @@ function loadAuthorized(inputPath, options = {}) {
|
|
|
77
77
|
error.plan = plan;
|
|
78
78
|
throw error;
|
|
79
79
|
}
|
|
80
|
-
//
|
|
80
|
+
// container.loadAuthorized snapshots packaged paths once and uses that same Buffer
|
|
81
81
|
// for its LoadPlan, authorization decision, and Runtime Capsule projection.
|
|
82
|
-
return
|
|
82
|
+
return container.loadAuthorized(inputPath, guardResolver(options));
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
module.exports = {
|