holarchy-eidolon-adapter 0.2.0 → 0.2.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/dist/HolarchyEidolonAdapterError.d.ts +4 -0
- package/dist/HolarchyEidolonAdapterError.js +8 -0
- package/dist/HolonDeploymentDefinition.d.ts +22 -0
- package/dist/HolonDeploymentDefinition.js +196 -0
- package/dist/HolonDeploymentRuntime.d.ts +61 -0
- package/dist/HolonDeploymentRuntime.js +295 -0
- package/dist/HolonExecutionBinding.d.ts +90 -0
- package/dist/HolonExecutionBinding.js +453 -0
- package/dist/HolonExecutionBindingProjection.d.ts +57 -0
- package/dist/HolonExecutionBindingProjection.js +289 -0
- package/dist/WorkbenchProtocol.d.ts +12 -0
- package/dist/WorkbenchProtocol.js +102 -0
- package/dist/WorkflowHolonTaskContract.d.ts +90 -0
- package/dist/WorkflowHolonTaskContract.js +211 -0
- package/dist/canonicalBase64.d.ts +2 -0
- package/dist/canonicalBase64.js +7 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +7 -0
- package/package.json +36 -20
- package/src/HolarchyEidolonAdapterError.ts +0 -9
- package/src/HolonDeploymentDefinition.ts +0 -241
- package/src/HolonDeploymentRuntime.ts +0 -388
- package/src/HolonExecutionBinding.ts +0 -558
- package/src/HolonExecutionBindingProjection.ts +0 -450
- package/src/index.ts +0 -5
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { type JsonSchema, type KindReaderRegistration, type KindSemanticContract } from "halfcode-compiler.xnl/resource-core";
|
|
2
|
+
export declare const HOLON_EXECUTION_BINDING_KIND: "HolonExecutionBinding";
|
|
3
|
+
export declare const HOLON_EXECUTION_BINDING_KIND_DEFINITION_FQN: "Eidolon.AI.KindDefinition.HolonExecutionBinding";
|
|
4
|
+
export declare const HOLON_EXECUTION_BINDING_API_VERSION: "eidolon.ai/v1";
|
|
5
|
+
export declare const HOLON_EXECUTION_BINDING_KIND_DEFINITION_SPEC_VERSION: 1;
|
|
6
|
+
export declare const HOLON_EXECUTION_BINDING_KIND_OWNER_PACKAGE_ID: "holarchy-eidolon-adapter";
|
|
7
|
+
export declare const HOLON_EXECUTION_BINDING_KIND_OWNER_PACKAGE_FINGERPRINT: `sha256:${string}`;
|
|
8
|
+
export declare const HOLON_EXECUTION_BINDING_KIND_OWNER: import("halfcode-compiler.xnl/resource-core").KindSubjectOwner;
|
|
9
|
+
export declare const HOLON_EXECUTION_BINDING_SPEC_SCHEMA_V1: JsonSchema;
|
|
10
|
+
export declare const HOLON_EXECUTION_BINDING_SEMANTIC_CONTRACT_V1: KindSemanticContract;
|
|
11
|
+
export declare const HOLON_EXECUTION_BINDING_KIND_SPEC_REVISION_V1: import("halfcode-compiler.xnl/resource-core").KindSpecRevision;
|
|
12
|
+
export declare const HOLON_EXECUTION_BINDING_KIND_DEFINITION_SOURCE: string;
|
|
13
|
+
export declare const HOLON_EXECUTION_BINDING_KIND_DEFINITION_BYTES: Readonly<Uint8Array>;
|
|
14
|
+
export declare const HOLON_MEMBER_EXECUTION_ADAPTER_KINDS: readonly ["ai-agent", "human-endpoint", "service", "hybrid"];
|
|
15
|
+
export type HolonExecutionResourceRef = `resource://${string}`;
|
|
16
|
+
export type HolonExecutionTarget = Readonly<{
|
|
17
|
+
readonly kind: "member";
|
|
18
|
+
readonly memberRef: string;
|
|
19
|
+
}> | Readonly<{
|
|
20
|
+
readonly kind: "role";
|
|
21
|
+
readonly roleRef: string;
|
|
22
|
+
}>;
|
|
23
|
+
export type HolonMemberExecutionAdapter = Readonly<{
|
|
24
|
+
readonly kind: "ai-agent";
|
|
25
|
+
readonly agentDefinitionRef: HolonExecutionResourceRef;
|
|
26
|
+
readonly runtimeProfileRef: HolonExecutionResourceRef;
|
|
27
|
+
}> | Readonly<{
|
|
28
|
+
readonly kind: "human-endpoint";
|
|
29
|
+
readonly humanEndpointRef: HolonExecutionResourceRef;
|
|
30
|
+
readonly inboxProfileRef: HolonExecutionResourceRef;
|
|
31
|
+
}> | Readonly<{
|
|
32
|
+
readonly kind: "service";
|
|
33
|
+
readonly serviceAdapterRef: HolonExecutionResourceRef;
|
|
34
|
+
readonly runtimeProfileRef: HolonExecutionResourceRef;
|
|
35
|
+
}> | Readonly<{
|
|
36
|
+
readonly kind: "hybrid";
|
|
37
|
+
readonly policyRef: HolonExecutionResourceRef;
|
|
38
|
+
readonly candidateBindingRefs: readonly [HolonExecutionResourceRef, ...HolonExecutionResourceRef[]];
|
|
39
|
+
}>;
|
|
40
|
+
export type HolonExecutionRuntimeIntent = Readonly<{
|
|
41
|
+
readonly mode: "shared-member-runtime";
|
|
42
|
+
}> | Readonly<{
|
|
43
|
+
readonly mode: "isolated-task-runtime";
|
|
44
|
+
}>;
|
|
45
|
+
export interface HolonExecutionPolicyV1 {
|
|
46
|
+
readonly version: "1";
|
|
47
|
+
readonly runtime: HolonExecutionRuntimeIntent;
|
|
48
|
+
readonly taskProfileRef: HolonExecutionResourceRef;
|
|
49
|
+
readonly capabilityRefs: readonly HolonExecutionResourceRef[];
|
|
50
|
+
readonly toolRefs: readonly HolonExecutionResourceRef[];
|
|
51
|
+
readonly materialRefs: readonly HolonExecutionResourceRef[];
|
|
52
|
+
}
|
|
53
|
+
export interface HolonExecutionBinding {
|
|
54
|
+
readonly apiVersion: typeof HOLON_EXECUTION_BINDING_API_VERSION;
|
|
55
|
+
readonly kind: typeof HOLON_EXECUTION_BINDING_KIND;
|
|
56
|
+
readonly bindingRef: HolonExecutionResourceRef;
|
|
57
|
+
readonly snapshotRef: HolonExecutionResourceRef;
|
|
58
|
+
readonly target: HolonExecutionTarget;
|
|
59
|
+
readonly adapter: HolonMemberExecutionAdapter;
|
|
60
|
+
readonly policy: HolonExecutionPolicyV1;
|
|
61
|
+
}
|
|
62
|
+
export interface HolonExecutionInvocation {
|
|
63
|
+
readonly apiVersion: typeof HOLON_EXECUTION_BINDING_API_VERSION;
|
|
64
|
+
readonly kind: "HolonExecutionInvocation";
|
|
65
|
+
readonly taskSpaceRef: string;
|
|
66
|
+
readonly taskRef: string;
|
|
67
|
+
readonly claimRef: string;
|
|
68
|
+
readonly invocationRef: string;
|
|
69
|
+
readonly targetBindingRef: HolonExecutionResourceRef;
|
|
70
|
+
readonly input: ClosedValue;
|
|
71
|
+
readonly materialRefs: readonly HolonExecutionResourceRef[];
|
|
72
|
+
readonly resultContractRef: HolonExecutionResourceRef;
|
|
73
|
+
}
|
|
74
|
+
interface ClosedArray extends ReadonlyArray<ClosedValue> {
|
|
75
|
+
}
|
|
76
|
+
interface ClosedRecord {
|
|
77
|
+
readonly [key: string]: ClosedValue;
|
|
78
|
+
}
|
|
79
|
+
export type ClosedValue = null | string | number | boolean | ClosedArray | ClosedRecord;
|
|
80
|
+
export declare class HolonExecutionBindingContractError extends Error {
|
|
81
|
+
readonly path: string;
|
|
82
|
+
constructor(path: string, message: string);
|
|
83
|
+
}
|
|
84
|
+
export declare function normalizeHolonExecutionBinding(value: unknown): HolonExecutionBinding;
|
|
85
|
+
export declare function canonicalHolonExecutionBindingBytes(value: unknown): Uint8Array;
|
|
86
|
+
export declare function parseHolonExecutionBindingBytes(bytes: Uint8Array): HolonExecutionBinding;
|
|
87
|
+
export declare const HOLON_EXECUTION_BINDING_KIND_READER_REGISTRATION_V1: KindReaderRegistration<HolonExecutionBinding>;
|
|
88
|
+
export declare function validateHolonExecutionBindingGraph(values: readonly HolonExecutionBinding[]): readonly HolonExecutionBinding[];
|
|
89
|
+
export declare function normalizeHolonExecutionInvocation(value: unknown): HolonExecutionInvocation;
|
|
90
|
+
export {};
|
|
@@ -0,0 +1,453 @@
|
|
|
1
|
+
import { decodeCanonicalBase64 } from './canonicalBase64.js';
|
|
2
|
+
import { digestCanonical, } from "halfcode-compiler.xnl/resource-core";
|
|
3
|
+
import { createKindSpecRevision, createKindSubjectOwner, } from "halfcode-compiler.xnl/kind-definition";
|
|
4
|
+
export const HOLON_EXECUTION_BINDING_KIND = "HolonExecutionBinding";
|
|
5
|
+
export const HOLON_EXECUTION_BINDING_KIND_DEFINITION_FQN = "Eidolon.AI.KindDefinition.HolonExecutionBinding";
|
|
6
|
+
export const HOLON_EXECUTION_BINDING_API_VERSION = "eidolon.ai/v1";
|
|
7
|
+
export const HOLON_EXECUTION_BINDING_KIND_DEFINITION_SPEC_VERSION = 1;
|
|
8
|
+
export const HOLON_EXECUTION_BINDING_KIND_OWNER_PACKAGE_ID = "holarchy-eidolon-adapter";
|
|
9
|
+
export const HOLON_EXECUTION_BINDING_KIND_OWNER_PACKAGE_FINGERPRINT = digestCanonical(Object.freeze({
|
|
10
|
+
authority: "holarchy-eidolon-adapter/holon-execution-binding-kind/v1",
|
|
11
|
+
ownerPackageId: HOLON_EXECUTION_BINDING_KIND_OWNER_PACKAGE_ID,
|
|
12
|
+
subjects: Object.freeze([HOLON_EXECUTION_BINDING_KIND_DEFINITION_FQN]),
|
|
13
|
+
semanticContractVersion: HOLON_EXECUTION_BINDING_API_VERSION,
|
|
14
|
+
}));
|
|
15
|
+
export const HOLON_EXECUTION_BINDING_KIND_OWNER = createKindSubjectOwner({
|
|
16
|
+
kind: HOLON_EXECUTION_BINDING_KIND,
|
|
17
|
+
subjectFqn: HOLON_EXECUTION_BINDING_KIND_DEFINITION_FQN,
|
|
18
|
+
ownerPackageId: HOLON_EXECUTION_BINDING_KIND_OWNER_PACKAGE_ID,
|
|
19
|
+
ownerPackageFingerprint: HOLON_EXECUTION_BINDING_KIND_OWNER_PACKAGE_FINGERPRINT,
|
|
20
|
+
sourceShapes: Object.freeze(["single-file"]),
|
|
21
|
+
documentCardinality: "one",
|
|
22
|
+
});
|
|
23
|
+
export const HOLON_EXECUTION_BINDING_SPEC_SCHEMA_V1 = Object.freeze({
|
|
24
|
+
type: "object",
|
|
25
|
+
required: Object.freeze(["properties", "body", "subdomains"]),
|
|
26
|
+
properties: Object.freeze({
|
|
27
|
+
properties: Object.freeze({
|
|
28
|
+
type: "object",
|
|
29
|
+
required: Object.freeze(["bindingBytesBase64"]),
|
|
30
|
+
properties: Object.freeze({
|
|
31
|
+
bindingBytesBase64: Object.freeze({ type: "string", minLength: 1 }),
|
|
32
|
+
}),
|
|
33
|
+
additionalProperties: false,
|
|
34
|
+
}),
|
|
35
|
+
body: Object.freeze({ type: "array", maxItems: 0 }),
|
|
36
|
+
subdomains: Object.freeze({ type: "object", maxProperties: 0 }),
|
|
37
|
+
}),
|
|
38
|
+
additionalProperties: false,
|
|
39
|
+
});
|
|
40
|
+
export const HOLON_EXECUTION_BINDING_SEMANTIC_CONTRACT_V1 = Object.freeze({
|
|
41
|
+
semanticValidatorFingerprint: digestCanonical(Object.freeze({
|
|
42
|
+
authority: "holarchy-eidolon-adapter/holon-execution-binding-kind/v1",
|
|
43
|
+
role: "canonical-binding-and-graph-validation",
|
|
44
|
+
apiVersion: HOLON_EXECUTION_BINDING_API_VERSION,
|
|
45
|
+
validators: Object.freeze([
|
|
46
|
+
"parseHolonExecutionBindingBytes",
|
|
47
|
+
"validateHolonExecutionBindingGraph",
|
|
48
|
+
]),
|
|
49
|
+
})),
|
|
50
|
+
referenceProjectionFingerprint: digestCanonical(Object.freeze({
|
|
51
|
+
authority: "holarchy-eidolon-adapter/holon-execution-binding-kind/v1",
|
|
52
|
+
role: "closed-execution-binding-reference-projection",
|
|
53
|
+
fields: Object.freeze([
|
|
54
|
+
"snapshotRef",
|
|
55
|
+
"adapter",
|
|
56
|
+
"policy.taskProfileRef",
|
|
57
|
+
"policy.capabilityRefs",
|
|
58
|
+
"policy.toolRefs",
|
|
59
|
+
"policy.materialRefs",
|
|
60
|
+
]),
|
|
61
|
+
})),
|
|
62
|
+
compilerInputFingerprint: digestCanonical(Object.freeze({
|
|
63
|
+
authority: "holarchy-eidolon-adapter/holon-execution-binding-kind/v1",
|
|
64
|
+
role: "authored-resource-to-canonical-binding-input",
|
|
65
|
+
fields: Object.freeze(["properties.bindingBytesBase64"]),
|
|
66
|
+
encoding: "canonical-base64",
|
|
67
|
+
})),
|
|
68
|
+
});
|
|
69
|
+
export const HOLON_EXECUTION_BINDING_KIND_SPEC_REVISION_V1 = createKindSpecRevision({
|
|
70
|
+
kind: HOLON_EXECUTION_BINDING_KIND_OWNER.kind,
|
|
71
|
+
subjectFqn: HOLON_EXECUTION_BINDING_KIND_OWNER.subjectFqn,
|
|
72
|
+
specVersion: HOLON_EXECUTION_BINDING_KIND_DEFINITION_SPEC_VERSION,
|
|
73
|
+
specSchema: HOLON_EXECUTION_BINDING_SPEC_SCHEMA_V1,
|
|
74
|
+
semanticContract: HOLON_EXECUTION_BINDING_SEMANTIC_CONTRACT_V1,
|
|
75
|
+
sourceContractFingerprint: HOLON_EXECUTION_BINDING_KIND_OWNER.sourceContract.sourceContractFingerprint,
|
|
76
|
+
stability: "stable",
|
|
77
|
+
});
|
|
78
|
+
function renderHolonExecutionBindingKindDefinition() {
|
|
79
|
+
const owner = HOLON_EXECUTION_BINDING_KIND_OWNER;
|
|
80
|
+
const revision = HOLON_EXECUTION_BINDING_KIND_SPEC_REVISION_V1;
|
|
81
|
+
return [
|
|
82
|
+
`<KindDefinition #${HOLON_EXECUTION_BINDING_KIND_DEFINITION_FQN} envelopeVersion="halfcode.resource-envelope/v1" specVersion=1 {`,
|
|
83
|
+
' lifecycle = "Stable"',
|
|
84
|
+
` resourceKind = "${owner.kind}"`,
|
|
85
|
+
` subjectFqn = "${owner.subjectFqn}"`,
|
|
86
|
+
' sourceShapes = ["single-file"]',
|
|
87
|
+
` documentCardinality = "${owner.sourceContract.documentCardinality}"`,
|
|
88
|
+
' description = "Maps one frozen Holon Member or Role identity to an exact Eidolon execution adapter closure."',
|
|
89
|
+
'} (',
|
|
90
|
+
' <SpecRevisions [',
|
|
91
|
+
` <SpecRevision #v${revision.specVersion} {`,
|
|
92
|
+
` specVersion = ${revision.specVersion}`,
|
|
93
|
+
' schemaRef = "vfs://./spec-v1.schema.json"',
|
|
94
|
+
` schemaFingerprint = "${revision.schemaFingerprint}"`,
|
|
95
|
+
` contractFingerprint = "${revision.contractFingerprint}"`,
|
|
96
|
+
` semanticValidatorFingerprint = "${revision.semanticContract.semanticValidatorFingerprint}"`,
|
|
97
|
+
` referenceProjectionFingerprint = "${revision.semanticContract.referenceProjectionFingerprint}"`,
|
|
98
|
+
` compilerInputFingerprint = "${revision.semanticContract.compilerInputFingerprint}"`,
|
|
99
|
+
` stability = "${revision.stability}"`,
|
|
100
|
+
' }>',
|
|
101
|
+
' ]>',
|
|
102
|
+
')>',
|
|
103
|
+
'',
|
|
104
|
+
].join("\n");
|
|
105
|
+
}
|
|
106
|
+
export const HOLON_EXECUTION_BINDING_KIND_DEFINITION_SOURCE = renderHolonExecutionBindingKindDefinition();
|
|
107
|
+
export const HOLON_EXECUTION_BINDING_KIND_DEFINITION_BYTES = new TextEncoder().encode(HOLON_EXECUTION_BINDING_KIND_DEFINITION_SOURCE);
|
|
108
|
+
export const HOLON_MEMBER_EXECUTION_ADAPTER_KINDS = Object.freeze([
|
|
109
|
+
"ai-agent",
|
|
110
|
+
"human-endpoint",
|
|
111
|
+
"service",
|
|
112
|
+
"hybrid",
|
|
113
|
+
]);
|
|
114
|
+
export class HolonExecutionBindingContractError extends Error {
|
|
115
|
+
path;
|
|
116
|
+
constructor(path, message) {
|
|
117
|
+
super(`${path}: ${message}`);
|
|
118
|
+
this.path = path;
|
|
119
|
+
this.name = "HolonExecutionBindingContractError";
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
const invalid = (path, message) => {
|
|
123
|
+
throw new HolonExecutionBindingContractError(path, message);
|
|
124
|
+
};
|
|
125
|
+
const compareUtf16CodeUnits = (left, right) => left < right ? -1 : left > right ? 1 : 0;
|
|
126
|
+
function closedObject(value, path) {
|
|
127
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
128
|
+
return invalid(path, "Expected a plain object");
|
|
129
|
+
}
|
|
130
|
+
const prototype = Object.getPrototypeOf(value);
|
|
131
|
+
if (prototype !== Object.prototype && prototype !== null) {
|
|
132
|
+
return invalid(path, "Expected a plain object");
|
|
133
|
+
}
|
|
134
|
+
const descriptors = Object.getOwnPropertyDescriptors(value);
|
|
135
|
+
const keys = Reflect.ownKeys(descriptors);
|
|
136
|
+
if (keys.some((key) => typeof key !== "string")) {
|
|
137
|
+
return invalid(path, "Symbol properties are not allowed");
|
|
138
|
+
}
|
|
139
|
+
const result = Object.create(null);
|
|
140
|
+
for (const key of keys.sort(compareUtf16CodeUnits)) {
|
|
141
|
+
const descriptor = descriptors[key];
|
|
142
|
+
if (!descriptor || !("value" in descriptor) || descriptor.enumerable !== true) {
|
|
143
|
+
return invalid(`${path}.${key}`, "Expected one enumerable own-data property");
|
|
144
|
+
}
|
|
145
|
+
result[key] = descriptor.value;
|
|
146
|
+
}
|
|
147
|
+
return result;
|
|
148
|
+
}
|
|
149
|
+
function exactKeys(value, expected, path) {
|
|
150
|
+
const expectedSet = new Set(expected);
|
|
151
|
+
const extra = Object.keys(value).find((key) => !expectedSet.has(key));
|
|
152
|
+
if (extra !== undefined)
|
|
153
|
+
invalid(`${path}.${extra}`, "Unsupported field");
|
|
154
|
+
const missing = expected.find((key) => !Object.prototype.hasOwnProperty.call(value, key));
|
|
155
|
+
if (missing !== undefined)
|
|
156
|
+
invalid(`${path}.${missing}`, "Required field is missing");
|
|
157
|
+
}
|
|
158
|
+
function exactString(value, path) {
|
|
159
|
+
if (typeof value !== "string" || value.length === 0 || value !== value.trim()) {
|
|
160
|
+
return invalid(path, "Expected an exact non-empty string");
|
|
161
|
+
}
|
|
162
|
+
return value;
|
|
163
|
+
}
|
|
164
|
+
function exactLiteral(value, expected, path) {
|
|
165
|
+
if (value !== expected)
|
|
166
|
+
invalid(path, `Expected '${expected}'`);
|
|
167
|
+
return expected;
|
|
168
|
+
}
|
|
169
|
+
function resourceRef(value, path) {
|
|
170
|
+
const exact = exactString(value, path);
|
|
171
|
+
const prefix = "resource://";
|
|
172
|
+
if (!exact.startsWith(prefix))
|
|
173
|
+
invalid(path, "Expected an exact resource:// reference");
|
|
174
|
+
const identity = exact.slice(prefix.length);
|
|
175
|
+
if (!identity || identity.includes("://"))
|
|
176
|
+
invalid(path, "Expected one exact Resource identity");
|
|
177
|
+
return exact;
|
|
178
|
+
}
|
|
179
|
+
function denseArray(value, path) {
|
|
180
|
+
if (!Array.isArray(value) || Object.getPrototypeOf(value) !== Array.prototype) {
|
|
181
|
+
return invalid(path, "Expected a plain dense array");
|
|
182
|
+
}
|
|
183
|
+
const descriptors = Object.getOwnPropertyDescriptors(value);
|
|
184
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
185
|
+
const descriptor = descriptors[String(index)];
|
|
186
|
+
if (!descriptor || !("value" in descriptor) || descriptor.enumerable !== true) {
|
|
187
|
+
return invalid(`${path}[${index}]`, "Expected a dense enumerable own-data entry");
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
for (const key of Reflect.ownKeys(descriptors)) {
|
|
191
|
+
if (key === "length")
|
|
192
|
+
continue;
|
|
193
|
+
if (typeof key !== "string" || !/^(0|[1-9][0-9]*)$/.test(key) || Number(key) >= value.length) {
|
|
194
|
+
return invalid(path, "Symbol and extra array properties are not allowed");
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return value;
|
|
198
|
+
}
|
|
199
|
+
function resourceRefs(value, path, options = {}) {
|
|
200
|
+
const refs = denseArray(value, path).map((entry, index) => resourceRef(entry, `${path}[${index}]`));
|
|
201
|
+
if (options.nonEmpty && refs.length === 0)
|
|
202
|
+
invalid(path, "Expected at least one Resource reference");
|
|
203
|
+
if (new Set(refs).size !== refs.length)
|
|
204
|
+
invalid(path, "Resource reference list contains a duplicate");
|
|
205
|
+
if (options.sort)
|
|
206
|
+
refs.sort(compareUtf16CodeUnits);
|
|
207
|
+
return Object.freeze(refs);
|
|
208
|
+
}
|
|
209
|
+
function target(value) {
|
|
210
|
+
const record = closedObject(value, "$.target");
|
|
211
|
+
const kind = exactString(record.kind, "$.target.kind");
|
|
212
|
+
if (kind === "member") {
|
|
213
|
+
exactKeys(record, ["kind", "memberRef"], "$.target");
|
|
214
|
+
return Object.freeze({ kind, memberRef: exactString(record.memberRef, "$.target.memberRef") });
|
|
215
|
+
}
|
|
216
|
+
if (kind === "role") {
|
|
217
|
+
exactKeys(record, ["kind", "roleRef"], "$.target");
|
|
218
|
+
return Object.freeze({ kind, roleRef: exactString(record.roleRef, "$.target.roleRef") });
|
|
219
|
+
}
|
|
220
|
+
return invalid("$.target.kind", "Expected 'member' or 'role'");
|
|
221
|
+
}
|
|
222
|
+
function adapter(value) {
|
|
223
|
+
const record = closedObject(value, "$.adapter");
|
|
224
|
+
const kind = exactString(record.kind, "$.adapter.kind");
|
|
225
|
+
if (kind === "ai-agent") {
|
|
226
|
+
exactKeys(record, ["kind", "agentDefinitionRef", "runtimeProfileRef"], "$.adapter");
|
|
227
|
+
return Object.freeze({
|
|
228
|
+
kind,
|
|
229
|
+
agentDefinitionRef: resourceRef(record.agentDefinitionRef, "$.adapter.agentDefinitionRef"),
|
|
230
|
+
runtimeProfileRef: resourceRef(record.runtimeProfileRef, "$.adapter.runtimeProfileRef"),
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
if (kind === "human-endpoint") {
|
|
234
|
+
exactKeys(record, ["kind", "humanEndpointRef", "inboxProfileRef"], "$.adapter");
|
|
235
|
+
return Object.freeze({
|
|
236
|
+
kind,
|
|
237
|
+
humanEndpointRef: resourceRef(record.humanEndpointRef, "$.adapter.humanEndpointRef"),
|
|
238
|
+
inboxProfileRef: resourceRef(record.inboxProfileRef, "$.adapter.inboxProfileRef"),
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
if (kind === "service") {
|
|
242
|
+
exactKeys(record, ["kind", "serviceAdapterRef", "runtimeProfileRef"], "$.adapter");
|
|
243
|
+
return Object.freeze({
|
|
244
|
+
kind,
|
|
245
|
+
serviceAdapterRef: resourceRef(record.serviceAdapterRef, "$.adapter.serviceAdapterRef"),
|
|
246
|
+
runtimeProfileRef: resourceRef(record.runtimeProfileRef, "$.adapter.runtimeProfileRef"),
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
if (kind === "hybrid") {
|
|
250
|
+
exactKeys(record, ["kind", "policyRef", "candidateBindingRefs"], "$.adapter");
|
|
251
|
+
const refs = resourceRefs(record.candidateBindingRefs, "$.adapter.candidateBindingRefs", { nonEmpty: true });
|
|
252
|
+
return Object.freeze({
|
|
253
|
+
kind,
|
|
254
|
+
policyRef: resourceRef(record.policyRef, "$.adapter.policyRef"),
|
|
255
|
+
candidateBindingRefs: refs,
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
return invalid("$.adapter.kind", "Expected one closed execution adapter kind");
|
|
259
|
+
}
|
|
260
|
+
function policy(value) {
|
|
261
|
+
const record = closedObject(value, "$.policy");
|
|
262
|
+
exactKeys(record, [
|
|
263
|
+
"version",
|
|
264
|
+
"runtime",
|
|
265
|
+
"taskProfileRef",
|
|
266
|
+
"capabilityRefs",
|
|
267
|
+
"toolRefs",
|
|
268
|
+
"materialRefs",
|
|
269
|
+
], "$.policy");
|
|
270
|
+
exactLiteral(record.version, "1", "$.policy.version");
|
|
271
|
+
const runtime = closedObject(record.runtime, "$.policy.runtime");
|
|
272
|
+
exactKeys(runtime, ["mode"], "$.policy.runtime");
|
|
273
|
+
const mode = exactString(runtime.mode, "$.policy.runtime.mode");
|
|
274
|
+
if (mode !== "shared-member-runtime" && mode !== "isolated-task-runtime") {
|
|
275
|
+
invalid("$.policy.runtime.mode", "Expected one closed runtime intent");
|
|
276
|
+
}
|
|
277
|
+
const normalizedMode = mode;
|
|
278
|
+
return Object.freeze({
|
|
279
|
+
version: "1",
|
|
280
|
+
runtime: Object.freeze({ mode: normalizedMode }),
|
|
281
|
+
taskProfileRef: resourceRef(record.taskProfileRef, "$.policy.taskProfileRef"),
|
|
282
|
+
capabilityRefs: resourceRefs(record.capabilityRefs, "$.policy.capabilityRefs", { sort: true }),
|
|
283
|
+
toolRefs: resourceRefs(record.toolRefs, "$.policy.toolRefs", { sort: true }),
|
|
284
|
+
materialRefs: resourceRefs(record.materialRefs, "$.policy.materialRefs", { sort: true }),
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
export function normalizeHolonExecutionBinding(value) {
|
|
288
|
+
const record = closedObject(value, "$");
|
|
289
|
+
exactKeys(record, [
|
|
290
|
+
"apiVersion",
|
|
291
|
+
"kind",
|
|
292
|
+
"bindingRef",
|
|
293
|
+
"snapshotRef",
|
|
294
|
+
"target",
|
|
295
|
+
"adapter",
|
|
296
|
+
"policy",
|
|
297
|
+
], "$");
|
|
298
|
+
return Object.freeze({
|
|
299
|
+
apiVersion: exactLiteral(record.apiVersion, HOLON_EXECUTION_BINDING_API_VERSION, "$.apiVersion"),
|
|
300
|
+
kind: exactLiteral(record.kind, HOLON_EXECUTION_BINDING_KIND, "$.kind"),
|
|
301
|
+
bindingRef: resourceRef(record.bindingRef, "$.bindingRef"),
|
|
302
|
+
snapshotRef: resourceRef(record.snapshotRef, "$.snapshotRef"),
|
|
303
|
+
target: target(record.target),
|
|
304
|
+
adapter: adapter(record.adapter),
|
|
305
|
+
policy: policy(record.policy),
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
function sameBytes(left, right) {
|
|
309
|
+
if (left.byteLength !== right.byteLength)
|
|
310
|
+
return false;
|
|
311
|
+
for (let index = 0; index < left.byteLength; index += 1) {
|
|
312
|
+
if (left[index] !== right[index])
|
|
313
|
+
return false;
|
|
314
|
+
}
|
|
315
|
+
return true;
|
|
316
|
+
}
|
|
317
|
+
export function canonicalHolonExecutionBindingBytes(value) {
|
|
318
|
+
return new TextEncoder().encode(JSON.stringify(normalizeHolonExecutionBinding(value)));
|
|
319
|
+
}
|
|
320
|
+
export function parseHolonExecutionBindingBytes(bytes) {
|
|
321
|
+
let decoded;
|
|
322
|
+
try {
|
|
323
|
+
decoded = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
324
|
+
}
|
|
325
|
+
catch {
|
|
326
|
+
return invalid("$bytes", "Binding bytes are not valid UTF-8");
|
|
327
|
+
}
|
|
328
|
+
let value;
|
|
329
|
+
try {
|
|
330
|
+
value = JSON.parse(decoded);
|
|
331
|
+
}
|
|
332
|
+
catch {
|
|
333
|
+
return invalid("$bytes", "Binding bytes are not valid JSON");
|
|
334
|
+
}
|
|
335
|
+
const binding = normalizeHolonExecutionBinding(value);
|
|
336
|
+
if (!sameBytes(bytes, canonicalHolonExecutionBindingBytes(binding))) {
|
|
337
|
+
return invalid("$bytes", "Binding bytes are not canonical");
|
|
338
|
+
}
|
|
339
|
+
return binding;
|
|
340
|
+
}
|
|
341
|
+
function canonicalBase64SpecBytes(spec, property) {
|
|
342
|
+
const properties = closedObject(spec.properties, "$.properties");
|
|
343
|
+
exactKeys(properties, [property], "$.properties");
|
|
344
|
+
const value = exactString(properties[property], `$.properties.${property}`);
|
|
345
|
+
let bytes;
|
|
346
|
+
try {
|
|
347
|
+
bytes = decodeCanonicalBase64(value);
|
|
348
|
+
}
|
|
349
|
+
catch {
|
|
350
|
+
return invalid(`$.properties.${property}`, "Expected canonical base64");
|
|
351
|
+
}
|
|
352
|
+
return bytes;
|
|
353
|
+
}
|
|
354
|
+
export const HOLON_EXECUTION_BINDING_KIND_READER_REGISTRATION_V1 = Object.freeze({
|
|
355
|
+
readerId: "holarchy-eidolon-adapter.holon-execution-binding.v1",
|
|
356
|
+
subjectFqn: HOLON_EXECUTION_BINDING_KIND_DEFINITION_FQN,
|
|
357
|
+
readerSpecVersion: HOLON_EXECUTION_BINDING_KIND_DEFINITION_SPEC_VERSION,
|
|
358
|
+
contractFingerprint: HOLON_EXECUTION_BINDING_KIND_SPEC_REVISION_V1.contractFingerprint,
|
|
359
|
+
readerImplementationFingerprint: digestCanonical(Object.freeze({
|
|
360
|
+
authority: "holarchy-eidolon-adapter/holon-execution-binding-reader/v1",
|
|
361
|
+
implementation: Object.freeze([
|
|
362
|
+
"canonicalBase64SpecBytes",
|
|
363
|
+
"parseHolonExecutionBindingBytes",
|
|
364
|
+
]),
|
|
365
|
+
})),
|
|
366
|
+
compatibilityPolicy: "exact",
|
|
367
|
+
read: (spec) => parseHolonExecutionBindingBytes(canonicalBase64SpecBytes(spec, "bindingBytesBase64")),
|
|
368
|
+
});
|
|
369
|
+
export function validateHolonExecutionBindingGraph(values) {
|
|
370
|
+
const bindings = values.map(normalizeHolonExecutionBinding);
|
|
371
|
+
const byRef = new Map();
|
|
372
|
+
for (const binding of bindings) {
|
|
373
|
+
if (byRef.has(binding.bindingRef)) {
|
|
374
|
+
invalid("$.bindings", `Duplicate binding identity '${binding.bindingRef}'`);
|
|
375
|
+
}
|
|
376
|
+
byRef.set(binding.bindingRef, binding);
|
|
377
|
+
}
|
|
378
|
+
const visiting = new Set();
|
|
379
|
+
const visited = new Set();
|
|
380
|
+
const visit = (bindingRef) => {
|
|
381
|
+
if (visited.has(bindingRef))
|
|
382
|
+
return;
|
|
383
|
+
if (visiting.has(bindingRef))
|
|
384
|
+
invalid("$.bindings", `Hybrid binding cycle includes '${bindingRef}'`);
|
|
385
|
+
const binding = byRef.get(bindingRef)
|
|
386
|
+
?? invalid("$.bindings", `Hybrid candidate '${bindingRef}' is unresolved`);
|
|
387
|
+
visiting.add(bindingRef);
|
|
388
|
+
if (binding.adapter.kind === "hybrid") {
|
|
389
|
+
for (const candidateRef of binding.adapter.candidateBindingRefs)
|
|
390
|
+
visit(candidateRef);
|
|
391
|
+
}
|
|
392
|
+
visiting.delete(bindingRef);
|
|
393
|
+
visited.add(bindingRef);
|
|
394
|
+
};
|
|
395
|
+
for (const binding of bindings)
|
|
396
|
+
visit(binding.bindingRef);
|
|
397
|
+
return Object.freeze(bindings);
|
|
398
|
+
}
|
|
399
|
+
function cloneClosedValue(value, path, active = new Set()) {
|
|
400
|
+
if (value === null || typeof value === "string" || typeof value === "boolean")
|
|
401
|
+
return value;
|
|
402
|
+
if (typeof value === "number") {
|
|
403
|
+
if (!Number.isFinite(value))
|
|
404
|
+
invalid(path, "Expected a finite number");
|
|
405
|
+
return value;
|
|
406
|
+
}
|
|
407
|
+
if (typeof value !== "object")
|
|
408
|
+
return invalid(path, "Expected JSON-compatible plain data");
|
|
409
|
+
if (active.has(value))
|
|
410
|
+
return invalid(path, "Cycles are not allowed");
|
|
411
|
+
active.add(value);
|
|
412
|
+
try {
|
|
413
|
+
if (Array.isArray(value)) {
|
|
414
|
+
return Object.freeze(denseArray(value, path).map((entry, index) => cloneClosedValue(entry, `${path}[${index}]`, active)));
|
|
415
|
+
}
|
|
416
|
+
const record = closedObject(value, path);
|
|
417
|
+
const output = Object.create(null);
|
|
418
|
+
for (const key of Object.keys(record).sort(compareUtf16CodeUnits)) {
|
|
419
|
+
output[key] = cloneClosedValue(record[key], `${path}.${key}`, active);
|
|
420
|
+
}
|
|
421
|
+
return Object.freeze(output);
|
|
422
|
+
}
|
|
423
|
+
finally {
|
|
424
|
+
active.delete(value);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
export function normalizeHolonExecutionInvocation(value) {
|
|
428
|
+
const record = closedObject(value, "$");
|
|
429
|
+
exactKeys(record, [
|
|
430
|
+
"apiVersion",
|
|
431
|
+
"kind",
|
|
432
|
+
"taskSpaceRef",
|
|
433
|
+
"taskRef",
|
|
434
|
+
"claimRef",
|
|
435
|
+
"invocationRef",
|
|
436
|
+
"targetBindingRef",
|
|
437
|
+
"input",
|
|
438
|
+
"materialRefs",
|
|
439
|
+
"resultContractRef",
|
|
440
|
+
], "$");
|
|
441
|
+
return Object.freeze({
|
|
442
|
+
apiVersion: exactLiteral(record.apiVersion, HOLON_EXECUTION_BINDING_API_VERSION, "$.apiVersion"),
|
|
443
|
+
kind: exactLiteral(record.kind, "HolonExecutionInvocation", "$.kind"),
|
|
444
|
+
taskSpaceRef: exactString(record.taskSpaceRef, "$.taskSpaceRef"),
|
|
445
|
+
taskRef: exactString(record.taskRef, "$.taskRef"),
|
|
446
|
+
claimRef: exactString(record.claimRef, "$.claimRef"),
|
|
447
|
+
invocationRef: exactString(record.invocationRef, "$.invocationRef"),
|
|
448
|
+
targetBindingRef: resourceRef(record.targetBindingRef, "$.targetBindingRef"),
|
|
449
|
+
input: cloneClosedValue(record.input, "$.input"),
|
|
450
|
+
materialRefs: resourceRefs(record.materialRefs, "$.materialRefs", { sort: true }),
|
|
451
|
+
resultContractRef: resourceRef(record.resultContractRef, "$.resultContractRef"),
|
|
452
|
+
});
|
|
453
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { type HolonExecutionBinding, type HolonExecutionResourceRef } from "./HolonExecutionBinding.js";
|
|
2
|
+
import { type HolonEffectiveSnapshot, type HolonEffectiveSnapshotIssuanceReceipt } from "holarchy-core-contract";
|
|
3
|
+
import { type EffectiveResourceRegistry, type ResourceContentIdentity, type ResourceRecord } from "halfcode-compiler.xnl/resource-core";
|
|
4
|
+
import type { AIWorkflowAgentResourceProjection } from "ai-workflow-contract";
|
|
5
|
+
export interface EidolonHolonExecutionBindingProjection {
|
|
6
|
+
readonly schemaVersion: "eidolon.holon-execution-binding-projection/v1";
|
|
7
|
+
readonly resource: ResourceRecord;
|
|
8
|
+
readonly binding: HolonExecutionBinding;
|
|
9
|
+
readonly snapshotResource: ResourceRecord;
|
|
10
|
+
readonly snapshot: HolonEffectiveSnapshot;
|
|
11
|
+
readonly snapshotBytes: Uint8Array;
|
|
12
|
+
readonly receiptBytes: Uint8Array;
|
|
13
|
+
readonly receipt: HolonEffectiveSnapshotIssuanceReceipt;
|
|
14
|
+
readonly bindingBytesDigest: `sha256:${string}`;
|
|
15
|
+
readonly receiptBytesDigest: `sha256:${string}`;
|
|
16
|
+
readonly closureResourceIds: readonly string[];
|
|
17
|
+
readonly registryRevision: string;
|
|
18
|
+
}
|
|
19
|
+
export interface EidolonHolonExecutionAgentProof {
|
|
20
|
+
readonly agentDefinitionRef: HolonExecutionResourceRef;
|
|
21
|
+
readonly agentContentDigest: `sha256:${string}`;
|
|
22
|
+
readonly closureResourceIds: readonly string[];
|
|
23
|
+
readonly snapshotRevision: `sha256:${string}`;
|
|
24
|
+
}
|
|
25
|
+
export interface EidolonHolonExecutionBindingFreezeReceipt {
|
|
26
|
+
readonly schemaVersion: "eidolon.holon-execution-binding-freeze/v1";
|
|
27
|
+
readonly bindingRef: HolonExecutionResourceRef;
|
|
28
|
+
readonly snapshotRef: HolonExecutionResourceRef;
|
|
29
|
+
readonly snapshotTreeDigest: `sha256:${string}`;
|
|
30
|
+
readonly snapshotReceiptDigest: `sha256:${string}`;
|
|
31
|
+
readonly bindingBytesDigest: `sha256:${string}`;
|
|
32
|
+
readonly registryRevision: string;
|
|
33
|
+
readonly closure: readonly Readonly<{
|
|
34
|
+
readonly resourceId: string;
|
|
35
|
+
readonly kind: string;
|
|
36
|
+
readonly authorityDigest: `sha256:${string}`;
|
|
37
|
+
readonly contentDigest: `sha256:${string}`;
|
|
38
|
+
}>[];
|
|
39
|
+
readonly agentProofs: readonly EidolonHolonExecutionAgentProof[];
|
|
40
|
+
readonly semanticFingerprint: `sha256:${string}`;
|
|
41
|
+
}
|
|
42
|
+
export interface HolonExecutionBindingProjectionInput {
|
|
43
|
+
readonly registry: EffectiveResourceRegistry;
|
|
44
|
+
readonly contentIdentities: ReadonlyMap<string, ResourceContentIdentity>;
|
|
45
|
+
readonly kindDefinitionAuthorityDigests: ReadonlyMap<string, `sha256:${string}`>;
|
|
46
|
+
readonly registryRevision: string;
|
|
47
|
+
}
|
|
48
|
+
export interface HolonExecutionBindingFreezeInput {
|
|
49
|
+
readonly registry: EffectiveResourceRegistry;
|
|
50
|
+
readonly contentIdentities: ReadonlyMap<string, ResourceContentIdentity>;
|
|
51
|
+
readonly registryRevision: string;
|
|
52
|
+
readonly projection: EidolonHolonExecutionBindingProjection;
|
|
53
|
+
readonly agentResources: AIWorkflowAgentResourceProjection;
|
|
54
|
+
}
|
|
55
|
+
export declare function projectHolonExecutionBindings(input: HolonExecutionBindingProjectionInput): Promise<readonly EidolonHolonExecutionBindingProjection[]>;
|
|
56
|
+
export declare function freezeHolonExecutionBinding(input: HolonExecutionBindingFreezeInput): EidolonHolonExecutionBindingFreezeReceipt;
|
|
57
|
+
export declare function assertHolonExecutionBindingFreezeReceipt(value: EidolonHolonExecutionBindingFreezeReceipt): EidolonHolonExecutionBindingFreezeReceipt;
|