@serve.zone/interfaces 32.49.0 → 32.51.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.
@@ -0,0 +1,188 @@
1
+ import type { TSha256Digest } from './immutableimage.js';
2
+ import type { IRuntimeAuthorityReference } from './runtimeassignment.js';
3
+ import type { IRuntimeNetworkNodeScope } from './networkprojection.js';
4
+ import { computeRuntimeNetworkProjectionDigest, snapshotRuntimeNetworkNodeScope,
5
+ snapshotRuntimeNetworkProjection } from './networkprojection.js';
6
+ import type { IRuntimeSessionBinding } from './runtimesession.js';
7
+ import { snapshotRuntimeSessionBinding } from './runtimesession.js';
8
+ import { captureNetwork, failNetwork, networkDigest, networkEqual, networkHash, networkId, networkRecord,
9
+ networkReference, networkReferenceOf, networkRevision, networkSafe, requireNetwork } from '../private/networkcontract.js';
10
+
11
+ /**
12
+ * A node's durable statement that its packet authority is bounded by one admitted projection.
13
+ *
14
+ * Every packet table the node holds was composed from `projection`, or the node holds none: the
15
+ * flows its kernel admits are a subset of that projection's grants. Only the node's joined native
16
+ * packet owner can supply it — the journaled application of the projection's policies on every
17
+ * role, or the release of every table — never an admission ACK, a single table inspection or a
18
+ * caller-selected flag. A crash, a reboot or a restored guard only removes authority, so a receipt
19
+ * never becomes false; applying a successor projection supersedes it.
20
+ *
21
+ * `nativeJournal` names the node-private joined packet journal that applied the projection, or is
22
+ * null when the node holds no packet table at all. The receipts of one node form one monotonic
23
+ * chain; a receipt never names an older projection than its predecessor. These portable values
24
+ * neither inspect a kernel nor authenticate their producer: the receiver binds the report to the
25
+ * current authenticated session or its own reporter history.
26
+ */
27
+ export interface IRuntimeNetworkProjectionApplicationReceipt extends IRuntimeNetworkNodeScope {
28
+ id: string;
29
+ generation: number;
30
+ previous: IRuntimeAuthorityReference | null;
31
+ projection: IRuntimeAuthorityReference;
32
+ reporterSessionId: string;
33
+ bootId: string;
34
+ nativeJournal: IRuntimeAuthorityReference | null;
35
+ digest: TSha256Digest;
36
+ }
37
+
38
+ export interface IReportRuntimeNetworkProjectionApplicationRequest {
39
+ session: IRuntimeSessionBinding;
40
+ receipt: IRuntimeNetworkProjectionApplicationReceipt;
41
+ }
42
+ export interface IReportRuntimeNetworkProjectionApplicationResponse {
43
+ status: 'accepted' | 'replay';
44
+ receipt: IRuntimeAuthorityReference;
45
+ authorityUse: 'current' | 'historical';
46
+ }
47
+
48
+ export const runtimeNetworkProjectionApplicationContract = Object.freeze({
49
+ digestDomain: 'serve.zone/runtime-network-projection-application-receipt',
50
+ claim: 'packet-authority-within-the-grants-of-the-named-projection',
51
+ receiptSource: 'joined-native-packet-journal-or-no-packet-table',
52
+ appliedPrevious: 'only-a-receipt-naming-the-exact-previous-projection',
53
+ olderProjection: 'advances-the-chain-never-applied-previous',
54
+ acknowledgement: 'an-admission-ack-is-never-an-application-receipt',
55
+ authentication: 'current-authenticated-session-or-receiver-reporter-history',
56
+ } as const);
57
+
58
+ const bootIdPattern = /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/;
59
+ const scopeOf = (value: IRuntimeNetworkNodeScope): IRuntimeNetworkNodeScope =>
60
+ ({ controller: value.controller, nodeId: value.nodeId, runtimeNamespace: value.runtimeNamespace });
61
+ const bootId = (value: unknown): string => {
62
+ requireNetwork(typeof value === 'string' && bootIdPattern.test(value) && value !== '00000000-0000-0000-0000-000000000000');
63
+ return value;
64
+ };
65
+
66
+ /** Exact-key structural snapshot; digest and chain rules are `admitRuntimeNetworkProjectionApplicationReceipt`'s. */
67
+ export const snapshotRuntimeNetworkProjectionApplicationReceipt = (
68
+ value: unknown,
69
+ ): IRuntimeNetworkProjectionApplicationReceipt => networkSafe(() => {
70
+ const item = networkRecord(captureNetwork(value), ['id', 'generation', 'previous', 'controller', 'nodeId',
71
+ 'runtimeNamespace', 'projection', 'reporterSessionId', 'bootId', 'nativeJournal', 'digest']);
72
+ const scope = snapshotRuntimeNetworkNodeScope({ controller: item.controller, nodeId: item.nodeId,
73
+ runtimeNamespace: item.runtimeNamespace });
74
+ return { ...networkRevision(item), ...scope, projection: networkReference(item.projection),
75
+ reporterSessionId: networkId(item.reporterSessionId), bootId: bootId(item.bootId),
76
+ nativeJournal: item.nativeJournal === null ? null : networkReference(item.nativeJournal),
77
+ digest: networkDigest(item.digest) };
78
+ });
79
+
80
+ export const computeRuntimeNetworkProjectionApplicationReceiptDigest = (
81
+ value: IRuntimeNetworkProjectionApplicationReceipt,
82
+ ): Promise<TSha256Digest> => networkHash(runtimeNetworkProjectionApplicationContract.digestDomain,
83
+ snapshotRuntimeNetworkProjectionApplicationReceipt(value));
84
+
85
+ /**
86
+ * Pure chain binding of one reported receipt. `previousReceiptValue` is the receiver's current
87
+ * receipt for the node, or null while it holds none; `headValue` is the receiver's current
88
+ * projection for the node. The owner must authenticate the reporter and fence its writes.
89
+ *
90
+ * The receipt names the head's projection chain at a generation the head has reached: the head
91
+ * itself, exactly, or an older generation. An older one is a receipt minted before the node
92
+ * admitted the head; it advances the chain and is never usable as `appliedPrevious`.
93
+ */
94
+ export const admitRuntimeNetworkProjectionApplicationReceipt = async (
95
+ value: unknown, previousReceiptValue: unknown | null, trustedScopeValue: unknown, headValue: unknown,
96
+ ): Promise<{ status: 'accepted' | 'replay'; receipt: IRuntimeNetworkProjectionApplicationReceipt }> => {
97
+ try {
98
+ const receipt = snapshotRuntimeNetworkProjectionApplicationReceipt(value);
99
+ const previous = previousReceiptValue === null ? null : snapshotRuntimeNetworkProjectionApplicationReceipt(previousReceiptValue);
100
+ const scope = snapshotRuntimeNetworkNodeScope(captureNetwork(trustedScopeValue));
101
+ const head = snapshotRuntimeNetworkProjection(headValue);
102
+ requireNetwork(networkEqual(scopeOf(receipt), scope) && networkEqual(scopeOf(head), scope));
103
+ requireNetwork(receipt.digest === await computeRuntimeNetworkProjectionApplicationReceiptDigest(receipt)
104
+ && head.digest === await computeRuntimeNetworkProjectionDigest(head));
105
+ requireNetwork(receipt.projection.id === head.id && receipt.projection.generation <= head.generation);
106
+ if (receipt.projection.generation === head.generation) requireNetwork(networkEqual(receipt.projection, networkReferenceOf(head)));
107
+ if (previous === null) requireNetwork(receipt.generation === 1 && receipt.previous === null);
108
+ else {
109
+ requireNetwork(networkEqual(scopeOf(previous), scope)
110
+ && previous.digest === await computeRuntimeNetworkProjectionApplicationReceiptDigest(previous));
111
+ if (networkEqual(receipt, previous)) return { status: 'replay', receipt };
112
+ requireNetwork(receipt.id === previous.id && receipt.generation === previous.generation + 1
113
+ && networkEqual(receipt.previous, networkReferenceOf(previous))
114
+ && receipt.projection.id === previous.projection.id
115
+ && receipt.projection.generation >= previous.projection.generation);
116
+ if (receipt.projection.generation === previous.projection.generation) {
117
+ requireNetwork(networkEqual(receipt.projection, previous.projection));
118
+ }
119
+ }
120
+ return { status: 'accepted', receipt };
121
+ } catch { return failNetwork(); }
122
+ };
123
+
124
+ /**
125
+ * The `appliedPrevious` argument of `admitRuntimeNetworkProjection` for the successor of
126
+ * `previousProjectionValue`: the receipt's projection when it is exactly that projection, else
127
+ * null. `receiptValue` must be the receiver's own admitted receipt for the node (a node passes its
128
+ * own durable receipt, a controller the latest receipt it admitted), never an ACK field.
129
+ */
130
+ export const selectRuntimeNetworkProjectionAppliedPrevious = async (
131
+ receiptValue: unknown | null, previousProjectionValue: unknown,
132
+ ): Promise<IRuntimeAuthorityReference | null> => {
133
+ try {
134
+ // Snapshot both caller-owned inputs before the first asynchronous operation.
135
+ const previous = snapshotRuntimeNetworkProjection(previousProjectionValue);
136
+ const receipt = receiptValue === null ? null : snapshotRuntimeNetworkProjectionApplicationReceipt(receiptValue);
137
+ requireNetwork(previous.digest === await computeRuntimeNetworkProjectionDigest(previous));
138
+ if (receipt === null) return null;
139
+ requireNetwork(networkEqual(scopeOf(receipt), scopeOf(previous))
140
+ && receipt.digest === await computeRuntimeNetworkProjectionApplicationReceiptDigest(receipt));
141
+ return networkEqual(receipt.projection, networkReferenceOf(previous)) ? networkReferenceOf(receipt.projection) : null;
142
+ } catch { return failNetwork(); }
143
+ };
144
+
145
+ export const snapshotReportRuntimeNetworkProjectionApplicationRequest = (
146
+ value: unknown,
147
+ ): IReportRuntimeNetworkProjectionApplicationRequest => networkSafe(() => {
148
+ const item = networkRecord(captureNetwork(value), ['session', 'receipt']);
149
+ return { session: snapshotRuntimeSessionBinding(item.session),
150
+ receipt: snapshotRuntimeNetworkProjectionApplicationReceipt(item.receipt) };
151
+ });
152
+
153
+ /**
154
+ * Both trusted bindings come from the receiver's fenced physical-session/history owner: the
155
+ * current session, and the session history entry that names the receipt's reporter. A receipt
156
+ * minted under an earlier session of the same node still drains from its outbox as `historical`.
157
+ */
158
+ export const bindReportRuntimeNetworkProjectionApplicationRequest = (
159
+ value: unknown, trustedCurrentSessionValue: unknown, trustedReporterSessionValue: unknown,
160
+ ): { request: IReportRuntimeNetworkProjectionApplicationRequest; authorityUse: 'current' | 'historical' } => networkSafe(() => {
161
+ const request = snapshotReportRuntimeNetworkProjectionApplicationRequest(value);
162
+ const current = snapshotRuntimeSessionBinding(captureNetwork(trustedCurrentSessionValue));
163
+ const reporter = snapshotRuntimeSessionBinding(captureNetwork(trustedReporterSessionValue));
164
+ requireNetwork(networkEqual(request.session, current) && networkEqual(scopeOf(request.receipt), scopeOf(current))
165
+ && networkEqual(scopeOf(reporter), scopeOf(current)) && reporter.reporterSessionId === request.receipt.reporterSessionId);
166
+ const authorityUse = reporter.reporterSessionId === current.reporterSessionId ? 'current' : 'historical';
167
+ requireNetwork(authorityUse === 'current' ? networkEqual(reporter, current)
168
+ : reporter.sessionEpoch < current.sessionEpoch && reporter.credentialGeneration <= current.credentialGeneration);
169
+ return { request, authorityUse };
170
+ });
171
+
172
+ export const snapshotReportRuntimeNetworkProjectionApplicationResponse = (
173
+ value: unknown,
174
+ ): IReportRuntimeNetworkProjectionApplicationResponse => networkSafe(() => {
175
+ const item = networkRecord(captureNetwork(value), ['status', 'receipt', 'authorityUse']);
176
+ requireNetwork((item.status === 'accepted' || item.status === 'replay')
177
+ && (item.authorityUse === 'current' || item.authorityUse === 'historical'));
178
+ return { status: item.status, receipt: networkReference(item.receipt), authorityUse: item.authorityUse };
179
+ });
180
+
181
+ /** Compare the response with the exact SENT receipt, never with a response-derived value. */
182
+ export const bindReportRuntimeNetworkProjectionApplicationResponse = (
183
+ value: unknown, sentReceiptValue: unknown,
184
+ ): IReportRuntimeNetworkProjectionApplicationResponse => networkSafe(() => {
185
+ const response = snapshotReportRuntimeNetworkProjectionApplicationResponse(value);
186
+ requireNetwork(networkEqual(response.receipt, networkReference(captureNetwork(sentReceiptValue))));
187
+ return response;
188
+ });
@@ -788,9 +788,11 @@ export const bindRuntimeNetworkWorkloadLeaseToAssignment = async (leaseValue: un
788
788
  };
789
789
 
790
790
  /**
791
- * Pure revision decision. appliedPrevious must be the receiver's exact durable,
792
- * joined application receipt, never an incoming ACK field. All prior accepted
793
- * material/apply journals survive until effects and DNS/allocation quarantine end.
791
+ * Pure revision decision. appliedPrevious must come from the receiver's exact durable,
792
+ * joined application receipt (`IRuntimeNetworkProjectionApplicationReceipt`, selected by
793
+ * `selectRuntimeNetworkProjectionAppliedPrevious`), never from an incoming ACK field. Only a
794
+ * receipt naming exactly `previousValue` releases its carried withdrawals and tombstones. All
795
+ * prior accepted material/apply journals survive until effects and DNS/allocation quarantine end.
794
796
  */
795
797
  export const admitRuntimeNetworkProjection = async (
796
798
  value: unknown, previousValue: unknown | null, trustedScopeValue: unknown, appliedPreviousValue: unknown | null,
@@ -4,6 +4,7 @@ import type * as binding from '../data/noderuntimebinding.js';
4
4
  import type * as terminal from '../data/runtimeterminalreceipt.js';
5
5
  import type * as network from '../data/networkdelivery.js';
6
6
  import type * as protection from '../data/networkprotection.js';
7
+ import type * as application from '../data/networkapplication.js';
7
8
  import type * as credential from '../data/networkcredential.js';
8
9
  import type * as assignmentSecret from '../runtime.assignmentsecret.js';
9
10
  import type * as fleet from '../data/fleetcutover.js';
@@ -32,6 +33,19 @@ export interface IReq_Pallet_Controller_ReportRuntimeNetworkProtection extends p
32
33
  response: protection.IReportRuntimeNetworkProtectionResponse;
33
34
  }
34
35
 
36
+ /**
37
+ * Current authenticated peer reports its durable joined application receipt: the projection that
38
+ * bounds its packet authority. The controller passes it as `appliedPrevious` only while it names
39
+ * the exact head; an admission ACK never stands in for it.
40
+ */
41
+ export interface IReq_Pallet_Controller_ReportRuntimeNetworkProjectionApplication extends plugins.typedrequestInterfaces.implementsTR<
42
+ plugins.typedrequestInterfaces.ITypedRequest, IReq_Pallet_Controller_ReportRuntimeNetworkProjectionApplication
43
+ > {
44
+ method: 'reportRuntimeNetworkProjectionApplication';
45
+ request: application.IReportRuntimeNetworkProjectionApplicationRequest;
46
+ response: application.IReportRuntimeNetworkProjectionApplicationResponse;
47
+ }
48
+
35
49
  /**
36
50
  * Current authenticated Pallet session only. Cloudly reads the current pallet runtime and exact
37
51
  * owner records, then grants one held prepared handoff; serialized session content is no proof.
@@ -17,7 +17,10 @@ import type {
17
17
  IServiceDeploymentStatus,
18
18
  } from '../data/deploymentoperation.js';
19
19
  import type { TSha256Digest } from '../data/immutableimage.js';
20
- import type { ILegacyServiceRuntimeAttestation } from '../data/deploymentlegacyimport.js';
20
+ import type {
21
+ ILegacyServiceHostObservation,
22
+ ILegacyServiceRuntimeAttestation,
23
+ } from '../data/deploymentlegacyimport.js';
21
24
  import type { IProtocolOffer } from '../protocol.js';
22
25
  import type {
23
26
  IRuntimeAssignmentLogAttemptPage,
@@ -330,10 +333,13 @@ extends plugins.typedrequestInterfaces.implementsTR<
330
333
  }
331
334
 
332
335
  /**
333
- * Captures durable evidence that a legacy `deployOnPush` service runs exactly the registry root its
334
- * tag names: every required replica observed healthy on that one digest, with the root's platform
335
- * manifests read from Cloudly's own registry. Administrators only, and only while the legacy
336
- * runtime still runs — incomplete evidence is refused, never stored.
336
+ * Captures durable evidence that a legacy `deployOnPush` service runs exactly one registry root of
337
+ * its own repository, from an administrator's observation of its Swarm service and containers on
338
+ * the hosts that run them (`hostObservation`). Cloudly judges the observation itself
339
+ * (`data.judgeLegacyServiceHostObservation`): every desired replica running, healthy or without a
340
+ * healthcheck, on one root that is whole in Cloudly's own registry, its platform manifests read
341
+ * from there. The source tag need not still name that root. Administrators only, and only while
342
+ * the legacy runtime still runs — incomplete evidence is refused, never stored.
337
343
  *
338
344
  * `expectedRuntimeDigest`, when stated, is an assertion the observed digest must equal. Capturing
339
345
  * again for an unchanged digest returns the attestation already stored.
@@ -348,6 +354,7 @@ extends plugins.typedrequestInterfaces.implementsTR<
348
354
  identity: IIdentityCredential;
349
355
  legacyServiceId: string;
350
356
  expectedRuntimeDigest?: TSha256Digest;
357
+ hostObservation: ILegacyServiceHostObservation;
351
358
  };
352
359
  response: {
353
360
  attestation: ILegacyServiceRuntimeAttestation;