@serve.zone/interfaces 27.3.1 → 27.5.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/.smartconfig.json +11 -4
- package/changelog.md +30 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/data/index.d.ts +1 -0
- package/dist_ts/data/index.js +2 -1
- package/dist_ts/data/runtimeassignment.d.ts +120 -0
- package/dist_ts/data/runtimeassignment.js +267 -0
- package/dist_ts/runtime.cloudlylegacydeploymentsettlement.offlineexport.d.ts +291 -0
- package/dist_ts/runtime.cloudlylegacydeploymentsettlement.offlineexport.golden.d.ts +30 -0
- package/dist_ts/runtime.cloudlylegacydeploymentsettlement.offlineexport.golden.js +408 -0
- package/dist_ts/runtime.cloudlylegacydeploymentsettlement.offlineexport.js +1126 -0
- package/dist_ts/runtime.corestore.databaseexportpackage.d.ts +118 -0
- package/dist_ts/runtime.corestore.databaseexportpackage.golden.d.ts +22 -0
- package/dist_ts/runtime.corestore.databaseexportpackage.golden.js +242 -0
- package/dist_ts/runtime.corestore.databaseexportpackage.js +428 -0
- package/dist_ts/runtime.d.ts +2 -0
- package/dist_ts/runtime.js +3 -1
- package/package.json +4 -4
- package/readme.md +67 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/data/index.ts +1 -0
- package/ts/data/runtimeassignment.ts +402 -0
- package/ts/runtime.cloudlylegacydeploymentsettlement.offlineexport.golden.ts +510 -0
- package/ts/runtime.cloudlylegacydeploymentsettlement.offlineexport.ts +2470 -0
- package/ts/runtime.corestore.databaseexportpackage.golden.ts +323 -0
- package/ts/runtime.corestore.databaseexportpackage.ts +862 -0
- package/ts/runtime.ts +2 -0
- /package/{license → license.md} +0 -0
package/.smartconfig.json
CHANGED
|
@@ -20,10 +20,16 @@
|
|
|
20
20
|
]
|
|
21
21
|
},
|
|
22
22
|
"release": {
|
|
23
|
+
"preflight": {
|
|
24
|
+
"test": true,
|
|
25
|
+
"build": true
|
|
26
|
+
},
|
|
23
27
|
"targets": {
|
|
24
28
|
"git": {
|
|
25
29
|
"enabled": true,
|
|
26
|
-
"remote": "origin"
|
|
30
|
+
"remote": "origin",
|
|
31
|
+
"pushBranch": true,
|
|
32
|
+
"pushTags": true
|
|
27
33
|
},
|
|
28
34
|
"npm": {
|
|
29
35
|
"enabled": true,
|
|
@@ -31,7 +37,8 @@
|
|
|
31
37
|
"https://verdaccio.lossless.digital",
|
|
32
38
|
"https://registry.npmjs.org"
|
|
33
39
|
],
|
|
34
|
-
"accessLevel": "public"
|
|
40
|
+
"accessLevel": "public",
|
|
41
|
+
"alreadyPublished": "success"
|
|
35
42
|
},
|
|
36
43
|
"docker": {
|
|
37
44
|
"enabled": false,
|
|
@@ -41,7 +48,7 @@
|
|
|
41
48
|
}
|
|
42
49
|
},
|
|
43
50
|
"@git.zone/tsdoc": {
|
|
44
|
-
"legal": "\n## License and Legal Information\n\nThis repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository. \n\n**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.\n\n### Trademarks\n\nThis project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.\n\n### Company Information\n\nTask Venture Capital GmbH \nRegistered at District court Bremen HRB 35230 HB, Germany\n\nFor any legal inquiries or if you require further information, please contact us via email at hello@task.vc.\n\nBy using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.\n"
|
|
51
|
+
"legal": "\n## License and Legal Information\n\nThis repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license.md](license.md) file within this repository. \n\n**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.\n\n### Trademarks\n\nThis project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.\n\n### Company Information\n\nTask Venture Capital GmbH \nRegistered at District court Bremen HRB 35230 HB, Germany\n\nFor any legal inquiries or if you require further information, please contact us via email at hello@task.vc.\n\nBy using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.\n"
|
|
45
52
|
},
|
|
46
53
|
"@ship.zone/szci": {}
|
|
47
|
-
}
|
|
54
|
+
}
|
package/changelog.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2026-09-05 - 27.5.0
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- add node-bound runtime assignment contracts (data)
|
|
8
|
+
- Add runtime assignment interfaces, canonical digest helpers, and data namespace exports.
|
|
9
|
+
- Add assignment and observation validators/evaluators for scope binding, CAS progression, replay handling, and sequence checks.
|
|
10
|
+
- Document node-bound runtime assignment semantics and add node test coverage.
|
|
11
|
+
|
|
12
|
+
### Fixes
|
|
13
|
+
|
|
14
|
+
- update release workflow and package metadata (release)
|
|
15
|
+
- Enable test and build preflight checks before releases
|
|
16
|
+
- Configure git releases to push branches and tags
|
|
17
|
+
- Update packaged license file references to license.md
|
|
18
|
+
- Bump dev tooling and package manager versions
|
|
19
|
+
|
|
20
|
+
## 2026-08-29 - 27.4.0
|
|
21
|
+
|
|
22
|
+
### Features
|
|
23
|
+
|
|
24
|
+
- add offline SmartDB settlement and Corestore export-package contracts (runtime)
|
|
25
|
+
- Adds isolated V1 codecs and golden vectors for exact-file Cloudly settlement rehearsal, split production authority, HMAC-authenticated authorization, deterministic journaling, complete-output receipt, and bounded result metadata.
|
|
26
|
+
- Adds metadata-only Corestore database-export package requests, immutable completion and replay wrappers, explicit allocation expectations, and fsynced exact-copy release contracts.
|
|
27
|
+
- Preserves the existing transaction settlement and Corestore database backup/restore contracts and bytes.
|
|
28
|
+
|
|
29
|
+
### Fixes
|
|
30
|
+
|
|
31
|
+
- restore pnpm 11.21.0 metadata required by exact release packaging (tooling)
|
|
32
|
+
|
|
3
33
|
## 2026-08-18 - 27.3.1
|
|
4
34
|
|
|
5
35
|
### Fixes
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@serve.zone/interfaces',
|
|
6
|
-
version: '27.
|
|
6
|
+
version: '27.5.0',
|
|
7
7
|
description: 'Shared TypeScript interfaces and TypedRequest contracts for the serve.zone ecosystem.'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSx3QkFBd0I7SUFDOUIsT0FBTyxFQUFFLFFBQVE7SUFDakIsV0FBVyxFQUFFLHVGQUF1RjtDQUNyRyxDQUFBIn0=
|
package/dist_ts/data/index.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ export * from './isolatedrestore.js';
|
|
|
21
21
|
export * from './isolatedrestore.golden.js';
|
|
22
22
|
export * from './mail.js';
|
|
23
23
|
export * from './registry.js';
|
|
24
|
+
export * from './runtimeassignment.js';
|
|
24
25
|
export * from './secret.js';
|
|
25
26
|
export * from './baremetal.js';
|
|
26
27
|
export * from './baseos.js';
|
package/dist_ts/data/index.js
CHANGED
|
@@ -21,6 +21,7 @@ export * from './isolatedrestore.js';
|
|
|
21
21
|
export * from './isolatedrestore.golden.js';
|
|
22
22
|
export * from './mail.js';
|
|
23
23
|
export * from './registry.js';
|
|
24
|
+
export * from './runtimeassignment.js';
|
|
24
25
|
export * from './secret.js';
|
|
25
26
|
export * from './baremetal.js';
|
|
26
27
|
export * from './baseos.js';
|
|
@@ -35,4 +36,4 @@ export * from './traffic.js';
|
|
|
35
36
|
export * from './user.js';
|
|
36
37
|
export * from './version.js';
|
|
37
38
|
export * from './webpush.js';
|
|
38
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
39
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9kYXRhL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsb0JBQW9CLENBQUM7QUFDbkMsY0FBYyxjQUFjLENBQUM7QUFDN0IsY0FBYyxhQUFhLENBQUM7QUFDNUIsY0FBYyxlQUFlLENBQUM7QUFDOUIsY0FBYyx1QkFBdUIsQ0FBQztBQUN0QyxjQUFjLGlCQUFpQixDQUFDO0FBQ2hDLGNBQWMseUJBQXlCLENBQUM7QUFDeEMsY0FBYywwQkFBMEIsQ0FBQztBQUN6QyxjQUFjLDBCQUEwQixDQUFDO0FBQ3pDLGNBQWMsZ0JBQWdCLENBQUM7QUFDL0IsY0FBYyxVQUFVLENBQUM7QUFDekIsY0FBYyxhQUFhLENBQUM7QUFDNUIsY0FBYyxhQUFhLENBQUM7QUFDNUIsY0FBYyxZQUFZLENBQUM7QUFDM0IsY0FBYyx1QkFBdUIsQ0FBQztBQUN0QyxjQUFjLGNBQWMsQ0FBQztBQUM3QixjQUFjLGdCQUFnQixDQUFDO0FBQy9CLGNBQWMsWUFBWSxDQUFDO0FBQzNCLGNBQWMscUJBQXFCLENBQUM7QUFDcEMsY0FBYyxzQkFBc0IsQ0FBQztBQUNyQyxjQUFjLDZCQUE2QixDQUFDO0FBQzVDLGNBQWMsV0FBVyxDQUFDO0FBQzFCLGNBQWMsZUFBZSxDQUFDO0FBQzlCLGNBQWMsd0JBQXdCLENBQUM7QUFDdkMsY0FBYyxhQUFhLENBQUM7QUFDNUIsY0FBYyxnQkFBZ0IsQ0FBQztBQUMvQixjQUFjLGFBQWEsQ0FBQztBQUM1QixjQUFjLGFBQWEsQ0FBQztBQUM1QixjQUFjLGtCQUFrQixDQUFDO0FBQ2pDLGNBQWMsZUFBZSxDQUFDO0FBQzlCLGNBQWMsY0FBYyxDQUFDO0FBQzdCLGNBQWMsbUJBQW1CLENBQUM7QUFDbEMsY0FBYyxhQUFhLENBQUM7QUFDNUIsY0FBYyxvQkFBb0IsQ0FBQztBQUNuQyxjQUFjLGNBQWMsQ0FBQztBQUM3QixjQUFjLFdBQVcsQ0FBQztBQUMxQixjQUFjLGNBQWMsQ0FBQztBQUM3QixjQUFjLGNBQWMsQ0FBQyJ9
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import type { TSha256Digest, TImmutableContainerPlatform } from './immutableimage.js';
|
|
2
|
+
export interface IRuntimeControllerV1 {
|
|
3
|
+
kind: 'cloudly' | 'onebox';
|
|
4
|
+
id: string;
|
|
5
|
+
/** Persisted authority incarnation; changing it requires explicit re-admission. */
|
|
6
|
+
epoch: string;
|
|
7
|
+
}
|
|
8
|
+
/** Content-bound reference, not a credential, mount path or permission grant. */
|
|
9
|
+
export interface IRuntimeAuthorityReferenceV1 {
|
|
10
|
+
id: string;
|
|
11
|
+
generation: number;
|
|
12
|
+
digest: TSha256Digest;
|
|
13
|
+
}
|
|
14
|
+
export interface IRuntimeAssignmentReferenceV1 {
|
|
15
|
+
assignmentId: string;
|
|
16
|
+
generation: number;
|
|
17
|
+
digest: TSha256Digest;
|
|
18
|
+
}
|
|
19
|
+
/** Derived from authenticated transport and locally configured ownership. */
|
|
20
|
+
export interface IRuntimeAssignmentScopeV1 {
|
|
21
|
+
controller: IRuntimeControllerV1;
|
|
22
|
+
organizationId: string;
|
|
23
|
+
nodeId: string;
|
|
24
|
+
runtimeNamespace: string;
|
|
25
|
+
}
|
|
26
|
+
export type TRuntimeAssignmentDispositionV1 = 'run' | 'stop-preserve' | 'remove-runtime-preserve-storage';
|
|
27
|
+
export interface IRuntimeAssignmentV1 extends IRuntimeAssignmentScopeV1 {
|
|
28
|
+
schemaVersion: 1;
|
|
29
|
+
assignmentId: string;
|
|
30
|
+
serviceId: string;
|
|
31
|
+
/** Stable logical replica; independent of container IDs and execution attempts. */
|
|
32
|
+
replicaId: string;
|
|
33
|
+
/** One execution attempt, immutable for this assignment. */
|
|
34
|
+
attemptId: string;
|
|
35
|
+
/** Logical topology provenance; placement authority remains nodeId. */
|
|
36
|
+
workerGroupId: string | null;
|
|
37
|
+
siteId: string | null;
|
|
38
|
+
generation: number;
|
|
39
|
+
/** Exact CAS predecessor; null only at generation 1. */
|
|
40
|
+
previous: IRuntimeAssignmentReferenceV1 | null;
|
|
41
|
+
disposition: TRuntimeAssignmentDispositionV1;
|
|
42
|
+
/** No automatic relocation or expiry-based claim of a stopped writer. */
|
|
43
|
+
offlinePolicy: 'continue-node-bound';
|
|
44
|
+
workload: {
|
|
45
|
+
registryHost: string;
|
|
46
|
+
repository: string;
|
|
47
|
+
imageDigest: TSha256Digest;
|
|
48
|
+
platform: TImmutableContainerPlatform;
|
|
49
|
+
/** Immutable complete invocation/configuration owned by the controller. */
|
|
50
|
+
config: IRuntimeAuthorityReferenceV1;
|
|
51
|
+
network: IRuntimeAuthorityReferenceV1 | null;
|
|
52
|
+
secrets: IRuntimeAuthorityReferenceV1 | null;
|
|
53
|
+
/** Sorted unique reference IDs. Empty means no persistent storage claims. */
|
|
54
|
+
storage: IRuntimeAuthorityReferenceV1[];
|
|
55
|
+
};
|
|
56
|
+
digest: TSha256Digest;
|
|
57
|
+
}
|
|
58
|
+
export type TRuntimeAssignmentDecisionV1 = {
|
|
59
|
+
status: 'accept' | 'replay';
|
|
60
|
+
assignment: IRuntimeAssignmentV1;
|
|
61
|
+
} | {
|
|
62
|
+
status: 'reject';
|
|
63
|
+
reason: 'invalid' | 'scope-mismatch' | 'conflict' | 'stale' | 'predecessor-mismatch' | 'attempt-mismatch' | 'disposition-regression';
|
|
64
|
+
};
|
|
65
|
+
/** Value-free execution evidence. Receipt/acceptance alone never means ready. */
|
|
66
|
+
export interface IRuntimeAssignmentObservationV1 {
|
|
67
|
+
schemaVersion: 1;
|
|
68
|
+
assignment: IRuntimeAssignmentReferenceV1;
|
|
69
|
+
/** Authenticated reporter session; its authority is verified by the receiver. */
|
|
70
|
+
reporterSessionId: string;
|
|
71
|
+
/** Durable per-assignment counter; never resets when a reporter reconnects. */
|
|
72
|
+
sequence: number;
|
|
73
|
+
observedAt: number;
|
|
74
|
+
phase: 'pending' | 'running' | 'stopped' | 'removed' | 'failed' | 'unknown';
|
|
75
|
+
ready: boolean;
|
|
76
|
+
runtime: {
|
|
77
|
+
sandboxId: string;
|
|
78
|
+
containerId: string;
|
|
79
|
+
imageDigest: TSha256Digest;
|
|
80
|
+
} | null;
|
|
81
|
+
digest: TSha256Digest;
|
|
82
|
+
}
|
|
83
|
+
export declare const runtimeAssignmentV1Contract: Readonly<{
|
|
84
|
+
readonly assignmentDigestDomain: "serve.zone/runtime-assignment-v1";
|
|
85
|
+
readonly observationDigestDomain: "serve.zone/runtime-assignment-observation-v1";
|
|
86
|
+
readonly maximumStorageReferences: 64;
|
|
87
|
+
readonly omission: "no-effect";
|
|
88
|
+
readonly removal: "retain-assignment-tombstone-and-storage";
|
|
89
|
+
}>;
|
|
90
|
+
/** Digest helpers validate structure and exclude only the object's own digest. */
|
|
91
|
+
export declare const computeRuntimeAssignmentV1Digest: (assignmentArg: IRuntimeAssignmentV1) => Promise<TSha256Digest>;
|
|
92
|
+
export declare const validateRuntimeAssignmentV1: (valueArg: unknown) => Promise<string[]>;
|
|
93
|
+
export declare const getRuntimeAssignmentV1Reference: (assignmentArg: IRuntimeAssignmentV1) => IRuntimeAssignmentReferenceV1;
|
|
94
|
+
/**
|
|
95
|
+
* Pure CAS decision, not authentication or execution. The caller must persist
|
|
96
|
+
* acceptance atomically before effects, serialize replica ownership, and retain
|
|
97
|
+
* removed assignments as tombstones. New attempts require separate stop/fencing
|
|
98
|
+
* admission for every older writer. An omitted assignment causes no transition.
|
|
99
|
+
* Persist only the returned detached snapshot, never the mutable input object.
|
|
100
|
+
*/
|
|
101
|
+
export declare const evaluateRuntimeAssignmentV1: (incomingArg: IRuntimeAssignmentV1, acceptedArg: IRuntimeAssignmentV1 | null, trustedScopeArg: IRuntimeAssignmentScopeV1) => Promise<TRuntimeAssignmentDecisionV1>;
|
|
102
|
+
export declare const computeRuntimeAssignmentObservationV1Digest: (observationArg: IRuntimeAssignmentObservationV1) => Promise<TSha256Digest>;
|
|
103
|
+
/** Checks exact assignment evidence; transport must separately bind reporter/session. */
|
|
104
|
+
export declare const validateRuntimeAssignmentObservationV1: (observationArg: unknown, assignmentArg: IRuntimeAssignmentV1) => Promise<string[]>;
|
|
105
|
+
export type TRuntimeObservationDecisionV1 = {
|
|
106
|
+
status: 'accept' | 'replay';
|
|
107
|
+
observation: IRuntimeAssignmentObservationV1;
|
|
108
|
+
} | {
|
|
109
|
+
status: 'reject';
|
|
110
|
+
reason: 'invalid' | 'session-mismatch' | 'stale' | 'conflict' | 'sequence-gap';
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Receiver must authorize the assignment's node before calling this helper.
|
|
114
|
+
* Compare/persist the returned snapshot atomically with the old receipt. A new
|
|
115
|
+
* session continues the durable counter; it does not reset observation history.
|
|
116
|
+
* Across dispositions, the old receipt must reference the exact predecessor;
|
|
117
|
+
* receivers must process each revision's observations in order.
|
|
118
|
+
* These observations are never sufficient authority to relocate a storage writer.
|
|
119
|
+
*/
|
|
120
|
+
export declare const evaluateRuntimeAssignmentObservationV1: (incomingArg: IRuntimeAssignmentObservationV1, acceptedArg: IRuntimeAssignmentObservationV1 | null, assignmentArg: IRuntimeAssignmentV1, trustedReporterSessionIdArg: string) => Promise<TRuntimeObservationDecisionV1>;
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import { buildDigestPinnedImageReference, isSha256Digest } from './immutableimage.js';
|
|
2
|
+
import { canonicalizeStrictJson, createCanonicalJsonSha256Hex } from '../private/canonicaljson.js';
|
|
3
|
+
export const runtimeAssignmentV1Contract = Object.freeze({
|
|
4
|
+
assignmentDigestDomain: 'serve.zone/runtime-assignment-v1',
|
|
5
|
+
observationDigestDomain: 'serve.zone/runtime-assignment-observation-v1',
|
|
6
|
+
maximumStorageReferences: 64,
|
|
7
|
+
omission: 'no-effect',
|
|
8
|
+
removal: 'retain-assignment-tombstone-and-storage',
|
|
9
|
+
});
|
|
10
|
+
const fail = (messageArg) => { throw new Error(messageArg); };
|
|
11
|
+
const isIdentifier = (valueArg) => typeof valueArg === 'string' && /^[A-Za-z0-9][A-Za-z0-9:._-]{0,199}$/.test(valueArg);
|
|
12
|
+
const isPositiveInteger = (valueArg) => typeof valueArg === 'number' && Number.isSafeInteger(valueArg) && valueArg > 0;
|
|
13
|
+
const isDigest = (valueArg) => typeof valueArg === 'string' && isSha256Digest(valueArg);
|
|
14
|
+
/** Reject accessors before reading any fields; do not run input-owned code. */
|
|
15
|
+
const isExactRecord = (valueArg, keysArg) => {
|
|
16
|
+
if (!valueArg || typeof valueArg !== 'object' || Array.isArray(valueArg))
|
|
17
|
+
return false;
|
|
18
|
+
const prototype = Object.getPrototypeOf(valueArg);
|
|
19
|
+
if (prototype !== Object.prototype && prototype !== null)
|
|
20
|
+
return false;
|
|
21
|
+
const keys = Reflect.ownKeys(valueArg);
|
|
22
|
+
return keys.length === keysArg.length && keys.every((keyArg) => {
|
|
23
|
+
const descriptor = Object.getOwnPropertyDescriptor(valueArg, keyArg);
|
|
24
|
+
return typeof keyArg === 'string' && keysArg.includes(keyArg)
|
|
25
|
+
&& descriptor?.enumerable === true && Object.hasOwn(descriptor, 'value');
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
const isController = (valueArg) => isExactRecord(valueArg, ['kind', 'id', 'epoch'])
|
|
29
|
+
&& (valueArg.kind === 'cloudly' || valueArg.kind === 'onebox')
|
|
30
|
+
&& isIdentifier(valueArg.id) && isIdentifier(valueArg.epoch);
|
|
31
|
+
const isAuthorityReference = (valueArg) => isExactRecord(valueArg, ['id', 'generation', 'digest'])
|
|
32
|
+
&& isIdentifier(valueArg.id) && isPositiveInteger(valueArg.generation) && isDigest(valueArg.digest);
|
|
33
|
+
const isAssignmentReference = (valueArg) => isExactRecord(valueArg, ['assignmentId', 'generation', 'digest'])
|
|
34
|
+
&& isIdentifier(valueArg.assignmentId) && isPositiveInteger(valueArg.generation)
|
|
35
|
+
&& isDigest(valueArg.digest);
|
|
36
|
+
const assignmentKeys = [
|
|
37
|
+
'schemaVersion', 'controller', 'organizationId', 'nodeId', 'runtimeNamespace',
|
|
38
|
+
'assignmentId', 'serviceId', 'replicaId', 'attemptId', 'workerGroupId', 'siteId',
|
|
39
|
+
'generation', 'previous', 'disposition', 'offlinePolicy', 'workload', 'digest',
|
|
40
|
+
];
|
|
41
|
+
const assertAssignment = (valueArg) => {
|
|
42
|
+
if (!isExactRecord(valueArg, assignmentKeys)
|
|
43
|
+
|| valueArg.schemaVersion !== 1 || !isController(valueArg.controller)
|
|
44
|
+
|| !isPositiveInteger(valueArg.generation) || !isDigest(valueArg.digest)
|
|
45
|
+
|| valueArg.offlinePolicy !== 'continue-node-bound'
|
|
46
|
+
|| !['run', 'stop-preserve', 'remove-runtime-preserve-storage'].includes(valueArg.disposition))
|
|
47
|
+
fail('runtime assignment must use its exact v1 schema');
|
|
48
|
+
for (const key of ['organizationId', 'nodeId', 'runtimeNamespace', 'assignmentId',
|
|
49
|
+
'serviceId', 'replicaId', 'attemptId']) {
|
|
50
|
+
if (!isIdentifier(valueArg[key]))
|
|
51
|
+
fail(`runtime assignment ${key} must be a canonical identifier`);
|
|
52
|
+
}
|
|
53
|
+
for (const key of ['workerGroupId', 'siteId']) {
|
|
54
|
+
if (valueArg[key] !== null && !isIdentifier(valueArg[key]))
|
|
55
|
+
fail('invalid runtime topology ID');
|
|
56
|
+
}
|
|
57
|
+
if (valueArg.generation === 1 ? valueArg.previous !== null
|
|
58
|
+
: !isAssignmentReference(valueArg.previous)
|
|
59
|
+
|| valueArg.previous.assignmentId !== valueArg.assignmentId
|
|
60
|
+
|| valueArg.previous.generation !== valueArg.generation - 1) {
|
|
61
|
+
fail('runtime assignment must bind its exact preceding generation');
|
|
62
|
+
}
|
|
63
|
+
const workload = valueArg.workload;
|
|
64
|
+
if (!isExactRecord(workload, ['registryHost', 'repository', 'imageDigest', 'platform',
|
|
65
|
+
'config', 'network', 'secrets', 'storage'])
|
|
66
|
+
|| typeof workload.registryHost !== 'string' || workload.registryHost.length > 253
|
|
67
|
+
|| typeof workload.repository !== 'string' || workload.repository.length > 255
|
|
68
|
+
|| !isDigest(workload.imageDigest)
|
|
69
|
+
|| !['linux/amd64', 'linux/arm64'].includes(workload.platform)
|
|
70
|
+
|| !isAuthorityReference(workload.config)
|
|
71
|
+
|| (workload.network !== null && !isAuthorityReference(workload.network))
|
|
72
|
+
|| (workload.secrets !== null && !isAuthorityReference(workload.secrets))
|
|
73
|
+
|| !Array.isArray(workload.storage)
|
|
74
|
+
|| workload.storage.length > runtimeAssignmentV1Contract.maximumStorageReferences) {
|
|
75
|
+
fail('runtime assignment workload must use exact immutable references');
|
|
76
|
+
}
|
|
77
|
+
buildDigestPinnedImageReference(workload.registryHost, workload.repository, workload.imageDigest);
|
|
78
|
+
let previousId = '';
|
|
79
|
+
for (let index = 0; index < workload.storage.length; index++) {
|
|
80
|
+
const descriptor = Object.getOwnPropertyDescriptor(workload.storage, String(index));
|
|
81
|
+
if (!descriptor || !Object.hasOwn(descriptor, 'value')
|
|
82
|
+
|| !isAuthorityReference(descriptor.value) || descriptor.value.id <= previousId) {
|
|
83
|
+
fail('runtime assignment storage references must be dense, sorted and unique');
|
|
84
|
+
}
|
|
85
|
+
previousId = descriptor.value.id;
|
|
86
|
+
}
|
|
87
|
+
canonicalizeStrictJson(valueArg, fail);
|
|
88
|
+
return valueArg;
|
|
89
|
+
};
|
|
90
|
+
const digestPayload = async (domainArg, valueArg) => {
|
|
91
|
+
const { digest: _digest, ...payload } = valueArg;
|
|
92
|
+
return `sha256:${await createCanonicalJsonSha256Hex(canonicalizeStrictJson({ domain: domainArg, payload }, fail), fail)}`;
|
|
93
|
+
};
|
|
94
|
+
/** Digest helpers validate structure and exclude only the object's own digest. */
|
|
95
|
+
export const computeRuntimeAssignmentV1Digest = async (assignmentArg) => digestPayload(runtimeAssignmentV1Contract.assignmentDigestDomain, assertAssignment(assignmentArg));
|
|
96
|
+
export const validateRuntimeAssignmentV1 = async (valueArg) => {
|
|
97
|
+
try {
|
|
98
|
+
const assignment = snapshotAssignment(valueArg);
|
|
99
|
+
return assignment.digest === await computeRuntimeAssignmentV1Digest(assignment)
|
|
100
|
+
? [] : ['runtime assignment digest does not match'];
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
return ['runtime assignment must use its exact canonical v1 schema'];
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
const snapshotAssignment = (valueArg) => JSON.parse(canonicalizeStrictJson(assertAssignment(valueArg), fail));
|
|
107
|
+
export const getRuntimeAssignmentV1Reference = (assignmentArg) => ({
|
|
108
|
+
assignmentId: assignmentArg.assignmentId,
|
|
109
|
+
generation: assignmentArg.generation,
|
|
110
|
+
digest: assignmentArg.digest,
|
|
111
|
+
});
|
|
112
|
+
const canonical = (valueArg) => canonicalizeStrictJson(valueArg, fail);
|
|
113
|
+
const immutableAttempt = (assignmentArg) => {
|
|
114
|
+
const { generation, previous, disposition, digest, ...attempt } = assignmentArg;
|
|
115
|
+
return canonical(attempt);
|
|
116
|
+
};
|
|
117
|
+
/**
|
|
118
|
+
* Pure CAS decision, not authentication or execution. The caller must persist
|
|
119
|
+
* acceptance atomically before effects, serialize replica ownership, and retain
|
|
120
|
+
* removed assignments as tombstones. New attempts require separate stop/fencing
|
|
121
|
+
* admission for every older writer. An omitted assignment causes no transition.
|
|
122
|
+
* Persist only the returned detached snapshot, never the mutable input object.
|
|
123
|
+
*/
|
|
124
|
+
export const evaluateRuntimeAssignmentV1 = async (incomingArg, acceptedArg, trustedScopeArg) => {
|
|
125
|
+
try {
|
|
126
|
+
incomingArg = snapshotAssignment(incomingArg);
|
|
127
|
+
acceptedArg = acceptedArg === null ? null : snapshotAssignment(acceptedArg);
|
|
128
|
+
if (!isExactRecord(trustedScopeArg, ['controller', 'organizationId', 'nodeId', 'runtimeNamespace'])
|
|
129
|
+
|| !isController(trustedScopeArg.controller)
|
|
130
|
+
|| !isIdentifier(trustedScopeArg.organizationId) || !isIdentifier(trustedScopeArg.nodeId)
|
|
131
|
+
|| !isIdentifier(trustedScopeArg.runtimeNamespace))
|
|
132
|
+
return { status: 'reject', reason: 'invalid' };
|
|
133
|
+
trustedScopeArg = JSON.parse(canonical(trustedScopeArg));
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
return { status: 'reject', reason: 'invalid' };
|
|
137
|
+
}
|
|
138
|
+
if ((await validateRuntimeAssignmentV1(incomingArg)).length
|
|
139
|
+
|| (acceptedArg !== null && (await validateRuntimeAssignmentV1(acceptedArg)).length)) {
|
|
140
|
+
return { status: 'reject', reason: 'invalid' };
|
|
141
|
+
}
|
|
142
|
+
const matchesScope = (assignmentArg) => assignmentArg.controller.kind === trustedScopeArg.controller.kind
|
|
143
|
+
&& assignmentArg.controller.id === trustedScopeArg.controller.id
|
|
144
|
+
&& assignmentArg.controller.epoch === trustedScopeArg.controller.epoch
|
|
145
|
+
&& assignmentArg.organizationId === trustedScopeArg.organizationId
|
|
146
|
+
&& assignmentArg.nodeId === trustedScopeArg.nodeId
|
|
147
|
+
&& assignmentArg.runtimeNamespace === trustedScopeArg.runtimeNamespace;
|
|
148
|
+
if (!matchesScope(incomingArg) || (acceptedArg !== null && !matchesScope(acceptedArg))) {
|
|
149
|
+
return { status: 'reject', reason: 'scope-mismatch' };
|
|
150
|
+
}
|
|
151
|
+
if (acceptedArg === null) {
|
|
152
|
+
return incomingArg.generation === 1
|
|
153
|
+
&& incomingArg.disposition === 'run'
|
|
154
|
+
? { status: 'accept', assignment: incomingArg }
|
|
155
|
+
: { status: 'reject', reason: 'predecessor-mismatch' };
|
|
156
|
+
}
|
|
157
|
+
if (incomingArg.assignmentId !== acceptedArg.assignmentId) {
|
|
158
|
+
return { status: 'reject', reason: 'attempt-mismatch' };
|
|
159
|
+
}
|
|
160
|
+
if (incomingArg.generation < acceptedArg.generation)
|
|
161
|
+
return { status: 'reject', reason: 'stale' };
|
|
162
|
+
if (incomingArg.generation === acceptedArg.generation) {
|
|
163
|
+
return incomingArg.digest === acceptedArg.digest
|
|
164
|
+
? { status: 'replay', assignment: acceptedArg } : { status: 'reject', reason: 'conflict' };
|
|
165
|
+
}
|
|
166
|
+
if (canonical(incomingArg.previous) !== canonical(getRuntimeAssignmentV1Reference(acceptedArg))) {
|
|
167
|
+
return { status: 'reject', reason: 'predecessor-mismatch' };
|
|
168
|
+
}
|
|
169
|
+
if (immutableAttempt(incomingArg) !== immutableAttempt(acceptedArg)) {
|
|
170
|
+
return { status: 'reject', reason: 'attempt-mismatch' };
|
|
171
|
+
}
|
|
172
|
+
const order = {
|
|
173
|
+
run: 0, 'stop-preserve': 1, 'remove-runtime-preserve-storage': 2,
|
|
174
|
+
};
|
|
175
|
+
if (order[incomingArg.disposition] !== order[acceptedArg.disposition] + 1) {
|
|
176
|
+
return { status: 'reject', reason: 'disposition-regression' };
|
|
177
|
+
}
|
|
178
|
+
return { status: 'accept', assignment: incomingArg };
|
|
179
|
+
};
|
|
180
|
+
const assertObservation = (valueArg) => {
|
|
181
|
+
if (!isExactRecord(valueArg, ['schemaVersion', 'assignment', 'reporterSessionId',
|
|
182
|
+
'sequence', 'observedAt', 'phase', 'ready', 'runtime', 'digest'])
|
|
183
|
+
|| valueArg.schemaVersion !== 1 || !isAssignmentReference(valueArg.assignment)
|
|
184
|
+
|| !isIdentifier(valueArg.reporterSessionId) || !isPositiveInteger(valueArg.sequence)
|
|
185
|
+
|| !isPositiveInteger(valueArg.observedAt) || !isDigest(valueArg.digest)
|
|
186
|
+
|| typeof valueArg.ready !== 'boolean'
|
|
187
|
+
|| !['pending', 'running', 'stopped', 'removed', 'failed', 'unknown'].includes(valueArg.phase)) {
|
|
188
|
+
fail('runtime observation must use its exact v1 schema');
|
|
189
|
+
}
|
|
190
|
+
if (valueArg.runtime !== null && (!isExactRecord(valueArg.runtime, [
|
|
191
|
+
'sandboxId', 'containerId', 'imageDigest',
|
|
192
|
+
]) || !isIdentifier(valueArg.runtime.sandboxId) || !isIdentifier(valueArg.runtime.containerId)
|
|
193
|
+
|| !isDigest(valueArg.runtime.imageDigest)))
|
|
194
|
+
fail('runtime identity must be canonical');
|
|
195
|
+
if ((valueArg.ready && valueArg.phase !== 'running')
|
|
196
|
+
|| (valueArg.phase === 'running' && valueArg.runtime === null)
|
|
197
|
+
|| (valueArg.phase === 'removed' && valueArg.runtime !== null)) {
|
|
198
|
+
fail('runtime observation readiness and identity contradict its phase');
|
|
199
|
+
}
|
|
200
|
+
canonical(valueArg);
|
|
201
|
+
return valueArg;
|
|
202
|
+
};
|
|
203
|
+
export const computeRuntimeAssignmentObservationV1Digest = async (observationArg) => digestPayload(runtimeAssignmentV1Contract.observationDigestDomain, assertObservation(observationArg));
|
|
204
|
+
/** Checks exact assignment evidence; transport must separately bind reporter/session. */
|
|
205
|
+
export const validateRuntimeAssignmentObservationV1 = async (observationArg, assignmentArg) => {
|
|
206
|
+
try {
|
|
207
|
+
const observation = JSON.parse(canonical(assertObservation(observationArg)));
|
|
208
|
+
assignmentArg = snapshotAssignment(assignmentArg);
|
|
209
|
+
if ((await validateRuntimeAssignmentV1(assignmentArg)).length)
|
|
210
|
+
return ['invalid assignment'];
|
|
211
|
+
if (canonical(observation.assignment) !== canonical(getRuntimeAssignmentV1Reference(assignmentArg))) {
|
|
212
|
+
return ['runtime observation does not match the exact assignment'];
|
|
213
|
+
}
|
|
214
|
+
if (observation.digest !== await computeRuntimeAssignmentObservationV1Digest(observation)) {
|
|
215
|
+
return ['runtime observation digest does not match'];
|
|
216
|
+
}
|
|
217
|
+
if (observation.ready && (assignmentArg.disposition !== 'run'
|
|
218
|
+
|| observation.runtime?.imageDigest !== assignmentArg.workload.imageDigest)) {
|
|
219
|
+
return ['runtime readiness does not match authorized execution'];
|
|
220
|
+
}
|
|
221
|
+
return [];
|
|
222
|
+
}
|
|
223
|
+
catch {
|
|
224
|
+
return ['runtime observation must use its exact canonical v1 schema'];
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
/**
|
|
228
|
+
* Receiver must authorize the assignment's node before calling this helper.
|
|
229
|
+
* Compare/persist the returned snapshot atomically with the old receipt. A new
|
|
230
|
+
* session continues the durable counter; it does not reset observation history.
|
|
231
|
+
* Across dispositions, the old receipt must reference the exact predecessor;
|
|
232
|
+
* receivers must process each revision's observations in order.
|
|
233
|
+
* These observations are never sufficient authority to relocate a storage writer.
|
|
234
|
+
*/
|
|
235
|
+
export const evaluateRuntimeAssignmentObservationV1 = async (incomingArg, acceptedArg, assignmentArg, trustedReporterSessionIdArg) => {
|
|
236
|
+
try {
|
|
237
|
+
incomingArg = JSON.parse(canonical(assertObservation(incomingArg)));
|
|
238
|
+
acceptedArg = acceptedArg === null ? null
|
|
239
|
+
: JSON.parse(canonical(assertObservation(acceptedArg)));
|
|
240
|
+
assignmentArg = snapshotAssignment(assignmentArg);
|
|
241
|
+
if (!isIdentifier(trustedReporterSessionIdArg)
|
|
242
|
+
|| (await validateRuntimeAssignmentObservationV1(incomingArg, assignmentArg)).length
|
|
243
|
+
|| (acceptedArg !== null && (acceptedArg.digest !== await computeRuntimeAssignmentObservationV1Digest(acceptedArg)
|
|
244
|
+
|| acceptedArg.assignment.assignmentId !== assignmentArg.assignmentId
|
|
245
|
+
|| (canonical(acceptedArg.assignment) !== canonical(getRuntimeAssignmentV1Reference(assignmentArg))
|
|
246
|
+
&& canonical(acceptedArg.assignment) !== canonical(assignmentArg.previous)))))
|
|
247
|
+
return { status: 'reject', reason: 'invalid' };
|
|
248
|
+
if (incomingArg.reporterSessionId !== trustedReporterSessionIdArg) {
|
|
249
|
+
return { status: 'reject', reason: 'session-mismatch' };
|
|
250
|
+
}
|
|
251
|
+
if (acceptedArg !== null && incomingArg.sequence <= acceptedArg.sequence) {
|
|
252
|
+
if (incomingArg.sequence < acceptedArg.sequence)
|
|
253
|
+
return { status: 'reject', reason: 'stale' };
|
|
254
|
+
return incomingArg.digest === acceptedArg.digest
|
|
255
|
+
? { status: 'replay', observation: acceptedArg }
|
|
256
|
+
: { status: 'reject', reason: 'conflict' };
|
|
257
|
+
}
|
|
258
|
+
if (incomingArg.sequence !== (acceptedArg?.sequence ?? 0) + 1) {
|
|
259
|
+
return { status: 'reject', reason: 'sequence-gap' };
|
|
260
|
+
}
|
|
261
|
+
return { status: 'accept', observation: incomingArg };
|
|
262
|
+
}
|
|
263
|
+
catch {
|
|
264
|
+
return { status: 'reject', reason: 'invalid' };
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVudGltZWFzc2lnbm1lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9kYXRhL3J1bnRpbWVhc3NpZ25tZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSwrQkFBK0IsRUFBRSxjQUFjLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN0RixPQUFPLEVBQUUsc0JBQXNCLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQTJGbkcsTUFBTSxDQUFDLE1BQU0sMkJBQTJCLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUN2RCxzQkFBc0IsRUFBRSxrQ0FBa0M7SUFDMUQsdUJBQXVCLEVBQUUsOENBQThDO0lBQ3ZFLHdCQUF3QixFQUFFLEVBQUU7SUFDNUIsUUFBUSxFQUFFLFdBQVc7SUFDckIsT0FBTyxFQUFFLHlDQUF5QztDQUMxQyxDQUFDLENBQUM7QUFFWixNQUFNLElBQUksR0FBa0MsQ0FBQyxVQUFVLEVBQUUsRUFBRSxHQUFHLE1BQU0sSUFBSSxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDN0YsTUFBTSxZQUFZLEdBQUcsQ0FBQyxRQUFpQixFQUFzQixFQUFFLENBQzdELE9BQU8sUUFBUSxLQUFLLFFBQVEsSUFBSSxxQ0FBcUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDdkYsTUFBTSxpQkFBaUIsR0FBRyxDQUFDLFFBQWlCLEVBQXNCLEVBQUUsQ0FDbEUsT0FBTyxRQUFRLEtBQUssUUFBUSxJQUFJLE1BQU0sQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLElBQUksUUFBUSxHQUFHLENBQUMsQ0FBQztBQUNqRixNQUFNLFFBQVEsR0FBRyxDQUFDLFFBQWlCLEVBQTZCLEVBQUUsQ0FDaEUsT0FBTyxRQUFRLEtBQUssUUFBUSxJQUFJLGNBQWMsQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUUzRCwrRUFBK0U7QUFDL0UsTUFBTSxhQUFhLEdBQUcs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
|