@serve.zone/interfaces 31.8.0 → 32.0.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.
Files changed (215) hide show
  1. package/.smartconfig.json +1 -0
  2. package/changelog.md +512 -0
  3. package/dist_ts/00_commitinfo_data.js +3 -3
  4. package/dist_ts/appstore/types.d.ts +4 -6
  5. package/dist_ts/appstore/types.js +5 -5
  6. package/dist_ts/data/backup.d.ts +3 -26
  7. package/dist_ts/data/cluster.d.ts +36 -11
  8. package/dist_ts/data/cluster.js +33 -22
  9. package/dist_ts/data/clusteringress.d.ts +8 -0
  10. package/dist_ts/data/clusteringress.js +13 -8
  11. package/dist_ts/data/clusternode.d.ts +121 -74
  12. package/dist_ts/data/clusternode.js +109 -132
  13. package/dist_ts/data/clusterruntime.d.ts +39 -0
  14. package/dist_ts/data/clusterruntime.js +11 -0
  15. package/dist_ts/data/coremail.d.ts +3 -7
  16. package/dist_ts/data/coremail.js +2 -2
  17. package/dist_ts/data/coremail.runtime.d.ts +0 -1
  18. package/dist_ts/data/coremail.runtime.js +5 -22
  19. package/dist_ts/data/deploymentadoption.d.ts +0 -2
  20. package/dist_ts/data/deploymentadoption.js +40 -6
  21. package/dist_ts/data/deploymentoperation.js +16 -3
  22. package/dist_ts/data/deploymentpreflight.d.ts +0 -2
  23. package/dist_ts/data/deploymentpreflight.js +1 -1
  24. package/dist_ts/data/immutableimage.d.ts +38 -21
  25. package/dist_ts/data/immutableimage.js +45 -5
  26. package/dist_ts/data/index.d.ts +5 -1
  27. package/dist_ts/data/index.js +5 -1
  28. package/dist_ts/data/isolatedrestore.d.ts +139 -21
  29. package/dist_ts/data/isolatedrestore.golden.d.ts +0 -1
  30. package/dist_ts/data/isolatedrestore.golden.js +6 -9
  31. package/dist_ts/data/isolatedrestore.js +176 -40
  32. package/dist_ts/data/mail.d.ts +1 -1
  33. package/dist_ts/data/networkaddressplan.d.ts +78 -0
  34. package/dist_ts/data/networkaddressplan.js +114 -0
  35. package/dist_ts/data/networkauthority.d.ts +20 -22
  36. package/dist_ts/data/networkauthority.js +29 -43
  37. package/dist_ts/data/networkcredential.d.ts +10 -10
  38. package/dist_ts/data/networkcredential.js +16 -16
  39. package/dist_ts/data/networkdelivery.d.ts +18 -18
  40. package/dist_ts/data/networkdelivery.js +16 -16
  41. package/dist_ts/data/networklease.d.ts +18 -7
  42. package/dist_ts/data/networklease.js +29 -7
  43. package/dist_ts/data/networknode.d.ts +37 -0
  44. package/dist_ts/data/networknode.js +6 -0
  45. package/dist_ts/data/networkprojection.d.ts +59 -60
  46. package/dist_ts/data/networkprojection.js +53 -57
  47. package/dist_ts/data/networkprotection.d.ts +27 -28
  48. package/dist_ts/data/networkprotection.js +36 -36
  49. package/dist_ts/data/networkrouter.d.ts +11 -11
  50. package/dist_ts/data/networkrouter.js +1 -1
  51. package/dist_ts/data/networksigning.d.ts +16 -18
  52. package/dist_ts/data/networksigning.js +20 -21
  53. package/dist_ts/data/nodecredential.d.ts +4 -6
  54. package/dist_ts/data/nodeenrollment.d.ts +35 -40
  55. package/dist_ts/data/nodeenrollment.js +57 -72
  56. package/dist_ts/data/privatenetwork.d.ts +21 -24
  57. package/dist_ts/data/privatenetwork.js +39 -54
  58. package/dist_ts/data/runtimeassignment.d.ts +50 -34
  59. package/dist_ts/data/runtimeassignment.js +79 -45
  60. package/dist_ts/data/runtimeconfig.d.ts +21 -22
  61. package/dist_ts/data/runtimeconfig.js +37 -100
  62. package/dist_ts/data/runtimesession.d.ts +100 -62
  63. package/dist_ts/data/runtimesession.js +98 -79
  64. package/dist_ts/data/runtimeterminalreceipt.d.ts +28 -29
  65. package/dist_ts/data/runtimeterminalreceipt.js +42 -42
  66. package/dist_ts/data/secret.d.ts +18 -25
  67. package/dist_ts/data/secret.js +12 -52
  68. package/dist_ts/data/servicecredential.d.ts +14 -16
  69. package/dist_ts/data/servicecredential.js +17 -28
  70. package/dist_ts/data/serviceruntime.d.ts +128 -0
  71. package/dist_ts/data/serviceruntime.js +92 -0
  72. package/dist_ts/data/sparknodereport.d.ts +27 -14
  73. package/dist_ts/data/sparknodereport.js +35 -28
  74. package/dist_ts/data/webpush.d.ts +0 -1
  75. package/dist_ts/index.d.ts +2 -1
  76. package/dist_ts/index.js +3 -2
  77. package/dist_ts/platform/objectstorageretention.d.ts +21 -24
  78. package/dist_ts/platform/objectstorageretention.js +6 -18
  79. package/dist_ts/platform/storage.d.ts +1 -3
  80. package/dist_ts/platform/storagemigration.d.ts +0 -7
  81. package/dist_ts/platform/storagemigration.golden.d.ts +0 -1
  82. package/dist_ts/platform/storagemigration.golden.js +8 -12
  83. package/dist_ts/platform/storagemigration.js +6 -51
  84. package/dist_ts/platform/types.d.ts +2 -2
  85. package/dist_ts/private/canonicaljson.d.ts +9 -1
  86. package/dist_ts/private/canonicaljson.js +14 -2
  87. package/dist_ts/private/dataproperties.d.ts +62 -0
  88. package/dist_ts/private/dataproperties.js +117 -0
  89. package/dist_ts/private/networkcontract.d.ts +14 -10
  90. package/dist_ts/private/networkcontract.js +15 -1
  91. package/dist_ts/private/producercontract.d.ts +11 -0
  92. package/dist_ts/private/producercontract.js +21 -0
  93. package/dist_ts/private/releaseversion.d.ts +37 -0
  94. package/dist_ts/private/releaseversion.js +48 -0
  95. package/dist_ts/private/runtimepolicy.d.ts +31 -0
  96. package/dist_ts/private/runtimepolicy.js +90 -0
  97. package/dist_ts/private/tokenlist.d.ts +9 -0
  98. package/dist_ts/private/tokenlist.js +23 -0
  99. package/dist_ts/protocol.d.ts +137 -0
  100. package/dist_ts/protocol.js +255 -0
  101. package/dist_ts/requests/admin.d.ts +8 -8
  102. package/dist_ts/requests/backup.d.ts +102 -112
  103. package/dist_ts/requests/cluster.d.ts +47 -10
  104. package/dist_ts/requests/cluster.js +1 -1
  105. package/dist_ts/requests/clusteringress.d.ts +9 -0
  106. package/dist_ts/requests/clusteringress.js +1 -1
  107. package/dist_ts/requests/config.d.ts +3 -3
  108. package/dist_ts/requests/corestore.d.ts +0 -3
  109. package/dist_ts/requests/corestore.js +5 -9
  110. package/dist_ts/requests/network.d.ts +87 -31
  111. package/dist_ts/requests/node.d.ts +15 -28
  112. package/dist_ts/requests/pallet.d.ts +13 -13
  113. package/dist_ts/requests/runtimesession.d.ts +53 -41
  114. package/dist_ts/requests/secret.d.ts +4 -5
  115. package/dist_ts/requests/secret.js +1 -5
  116. package/dist_ts/requests/service.d.ts +60 -0
  117. package/dist_ts/runtime.corestore.d.ts +56 -74
  118. package/dist_ts/runtime.corestore.databaseexportpackage.d.ts +30 -36
  119. package/dist_ts/runtime.corestore.databaseexportpackage.golden.d.ts +11 -12
  120. package/dist_ts/runtime.corestore.databaseexportpackage.golden.js +54 -71
  121. package/dist_ts/runtime.corestore.databaseexportpackage.js +9 -25
  122. package/dist_ts/runtime.corestore.js +35 -135
  123. package/dist_ts/runtime.corestore.relay.js +2 -7
  124. package/dist_ts/runtime.d.ts +38 -48
  125. package/dist_ts/runtime.js +20 -77
  126. package/dist_ts/runtime.networkprojection.d.ts +4 -4
  127. package/dist_ts/runtime.networkprojection.js +18 -18
  128. package/dist_ts/runtime.workloadinit.d.ts +23 -24
  129. package/dist_ts/runtime.workloadinit.js +6 -13
  130. package/package.json +2 -2
  131. package/readme.md +540 -269
  132. package/ts/00_commitinfo_data.ts +3 -3
  133. package/ts/appstore/types.ts +4 -6
  134. package/ts/data/backup.ts +3 -38
  135. package/ts/data/cluster.ts +51 -34
  136. package/ts/data/clusteringress.ts +12 -12
  137. package/ts/data/clusternode.ts +204 -232
  138. package/ts/data/clusterruntime.ts +45 -0
  139. package/ts/data/coremail.runtime.ts +4 -21
  140. package/ts/data/coremail.ts +3 -7
  141. package/ts/data/deploymentadoption.ts +46 -4
  142. package/ts/data/deploymentoperation.ts +16 -1
  143. package/ts/data/deploymentpreflight.ts +0 -2
  144. package/ts/data/immutableimage.ts +71 -24
  145. package/ts/data/index.ts +5 -1
  146. package/ts/data/isolatedrestore.golden.ts +5 -9
  147. package/ts/data/isolatedrestore.ts +339 -54
  148. package/ts/data/mail.ts +1 -1
  149. package/ts/data/networkaddressplan.ts +175 -0
  150. package/ts/data/networkauthority.ts +45 -61
  151. package/ts/data/networkcredential.ts +24 -24
  152. package/ts/data/networkdelivery.ts +27 -27
  153. package/ts/data/networklease.ts +40 -13
  154. package/ts/data/networknode.ts +37 -0
  155. package/ts/data/networkprojection.ts +119 -124
  156. package/ts/data/networkprotection.ts +54 -55
  157. package/ts/data/networkrouter.ts +14 -14
  158. package/ts/data/networksigning.ts +29 -32
  159. package/ts/data/nodecredential.ts +4 -6
  160. package/ts/data/nodeenrollment.ts +96 -114
  161. package/ts/data/privatenetwork.ts +58 -74
  162. package/ts/data/runtimeassignment.ts +143 -94
  163. package/ts/data/runtimeconfig.ts +62 -122
  164. package/ts/data/runtimesession.ts +185 -138
  165. package/ts/data/runtimeterminalreceipt.ts +72 -73
  166. package/ts/data/secret.ts +28 -76
  167. package/ts/data/servicecredential.ts +33 -43
  168. package/ts/data/serviceruntime.ts +208 -0
  169. package/ts/data/sparknodereport.ts +48 -36
  170. package/ts/data/webpush.ts +0 -1
  171. package/ts/index.ts +2 -0
  172. package/ts/platform/objectstorageretention.ts +36 -55
  173. package/ts/platform/storage.ts +1 -3
  174. package/ts/platform/storagemigration.golden.ts +7 -11
  175. package/ts/platform/storagemigration.ts +5 -55
  176. package/ts/platform/types.ts +2 -2
  177. package/ts/private/canonicaljson.ts +13 -1
  178. package/ts/private/dataproperties.ts +139 -0
  179. package/ts/private/networkcontract.ts +23 -9
  180. package/ts/private/producercontract.ts +19 -0
  181. package/ts/private/releaseversion.ts +70 -0
  182. package/ts/private/runtimepolicy.ts +105 -0
  183. package/ts/private/tokenlist.ts +30 -0
  184. package/ts/protocol.ts +364 -0
  185. package/ts/requests/admin.ts +11 -11
  186. package/ts/requests/backup.ts +112 -117
  187. package/ts/requests/cluster.ts +58 -13
  188. package/ts/requests/clusteringress.ts +9 -0
  189. package/ts/requests/config.ts +3 -3
  190. package/ts/requests/corestore.ts +4 -16
  191. package/ts/requests/network.ts +90 -41
  192. package/ts/requests/node.ts +21 -38
  193. package/ts/requests/pallet.ts +17 -17
  194. package/ts/requests/runtimesession.ts +63 -51
  195. package/ts/requests/secret.ts +5 -10
  196. package/ts/requests/service.ts +81 -0
  197. package/ts/runtime.corestore.databaseexportpackage.golden.ts +77 -95
  198. package/ts/runtime.corestore.databaseexportpackage.ts +51 -73
  199. package/ts/runtime.corestore.relay.ts +1 -10
  200. package/ts/runtime.corestore.ts +118 -268
  201. package/ts/runtime.networkprojection.ts +30 -30
  202. package/ts/runtime.ts +83 -158
  203. package/ts/runtime.workloadinit.ts +36 -48
  204. package/dist_ts/runtime.cloudlylegacydeploymentsettlement.d.ts +0 -902
  205. package/dist_ts/runtime.cloudlylegacydeploymentsettlement.golden.d.ts +0 -35
  206. package/dist_ts/runtime.cloudlylegacydeploymentsettlement.golden.js +0 -315
  207. package/dist_ts/runtime.cloudlylegacydeploymentsettlement.js +0 -3315
  208. package/dist_ts/runtime.cloudlylegacydeploymentsettlement.offlineexport.d.ts +0 -291
  209. package/dist_ts/runtime.cloudlylegacydeploymentsettlement.offlineexport.golden.d.ts +0 -30
  210. package/dist_ts/runtime.cloudlylegacydeploymentsettlement.offlineexport.golden.js +0 -408
  211. package/dist_ts/runtime.cloudlylegacydeploymentsettlement.offlineexport.js +0 -1126
  212. package/ts/runtime.cloudlylegacydeploymentsettlement.golden.ts +0 -421
  213. package/ts/runtime.cloudlylegacydeploymentsettlement.offlineexport.golden.ts +0 -510
  214. package/ts/runtime.cloudlylegacydeploymentsettlement.offlineexport.ts +0 -2470
  215. package/ts/runtime.cloudlylegacydeploymentsettlement.ts +0 -6630
@@ -6,11 +6,17 @@ import type {
6
6
  IBackupArchiveObject,
7
7
  IBackupRecord,
8
8
  IBackupReplicationResult,
9
- IIsolatedRestoreNodeState,
10
9
  IIsolatedRestoreRecord,
11
10
  TBackupSnapshot,
12
- TIsolatedRestoreResourceMapping,
13
11
  } from '../data/backup.js';
12
+ import type {
13
+ IIsolatedRestoreControlCleanupRequest,
14
+ IIsolatedRestoreControlExecuteRequest,
15
+ IIsolatedRestoreControlPrepareRequest,
16
+ IIsolatedRestoreControlStatusRequest,
17
+ IIsolatedRestoreControlWriteRequest,
18
+ IIsolatedRestoreProgress,
19
+ } from '../data/isolatedrestore.js';
14
20
  import type { IService } from '../data/service.js';
15
21
  import type { IIdentity, IIdentityCredential } from '../data/user.js';
16
22
  import type { ICorestoreDatabaseClosureDescriptor } from '../runtime.corestore.relay.js';
@@ -400,7 +406,14 @@ extends plugins.typedrequestInterfaces.implementsTR<
400
406
  /** Cloudly verifies this credential and derives all actor claims server-side. */
401
407
  identity: IIdentityCredential;
402
408
  sourceBackupId: string;
403
- targetNodeName: string;
409
+ /**
410
+ * The cluster node this restore is dispatched to, as the cluster document names it.
411
+ *
412
+ * Cloudly signs the restore grant for the `targetNodeName` that node carries, and every
413
+ * control call is routed by this id: the name is what the operator's grant authorizes, the id
414
+ * is what the relay routes on, and Cloudly is the one party that holds both.
415
+ */
416
+ targetNodeId: string;
404
417
  purpose: string;
405
418
  /** Caller-generated key; retries return the original restore. */
406
419
  idempotencyKey: string;
@@ -414,6 +427,8 @@ extends plugins.typedrequestInterfaces.implementsTR<
414
427
  id?: never;
415
428
  /** Alias-like caller input is forbidden as well. */
416
429
  restoreId?: never;
430
+ /** Derived from the node the restore is dispatched to; the grant carries it. */
431
+ targetNodeName?: never;
417
432
  /** Legacy runnable-service targeting is forbidden. */
418
433
  targetServiceId?: never;
419
434
  /** Generated by Cloudly. Explicitly forbidden as caller input. */
@@ -440,6 +455,9 @@ extends plugins.typedrequestInterfaces.implementsTR<
440
455
  sourceBackupId?: string;
441
456
  sourceServiceId?: string;
442
457
  clusterId?: string;
458
+ /** The node the restore is dispatched to. */
459
+ targetNodeId?: string;
460
+ /** The node name the restore grant authorizes. */
443
461
  targetNodeName?: string;
444
462
  scratchNamespaceId?: string;
445
463
  status?: IIsolatedRestoreRecord['status'];
@@ -473,54 +491,67 @@ extends plugins.typedrequestInterfaces.implementsTR<
473
491
  }
474
492
 
475
493
  /**
476
- * Prepares and stages one isolated restore on an exact cluster node. A missing
477
- * node state has revision 0; successful mutation returns the next revision.
494
+ * Carrying one isolated-restore control to one exact node of this cluster.
495
+ *
496
+ * Five contracts share one shape: `nodeId` names the node of this cluster, `control` is the body
497
+ * Corestore reads, and the answer is what that node states about the restore. The relay is a
498
+ * carrier: it forwards the control untouched, adds nothing to it and reads nothing out of it. The
499
+ * signed `restoreGrant` inside is the only authority Corestore accepts on these routes — it names
500
+ * the operation, expires within minutes, and binds the cluster, the node name, the canonical
501
+ * resource mappings and the archive manifest — so a relay can carry it but can neither widen it
502
+ * nor mint one.
503
+ *
504
+ * The node is a request field because one relay serves every node of its cluster over one
505
+ * session: the connection that answers proves which cluster is speaking, never which node is
506
+ * meant. No identity field: the cluster is the one the verified machine identity on the session
507
+ * `registerCloudlyClientSession` opened names, exactly as `getClusterRouteTable` and
508
+ * `getClusterPlatformDesiredState` work, and a request-level identity would be a second authority
509
+ * for the same fact, and the weaker of the two. No protocol offer either: that handshake exchanged
510
+ * one, and the relay stated its own again in `registerClusterRelay`'s `protocol` member, so
511
+ * neither fact belongs on a request.
512
+ *
513
+ * Sensitive ephemeral input on all five: the control carries a bearer grant, so exclude the
514
+ * complete request from hooks, logs, diagnostics and durable journals on every hop.
515
+ *
516
+ * A relay that cannot reach the node answers one of `data.isolatedRestoreNodeControlRefusals`
517
+ * instead of a progress; everything Corestore itself refused arrives under
518
+ * `restore-node-refused` with Corestore's own reason.
478
519
  */
479
- export interface IReq_Cloudly_Coreflow_PrepareIsolatedRestore
520
+ export interface IReq_Cloudly_Relay_PrepareIsolatedRestoreOnNode
480
521
  extends plugins.typedrequestInterfaces.implementsTR<
481
522
  plugins.typedrequestInterfaces.ITypedRequest,
482
- IReq_Cloudly_Coreflow_PrepareIsolatedRestore
523
+ IReq_Cloudly_Relay_PrepareIsolatedRestoreOnNode
483
524
  > {
484
- method: 'coreflowPrepareIsolatedRestore';
525
+ method: 'prepareIsolatedRestoreOnNode';
485
526
  request: {
486
- /**
487
- * The compact RS256 restore grant Cloudly signed for exactly this
488
- * operation, carried untouched to Corestore.
489
- *
490
- * Corestore accepts no other authority on an isolated-restore route: the
491
- * grant names the operation, expires within minutes, and binds the cluster,
492
- * the node, the canonical resource mappings and the archive manifest, so a
493
- * relay can carry it but can neither widen it nor mint one. Sensitive
494
- * ephemeral input: exclude the complete request from hooks, logs and
495
- * journals on every hop.
496
- */
497
- restoreGrant: string;
498
- clusterId: string;
499
- targetNodeName: string;
500
- restoreId: string;
501
- expectedRevision: number;
502
- sourceBackupId: string;
503
- sourceServiceId: string;
504
- scratchNamespaceId: string;
505
- stagingArchiveId: string;
506
- resourceMappings: TIsolatedRestoreResourceMapping[];
507
- archiveManifest: IBackupArchiveManifest;
527
+ /** The cluster node whose Corestore stages this restore. */
528
+ nodeId: string;
529
+ /** `expectedRevision` is 0 for a restore this node does not hold yet; a replay returns its state. */
530
+ control: IIsolatedRestoreControlPrepareRequest;
508
531
  };
509
532
  response: {
510
- state: IIsolatedRestoreNodeState;
533
+ progress: IIsolatedRestoreProgress;
511
534
  };
512
535
  }
513
536
 
514
537
  /**
515
- * Cloudly stages one archive object of an isolated restore on the relay's node.
538
+ * Cloudly stages one bounded chunk of one archive object on the relay's node.
516
539
  *
517
- * Cloudly holds the source backup, so these bytes travel Cloudly → relay and
518
- * the requester is the sender. One object per call, as the archive manifest
519
- * lists it: Corestore writes staged objects under a `write-object` grant, one
520
- * bounded chunk at a time, and the relay is what turns this stream into those
521
- * chunks. The object descriptor is the manifest entry itself — path, exact size
522
- * and digest — so the relay can prove the complete object before it counts as
523
- * written, and so a replayed stage settles on the same bytes.
540
+ * Cloudly holds the source backup, so these bytes travel Cloudly → relay → Corestore, one chunk
541
+ * per call as `data.isolatedRestoreContractLimits` bounds them: at most 512 KiB decoded per chunk,
542
+ * 4,096 chunks per object and 64 MiB per object. The chunk states the complete object — `path`,
543
+ * `size`, `sha256` — and authenticates its own bytes with `chunkSha256`, so a replayed chunk
544
+ * settles on the same bytes and a completed object is proved rather than assumed. The answer's
545
+ * `stagedObject` says where the next chunk continues, which is what lets an interrupted staging
546
+ * run resume at the byte the node already holds.
547
+ *
548
+ * That answer is a projection of Corestore's own: `path`, `nextOffset` and `completed` are top
549
+ * level on Corestore's write answer and become `stagedObject` here, Corestore's own `object`
550
+ * member is the received-object receipt it stored and is not carried, and the extra members the
551
+ * mutating routes add (`written`, `restored`, `ok`, `stagingArchiveDeleted`, `alreadyAbsent`) are
552
+ * dropped, so all five contracts answer the one shape a node can state.
553
+ *
554
+ * Sensitive ephemeral input; see `prepareIsolatedRestoreOnNode`.
524
555
  */
525
556
  export interface IReq_Cloudly_Relay_StageIsolatedRestoreArchive
526
557
  extends plugins.typedrequestInterfaces.implementsTR<
@@ -529,115 +560,79 @@ extends plugins.typedrequestInterfaces.implementsTR<
529
560
  > {
530
561
  method: 'stageIsolatedRestoreArchive';
531
562
  request: {
532
- /**
533
- * The compact RS256 restore grant for the `write-object` operation, carried
534
- * untouched to Corestore. Sensitive ephemeral input, like every other
535
- * grant on these routes.
536
- */
537
- restoreGrant: string;
538
- clusterId: string;
539
- targetNodeName: string;
540
- restoreId: string;
541
- expectedRevision: number;
542
- /** The manifest entry these bytes complete: `path`, `size`, `sha256`. */
543
- object: IBackupArchiveObject;
544
- /** Requester sends the object bytes; the TypedHandler receives them. */
545
- archive: plugins.typedrequestInterfaces.TVirtualStream<'send'>;
563
+ /** The cluster node whose Corestore holds the staging tree. */
564
+ nodeId: string;
565
+ control: IIsolatedRestoreControlWriteRequest;
546
566
  };
547
567
  response: {
548
- state: IIsolatedRestoreNodeState;
568
+ progress: IIsolatedRestoreProgress;
549
569
  };
550
570
  }
551
571
 
552
- /** Read-only status for one exact cluster/node/restore routing key. */
553
- export interface IReq_Cloudly_Coreflow_GetIsolatedRestoreStatus
572
+ /** Reads what one node holds for a restore, without changing it; see `prepareIsolatedRestoreOnNode`. */
573
+ export interface IReq_Cloudly_Relay_GetIsolatedRestoreProgressOnNode
554
574
  extends plugins.typedrequestInterfaces.implementsTR<
555
575
  plugins.typedrequestInterfaces.ITypedRequest,
556
- IReq_Cloudly_Coreflow_GetIsolatedRestoreStatus
576
+ IReq_Cloudly_Relay_GetIsolatedRestoreProgressOnNode
557
577
  > {
558
- method: 'coreflowGetIsolatedRestoreStatus';
578
+ method: 'getIsolatedRestoreProgressOnNode';
559
579
  request: {
560
- /**
561
- * The compact RS256 restore grant Cloudly signed for exactly this
562
- * operation, carried untouched to Corestore.
563
- *
564
- * Corestore accepts no other authority on an isolated-restore route: the
565
- * grant names the operation, expires within minutes, and binds the cluster,
566
- * the node, the canonical resource mappings and the archive manifest, so a
567
- * relay can carry it but can neither widen it nor mint one. Sensitive
568
- * ephemeral input: exclude the complete request from hooks, logs and
569
- * journals on every hop.
570
- */
571
- restoreGrant: string;
572
- clusterId: string;
573
- targetNodeName: string;
574
- restoreId: string;
580
+ /** The cluster node whose Corestore is read. */
581
+ nodeId: string;
582
+ control: IIsolatedRestoreControlStatusRequest;
575
583
  };
576
584
  response: {
577
- found: boolean;
578
- state?: IIsolatedRestoreNodeState;
585
+ progress: IIsolatedRestoreProgress;
579
586
  };
580
587
  }
581
588
 
582
- export interface IReq_Cloudly_Coreflow_ExecuteIsolatedRestore
589
+ /**
590
+ * Restores every staged mapping into the scratch namespace on that node.
591
+ *
592
+ * `executed` requires every mapping of the plan to be completed, and a run that stopped answers
593
+ * `failed` with its staging tree intact, so the caller can read the progress and clean up rather
594
+ * than guess what is on the node.
595
+ *
596
+ * Sensitive ephemeral input; see `prepareIsolatedRestoreOnNode`.
597
+ */
598
+ export interface IReq_Cloudly_Relay_ExecuteIsolatedRestoreOnNode
583
599
  extends plugins.typedrequestInterfaces.implementsTR<
584
600
  plugins.typedrequestInterfaces.ITypedRequest,
585
- IReq_Cloudly_Coreflow_ExecuteIsolatedRestore
601
+ IReq_Cloudly_Relay_ExecuteIsolatedRestoreOnNode
586
602
  > {
587
- method: 'coreflowExecuteIsolatedRestore';
603
+ method: 'executeIsolatedRestoreOnNode';
588
604
  request: {
589
- /**
590
- * The compact RS256 restore grant Cloudly signed for exactly this
591
- * operation, carried untouched to Corestore.
592
- *
593
- * Corestore accepts no other authority on an isolated-restore route: the
594
- * grant names the operation, expires within minutes, and binds the cluster,
595
- * the node, the canonical resource mappings and the archive manifest, so a
596
- * relay can carry it but can neither widen it nor mint one. Sensitive
597
- * ephemeral input: exclude the complete request from hooks, logs and
598
- * journals on every hop.
599
- */
600
- restoreGrant: string;
601
- clusterId: string;
602
- targetNodeName: string;
603
- restoreId: string;
604
- expectedRevision: number;
605
+ /** The cluster node that runs the restore. */
606
+ nodeId: string;
607
+ control: IIsolatedRestoreControlExecuteRequest;
605
608
  };
606
609
  response: {
607
- state: IIsolatedRestoreNodeState;
610
+ progress: IIsolatedRestoreProgress;
608
611
  };
609
612
  }
610
613
 
611
614
  /**
612
- * Idempotent cleanup mutation. A cleanup-failed state remains retryable and
613
- * does not authorize release of the source-backup hold.
615
+ * Idempotent cleanup of everything this restore left on that node.
616
+ *
617
+ * A node that already cleaned up answers `cleaned` again rather than refusing, and a cleanup that
618
+ * failed stays retryable: the source-backup hold is released by the control plane only once a node
619
+ * states `cleaned`.
620
+ *
621
+ * Sensitive ephemeral input; see `prepareIsolatedRestoreOnNode`.
614
622
  */
615
- export interface IReq_Cloudly_Coreflow_CleanupIsolatedRestore
623
+ export interface IReq_Cloudly_Relay_CleanupIsolatedRestoreOnNode
616
624
  extends plugins.typedrequestInterfaces.implementsTR<
617
625
  plugins.typedrequestInterfaces.ITypedRequest,
618
- IReq_Cloudly_Coreflow_CleanupIsolatedRestore
626
+ IReq_Cloudly_Relay_CleanupIsolatedRestoreOnNode
619
627
  > {
620
- method: 'coreflowCleanupIsolatedRestore';
628
+ method: 'cleanupIsolatedRestoreOnNode';
621
629
  request: {
622
- /**
623
- * The compact RS256 restore grant Cloudly signed for exactly this
624
- * operation, carried untouched to Corestore.
625
- *
626
- * Corestore accepts no other authority on an isolated-restore route: the
627
- * grant names the operation, expires within minutes, and binds the cluster,
628
- * the node, the canonical resource mappings and the archive manifest, so a
629
- * relay can carry it but can neither widen it nor mint one. Sensitive
630
- * ephemeral input: exclude the complete request from hooks, logs and
631
- * journals on every hop.
632
- */
633
- restoreGrant: string;
634
- clusterId: string;
635
- targetNodeName: string;
636
- restoreId: string;
637
- expectedRevision: number;
630
+ /** The cluster node whose staging tree and scratch resources are removed. */
631
+ nodeId: string;
632
+ control: IIsolatedRestoreControlCleanupRequest;
638
633
  };
639
634
  response: {
640
- state: IIsolatedRestoreNodeState;
635
+ progress: IIsolatedRestoreProgress;
641
636
  };
642
637
  }
643
638
 
@@ -1,5 +1,7 @@
1
1
  import * as userInterfaces from '../data/user.js';
2
2
  import * as clusterInterfaces from '../data/cluster.js';
3
+ import type { IClusterRuntime, TClusterRuntimeBlocker } from '../data/clusterruntime.js';
4
+ import type { IServiceRuntimeAssignmentView } from '../data/serviceruntime.js';
3
5
  import type * as leaseInterfaces from '../data/networklease.js';
4
6
  import * as plugins from '../plugins.js';
5
7
 
@@ -75,17 +77,17 @@ export interface IReq_Any_Cloudly_UpdateCluster extends plugins.typedrequestInte
75
77
  * The response carries the block Cloudly published, which is the same block every cluster-side
76
78
  * component then reads from `ICluster.data.relay`.
77
79
  */
78
- export interface IReq_Any_Cloudly_EnableClusterRelayV1 extends plugins.typedrequestInterfaces.implementsTR<
80
+ export interface IReq_Any_Cloudly_EnableClusterRelay extends plugins.typedrequestInterfaces.implementsTR<
79
81
  plugins.typedrequestInterfaces.ITypedRequest,
80
- IReq_Any_Cloudly_EnableClusterRelayV1
82
+ IReq_Any_Cloudly_EnableClusterRelay
81
83
  > {
82
- method: 'enableClusterRelayV1';
84
+ method: 'enableClusterRelay';
83
85
  request: {
84
86
  identity: userInterfaces.IIdentity;
85
87
  clusterId: string;
86
88
  };
87
89
  response: {
88
- relay: clusterInterfaces.IClusterRelayV1;
90
+ relay: clusterInterfaces.IClusterRelay;
89
91
  };
90
92
  }
91
93
 
@@ -96,11 +98,11 @@ export interface IReq_Any_Cloudly_EnableClusterRelayV1 extends plugins.typedrequ
96
98
  * the response rather than absent: the caller learns that the block is gone, not that the
97
99
  * response forgot it.
98
100
  */
99
- export interface IReq_Any_Cloudly_DisableClusterRelayV1 extends plugins.typedrequestInterfaces.implementsTR<
101
+ export interface IReq_Any_Cloudly_DisableClusterRelay extends plugins.typedrequestInterfaces.implementsTR<
100
102
  plugins.typedrequestInterfaces.ITypedRequest,
101
- IReq_Any_Cloudly_DisableClusterRelayV1
103
+ IReq_Any_Cloudly_DisableClusterRelay
102
104
  > {
103
- method: 'disableClusterRelayV1';
105
+ method: 'disableClusterRelay';
104
106
  request: {
105
107
  identity: userInterfaces.IIdentity;
106
108
  clusterId: string;
@@ -134,17 +136,17 @@ export interface IReq_Any_Cloudly_GetClusterRelayRegistrations extends plugins.t
134
136
  /**
135
137
  * The cluster relay tells Cloudly where it listens, over its own authenticated socket.
136
138
  *
137
- * Sent after `registerCloudlyClientSessionV1`, so the cluster is the one the verified machine
139
+ * Sent after `registerCloudlyClientSession`, so the cluster is the one the verified machine
138
140
  * identity on that socket names and is never a request field. `Relay` names the role, not a
139
141
  * component: whichever process fills it for a cluster sends this.
140
142
  */
141
- export interface IReq_Relay_Cloudly_RegisterClusterRelayV1 extends plugins.typedrequestInterfaces.implementsTR<
143
+ export interface IReq_Relay_Cloudly_RegisterClusterRelay extends plugins.typedrequestInterfaces.implementsTR<
142
144
  plugins.typedrequestInterfaces.ITypedRequest,
143
- IReq_Relay_Cloudly_RegisterClusterRelayV1
145
+ IReq_Relay_Cloudly_RegisterClusterRelay
144
146
  > {
145
- method: 'registerClusterRelayV1';
146
- request: clusterInterfaces.IClusterRelayRegistrationV1;
147
- response: clusterInterfaces.IClusterRelayRegistrationResponseV1;
147
+ method: 'registerClusterRelay';
148
+ request: clusterInterfaces.IRegisterClusterRelayRequest;
149
+ response: clusterInterfaces.IRegisterClusterRelayResponse;
148
150
  }
149
151
 
150
152
  /**
@@ -182,3 +184,46 @@ export interface IReq_Any_Cloudly_DeleteClusterById extends plugins.typedrequest
182
184
  ok: boolean;
183
185
  };
184
186
  }
187
+
188
+ /**
189
+ * A cluster's runtime phase, and what still blocks it from leaving `swarm`.
190
+ *
191
+ * Cloudly refuses a cluster without a phase record as `cluster-runtime-missing` rather than
192
+ * assuming one. `blockers` is empty once nothing blocks the cutover.
193
+ */
194
+ export interface IReq_Any_Cloudly_GetClusterRuntime extends plugins.typedrequestInterfaces.implementsTR<
195
+ plugins.typedrequestInterfaces.ITypedRequest,
196
+ IReq_Any_Cloudly_GetClusterRuntime
197
+ > {
198
+ method: 'getClusterRuntime';
199
+ request: {
200
+ identity: userInterfaces.IIdentity;
201
+ clusterId: string;
202
+ };
203
+ response: {
204
+ runtime: IClusterRuntime;
205
+ blockers: TClusterRuntimeBlocker[];
206
+ };
207
+ }
208
+
209
+ /**
210
+ * Every current runtime assignment on one cluster's nodes, a page at a time: a cluster carries
211
+ * every node's slots of every service, which no single response bounds. `limit` runs from 1 to
212
+ * `serviceRuntimeContract.maximumAssignmentPageSize`; Cloudly refuses any other.
213
+ */
214
+ export interface IReq_Any_Cloudly_GetClusterRuntimeAssignments extends plugins.typedrequestInterfaces.implementsTR<
215
+ plugins.typedrequestInterfaces.ITypedRequest,
216
+ IReq_Any_Cloudly_GetClusterRuntimeAssignments
217
+ > {
218
+ method: 'getClusterRuntimeAssignments';
219
+ request: {
220
+ identity: userInterfaces.IIdentity;
221
+ clusterId: string;
222
+ cursor: string | null;
223
+ limit: number;
224
+ };
225
+ response: {
226
+ assignments: IServiceRuntimeAssignmentView[];
227
+ nextCursor: string | null;
228
+ };
229
+ }
@@ -1,4 +1,5 @@
1
1
  import * as clusterIngressInterfaces from '../data/clusteringress.js';
2
+ import type { IProtocolOffer } from '../protocol.js';
2
3
  import * as plugins from '../plugins.js';
3
4
 
4
5
  /**
@@ -65,6 +66,10 @@ export interface IReq_Relay_Cloudly_GetClusterRouteTable extends plugins.typedre
65
66
  * `revision` is the table the relay holds, so an accepted ingress knows at once
66
67
  * whether it has to fetch one. Cloudly answers `null`: the table is the relay's
67
68
  * to state, not Cloudly's to echo.
69
+ *
70
+ * Both hops judge the body in the one server order `protocol.readProtocolOffer`
71
+ * states, negotiating before the bearer is verified, as the shape states at
72
+ * `validateClusterIngressRegistration`.
68
73
  */
69
74
  export interface IReq_Ingress_Relay_Cloudly_RegisterClusterIngress extends plugins.typedrequestInterfaces.implementsTR<
70
75
  plugins.typedrequestInterfaces.ITypedRequest,
@@ -84,10 +89,14 @@ export interface IReq_Ingress_Relay_Cloudly_RegisterClusterIngress extends plugi
84
89
  nodeId: string;
85
90
  /** Optional capability names; an ingress that states none states nothing. */
86
91
  capabilities?: string[];
92
+ /** Read and negotiated by the relay and by Cloudly before the bearer is verified. */
93
+ protocol: IProtocolOffer;
87
94
  };
88
95
  response: {
89
96
  accepted: true;
90
97
  revision: number | null;
98
+ /** The offer of the side that accepted, so an ingress judges the session it opened. */
99
+ protocol: IProtocolOffer;
91
100
  };
92
101
  }
93
102
 
@@ -3,7 +3,7 @@ import * as clusterInterfaces from '../data/cluster.js';
3
3
  import * as userInterfaces from '../data/user.js';
4
4
  import type { IService } from '../data/service.js';
5
5
  import type { IPlatformBinding, IPlatformProviderConfig } from '../platform/types.js';
6
- import type { ICorestoreCredentialPublicationGrantV1 } from '../runtime.corestore.js';
6
+ import type { ICorestoreCredentialPublicationGrant } from '../runtime.corestore.js';
7
7
 
8
8
  export interface IRequest_Any_Cloudly_GetClusterConfig
9
9
  extends plugins.typedrequestInterfaces.implementsTR<
@@ -19,7 +19,7 @@ extends plugins.typedrequestInterfaces.implementsTR<
19
19
  services: IService[];
20
20
  platformProviderConfigs?: IPlatformProviderConfig[];
21
21
  platformBindings?: IPlatformBinding[];
22
- corestoreCredentialPublicationGrants?: ICorestoreCredentialPublicationGrantV1[];
22
+ corestoreCredentialPublicationGrants?: ICorestoreCredentialPublicationGrant[];
23
23
  };
24
24
  }
25
25
 
@@ -34,7 +34,7 @@ extends plugins.typedrequestInterfaces.implementsTR<
34
34
  services: IService[];
35
35
  platformProviderConfigs?: IPlatformProviderConfig[];
36
36
  platformBindings?: IPlatformBinding[];
37
- corestoreCredentialPublicationGrants?: ICorestoreCredentialPublicationGrantV1[];
37
+ corestoreCredentialPublicationGrants?: ICorestoreCredentialPublicationGrant[];
38
38
  };
39
39
  response: {};
40
40
  }
@@ -1,5 +1,6 @@
1
1
  import * as plugins from '../plugins.js';
2
2
  import type { IIdentity } from '../data/user.js';
3
+ import { hasExactKeys } from '../private/dataproperties.js';
3
4
 
4
5
  /**
5
6
  * A provisioned corestore resource (NoSQLDB database or ObjectStorage bucket)
@@ -30,7 +31,6 @@ export interface ICorestoreServiceResources {
30
31
  export interface ICorestoreNodeInventory {
31
32
  /** Swarm node hostnames of the reporting coreflow. */
32
33
  nodeNames: string[];
33
- protocolVersion: 1;
34
34
  checkedAt: number;
35
35
  reachable: boolean;
36
36
  errorCode?: 'NODE_DISCOVERY_FAILED' | 'CORESTORE_UNREACHABLE';
@@ -66,7 +66,6 @@ export interface ICorestoreInventoryProbe {
66
66
  status: TCorestoreInventoryProbeStatus;
67
67
  connectionId?: string;
68
68
  reporterSessionId?: string;
69
- capabilityVersion?: number;
70
69
  observedNodeNames: string[];
71
70
  checkedAt: number;
72
71
  lastSuccessfulInventoryAt?: number;
@@ -82,7 +81,6 @@ export interface ICorestoreInventoryReport {
82
81
 
83
82
  /** Final registration tag restored only after identity and capability tags. */
84
83
  export interface ICoreflowInventoryRegistration {
85
- registrationVersion: 1;
86
84
  reporterSessionId: string;
87
85
  registeredAt: number;
88
86
  }
@@ -118,22 +116,12 @@ const isClusterCorestoreRecord = (
118
116
  || Object.getPrototypeOf(valueArg) === null)
119
117
  );
120
118
 
121
- const hasClusterCorestoreKeys = (
122
- valueArg: Record<string, unknown>,
123
- keysArg: readonly string[],
124
- optionalKeysArg: readonly string[] = [],
125
- ): boolean => {
126
- const actualKeys = Object.keys(valueArg);
127
- return keysArg.every((keyArg) => actualKeys.includes(keyArg))
128
- && actualKeys.every((keyArg) => keysArg.includes(keyArg) || optionalKeysArg.includes(keyArg));
129
- };
130
-
131
119
  const validateClusterCorestoreServiceResources = (
132
120
  valueArg: unknown,
133
121
  pathArg: string,
134
122
  ): string[] => {
135
123
  if (!isClusterCorestoreRecord(valueArg)
136
- || !hasClusterCorestoreKeys(
124
+ || !hasExactKeys(
137
125
  valueArg,
138
126
  ['serviceId', 'resources', 'updatedAt'],
139
127
  ['serviceName'],
@@ -155,7 +143,7 @@ const validateClusterCorestoreServiceResources = (
155
143
  for (const [index, resource] of valueArg.resources.entries()) {
156
144
  const resourcePath = `${pathArg} resources[${index}]`;
157
145
  if (!isClusterCorestoreRecord(resource)
158
- || !hasClusterCorestoreKeys(
146
+ || !hasExactKeys(
159
147
  resource,
160
148
  ['capability', 'provider', 'resourceName', 'createdAt'],
161
149
  )) {
@@ -193,7 +181,7 @@ export const validateClusterCorestoreInventory = (
193
181
  pathArg = 'cluster corestore inventory',
194
182
  ): string[] => {
195
183
  if (!isClusterCorestoreRecord(valueArg)
196
- || !hasClusterCorestoreKeys(
184
+ || !hasExactKeys(
197
185
  valueArg,
198
186
  ['nodeId', 'checkedAt', 'reachable', 'services'],
199
187
  ['errorCode'],