@zlink-systems/framework 0.26.0 → 0.28.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 (561) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/contracts/Actors/ZLinkActorClient.d.ts +1 -1
  3. package/dist/contracts/Channels/Calls.d.ts +1 -1
  4. package/dist/contracts/Common/CoreTypes.d.ts +6 -0
  5. package/dist/contracts/Common/CoreTypes.js +7 -0
  6. package/dist/contracts/Common/index.d.ts +1 -1
  7. package/dist/contracts/Common/index.js +0 -1
  8. package/dist/contracts/Configuration/Builders.d.ts +0 -1
  9. package/dist/contracts/Configuration/Configs.d.ts +0 -1
  10. package/dist/contracts/Configuration/InternalDefaults.d.ts +8 -0
  11. package/dist/contracts/Configuration/InternalDefaults.js +9 -1
  12. package/dist/contracts/Configuration/Registration.d.ts +13 -2
  13. package/dist/contracts/Configuration/Registration.js +58 -36
  14. package/dist/contracts/Configuration/RegistrationBuilderPolicy.d.ts +13 -1
  15. package/dist/contracts/Configuration/RegistrationBuilderPolicy.js +38 -1
  16. package/dist/contracts/Configuration/RegistrationBuilders.d.ts +2 -3
  17. package/dist/contracts/Configuration/RegistrationBuilders.js +27 -32
  18. package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -5
  19. package/dist/contracts/Configuration/RegistrationValidators.js +15 -14
  20. package/dist/contracts/Configuration/TimerRegistrationValidator.js +3 -2
  21. package/dist/contracts/Dispatch/ZLinkDispatchOptions.d.ts +1 -1
  22. package/dist/contracts/Handlers/JsonContract.js +10 -4
  23. package/dist/contracts/Locations/Authority.d.ts +1 -1
  24. package/dist/contracts/Locations/Authority.js +3 -2
  25. package/dist/contracts/Locations/Options.js +1 -1
  26. package/dist/contracts/Locations/Stores.d.ts +12 -0
  27. package/dist/contracts/Locations/Stores.js +9 -0
  28. package/dist/contracts/Spots/Contracts.d.ts +2 -2
  29. package/dist/contracts/Streams/BoundSessionContracts.d.ts +1 -1
  30. package/dist/contracts/Streams/IZLinkSession.d.ts +2 -3
  31. package/dist/contracts/Streams/IZLinkSessionActor.d.ts +2 -2
  32. package/dist/internal.d.ts +4 -0
  33. package/dist/internal.js +15 -1
  34. package/dist/nest-integration.d.ts +4 -2
  35. package/dist/nest-integration.js +14 -4
  36. package/dist/runtime/abort.d.ts +1 -0
  37. package/dist/runtime/abort.js +8 -5
  38. package/dist/runtime/activation-admission.d.ts +1 -2
  39. package/dist/runtime/activation-admission.js +2 -6
  40. package/dist/runtime/actors/actor-authority-payload-codec.d.ts +1 -2
  41. package/dist/runtime/actors/actor-authority-payload-codec.js +34 -18
  42. package/dist/runtime/actors/actor-client.d.ts +2 -2
  43. package/dist/runtime/actors/actor-client.js +49 -153
  44. package/dist/runtime/actors/actor-context.d.ts +3 -5
  45. package/dist/runtime/actors/actor-context.js +13 -11
  46. package/dist/runtime/actors/actor-handoff.d.ts +4 -4
  47. package/dist/runtime/actors/actor-handoff.js +8 -8
  48. package/dist/runtime/actors/actor-lifecycle-snapshot.js +2 -1
  49. package/dist/runtime/actors/actor-local-native-join.d.ts +11 -6
  50. package/dist/runtime/actors/actor-local-native-join.js +83 -105
  51. package/dist/runtime/actors/actor-native-lookup.js +2 -8
  52. package/dist/runtime/actors/actor-packet-relay-wire.d.ts +3 -3
  53. package/dist/runtime/actors/actor-packet-relay-wire.js +5 -3
  54. package/dist/runtime/actors/actor-remote-joiner.d.ts +1 -1
  55. package/dist/runtime/actors/actor-remote-joiner.js +5 -9
  56. package/dist/runtime/actors/actor-remote-wire.js +5 -3
  57. package/dist/runtime/actors/actor-request-deadline.d.ts +1 -0
  58. package/dist/runtime/actors/actor-request-deadline.js +6 -0
  59. package/dist/runtime/actors/actor-retry-delay.js +2 -1
  60. package/dist/runtime/actors/actor-routed-join-transport.d.ts +2 -3
  61. package/dist/runtime/actors/actor-runtime-state.d.ts +9 -21
  62. package/dist/runtime/actors/actor-runtime-state.js +70 -187
  63. package/dist/runtime/actors/bound-session-wire.js +2 -7
  64. package/dist/runtime/actors/deferred-join-completion.d.ts +11 -6
  65. package/dist/runtime/actors/deferred-join-completion.js +1 -0
  66. package/dist/runtime/actors/index.d.ts +9 -7
  67. package/dist/runtime/actors/index.js +87 -69
  68. package/dist/runtime/actors/spot-actor-dispatch.d.ts +3 -3
  69. package/dist/runtime/actors/spot-actor-dispatch.js +25 -10
  70. package/dist/runtime/actors/transferred-actor-rollback.d.ts +3 -5
  71. package/dist/runtime/actors/transferred-actor-rollback.js +9 -42
  72. package/dist/runtime/admission.d.ts +2 -0
  73. package/dist/runtime/admission.js +7 -1
  74. package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +1 -1
  75. package/dist/runtime/application-jobs/application-job-queue-scope.js +1 -1
  76. package/dist/runtime/backend/contracts/index.d.ts +7 -27
  77. package/dist/runtime/backend/mesh-actor-session-node-adapter.js +1 -17
  78. package/dist/runtime/backend/mesh-dispatch-pump.d.ts +1 -2
  79. package/dist/runtime/backend/mesh-dispatch-pump.js +95 -107
  80. package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +3 -1
  81. package/dist/runtime/backend/node/node-backend-adapter-support.js +51 -10
  82. package/dist/runtime/backend/node/node-dealer-channel-client-transport.d.ts +1 -1
  83. package/dist/runtime/backend/node/node-dealer-channel-client-transport.js +1 -2
  84. package/dist/runtime/backend/node/node-event-loop-poller.d.ts +2 -2
  85. package/dist/runtime/backend/node/node-event-loop-poller.js +6 -7
  86. package/dist/runtime/backend/node/node-monitor-backend-adapter.js +1 -0
  87. package/dist/runtime/backend/node/node-raw-binding-port.js +41 -34
  88. package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +14 -15
  89. package/dist/runtime/backend/node/node-raw-mesh-backend.js +146 -118
  90. package/dist/runtime/backend/node/node-socket-backend-adapter.js +4 -3
  91. package/dist/runtime/backend/raw-binding-port.d.ts +1 -1
  92. package/dist/runtime/backend/runtime-values.d.ts +4 -1
  93. package/dist/runtime/backend/runtime-values.js +2 -0
  94. package/dist/runtime/channels/channel-clients.d.ts +20 -8
  95. package/dist/runtime/channels/channel-clients.js +73 -59
  96. package/dist/runtime/channels/channel-envelope-inspection.js +2 -1
  97. package/dist/runtime/channels/channel-envelope.d.ts +1 -1
  98. package/dist/runtime/channels/channel-envelope.js +51 -39
  99. package/dist/runtime/channels/channel-outbound-operations.d.ts +5 -2
  100. package/dist/runtime/channels/channel-outbound-operations.js +25 -42
  101. package/dist/runtime/channels/channel-receive-loops.d.ts +8 -3
  102. package/dist/runtime/channels/channel-receive-loops.js +27 -6
  103. package/dist/runtime/channels/channel-runtime-lifecycle.d.ts +12 -1
  104. package/dist/runtime/channels/channel-runtime-lifecycle.js +48 -28
  105. package/dist/runtime/channels/channel-runtime-manager.d.ts +4 -4
  106. package/dist/runtime/channels/channel-runtime-manager.js +13 -10
  107. package/dist/runtime/channels/channel-socket-options.js +3 -12
  108. package/dist/runtime/channels/channel-socket-registry.d.ts +14 -29
  109. package/dist/runtime/channels/channel-socket-registry.js +240 -177
  110. package/dist/runtime/channels/channel-transports.d.ts +21 -31
  111. package/dist/runtime/channels/channel-transports.js +80 -62
  112. package/dist/runtime/channels/client-server-location-runtime.d.ts +1 -1
  113. package/dist/runtime/channels/client-server-location-runtime.js +10 -11
  114. package/dist/runtime/channels/client-server-service-wire.d.ts +7 -2
  115. package/dist/runtime/channels/client-server-service-wire.js +32 -11
  116. package/dist/runtime/channels/dispatch-error-reporter.d.ts +1 -2
  117. package/dist/runtime/channels/dispatch-error-reporter.js +2 -1
  118. package/dist/runtime/channels/fanout-location-runtime.d.ts +16 -3
  119. package/dist/runtime/channels/fanout-location-runtime.js +130 -72
  120. package/dist/runtime/channels/local-spot-route-transport.d.ts +1 -1
  121. package/dist/runtime/channels/local-spot-route-transport.js +1 -3
  122. package/dist/runtime/channels/router-socket-spot-route-transport.d.ts +1 -1
  123. package/dist/runtime/channels/router-socket-spot-route-transport.js +2 -2
  124. package/dist/runtime/channels/source-spot-router.d.ts +1 -1
  125. package/dist/runtime/channels/source-spot-router.js +2 -4
  126. package/dist/runtime/channels/spot-direct-envelope.d.ts +1 -0
  127. package/dist/runtime/channels/spot-direct-envelope.js +4 -3
  128. package/dist/runtime/channels/spot-node-route-transport.d.ts +1 -1
  129. package/dist/runtime/channels/spot-node-route-transport.js +5 -5
  130. package/dist/runtime/channels/spot-route-bridge-transport.d.ts +1 -1
  131. package/dist/runtime/channels/spot-route-bridge-transport.js +2 -2
  132. package/dist/runtime/channels/spot-route-dispatch-strategy.d.ts +2 -4
  133. package/dist/runtime/channels/spot-route-dispatch-strategy.js +11 -12
  134. package/dist/runtime/diagnostics/diagnostic-text.d.ts +2 -0
  135. package/dist/runtime/diagnostics/diagnostic-text.js +7 -0
  136. package/dist/runtime/diagnostics/dispatch-error-details.d.ts +3 -0
  137. package/dist/runtime/diagnostics/dispatch-error-details.js +30 -2
  138. package/dist/runtime/diagnostics/flow-context.d.ts +6 -0
  139. package/dist/runtime/diagnostics/flow-context.js +16 -2
  140. package/dist/runtime/diagnostics/index.d.ts +4 -2
  141. package/dist/runtime/diagnostics/index.js +14 -4
  142. package/dist/runtime/diagnostics/message-flow.d.ts +1 -1
  143. package/dist/runtime/diagnostics/message-flow.js +10 -19
  144. package/dist/runtime/diagnostics/runtime-metrics.d.ts +94 -31
  145. package/dist/runtime/diagnostics/runtime-metrics.js +168 -105
  146. package/dist/runtime/diagnostics/runtime-observation-queue.js +3 -2
  147. package/dist/runtime/diagnostics/topology-runtime-projections.d.ts +2 -4
  148. package/dist/runtime/diagnostics/topology-runtime-projections.js +135 -154
  149. package/dist/runtime/disposal.d.ts +5 -0
  150. package/dist/runtime/disposal.js +22 -0
  151. package/dist/runtime/execution/index.d.ts +12 -9
  152. package/dist/runtime/execution/index.js +58 -14
  153. package/dist/runtime/execution/serial-execution-queue.d.ts +8 -2
  154. package/dist/runtime/execution/serial-execution-queue.js +54 -15
  155. package/dist/runtime/execution/state-lane.d.ts +8 -1
  156. package/dist/runtime/execution/state-lane.js +118 -3
  157. package/dist/runtime/foundation/actor-join-recovery-codec.d.ts +3 -0
  158. package/dist/runtime/foundation/actor-join-recovery-codec.js +15 -11
  159. package/dist/runtime/foundation/event-loop-resources.d.ts +2 -24
  160. package/dist/runtime/foundation/event-loop-resources.js +6 -119
  161. package/dist/runtime/foundation/operation-identity.d.ts +2 -0
  162. package/dist/runtime/foundation/operation-identity.js +9 -5
  163. package/dist/runtime/foundation/operation-registry.d.ts +5 -7
  164. package/dist/runtime/foundation/operation-registry.js +34 -44
  165. package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +8 -5
  166. package/dist/runtime/foundation/raw-service-mesh-runtime.js +79 -94
  167. package/dist/runtime/foundation/runtime-state-projections.d.ts +3 -1
  168. package/dist/runtime/foundation/runtime-state-projections.js +8 -0
  169. package/dist/runtime/foundation/service-authority-payload-codec.js +22 -12
  170. package/dist/runtime/foundation/service-discovery-registry.d.ts +4 -0
  171. package/dist/runtime/foundation/service-discovery-registry.js +22 -3
  172. package/dist/runtime/foundation/service-instance-activation-recovery-codec.js +8 -4
  173. package/dist/runtime/foundation/service-liveness-registry.js +2 -1
  174. package/dist/runtime/foundation/service-maintenance-runtime.d.ts +0 -1
  175. package/dist/runtime/foundation/service-maintenance-runtime.js +0 -6
  176. package/dist/runtime/foundation/service-metadata-codec.js +3 -3
  177. package/dist/runtime/foundation/service-relocation-aggregate-committer.d.ts +2 -5
  178. package/dist/runtime/foundation/service-relocation-aggregate-committer.js +1 -48
  179. package/dist/runtime/foundation/service-relocation-object-owner.js +3 -2
  180. package/dist/runtime/foundation/service-relocation-runtime.js +43 -32
  181. package/dist/runtime/foundation/service-runtime-contracts.d.ts +40 -8
  182. package/dist/runtime/foundation/service-runtime-contracts.js +25 -1
  183. package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +0 -12
  184. package/dist/runtime/foundation/service-stateful-registry.d.ts +2 -0
  185. package/dist/runtime/foundation/service-stateful-registry.js +10 -2
  186. package/dist/runtime/foundation/service-stateful-runtime.d.ts +26 -25
  187. package/dist/runtime/foundation/service-stateful-runtime.js +217 -204
  188. package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +3 -3
  189. package/dist/runtime/foundation/service-stateful-wire-codec.js +89 -55
  190. package/dist/runtime/foundation/service-topology-registry.d.ts +0 -1
  191. package/dist/runtime/foundation/service-topology-registry.js +17 -32
  192. package/dist/runtime/foundation/service-wire-binary-primitives.d.ts +5 -0
  193. package/dist/runtime/foundation/service-wire-binary-primitives.js +6 -0
  194. package/dist/runtime/foundation/service-wire-codec.js +10 -8
  195. package/dist/runtime/foundation/service-wire-constants.generated.d.ts +1 -0
  196. package/dist/runtime/foundation/service-wire-constants.generated.js +2 -1
  197. package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +2 -0
  198. package/dist/runtime/foundation/service-wire-m6a-codec.js +23 -13
  199. package/dist/runtime/framework-errors-internal.d.ts +2 -1
  200. package/dist/runtime/framework-errors-internal.js +343 -122
  201. package/dist/runtime/handlers/handler-instance-scope.d.ts +3 -1
  202. package/dist/runtime/handlers/handler-instance-scope.js +61 -74
  203. package/dist/runtime/host/actor-packet-relay.d.ts +11 -8
  204. package/dist/runtime/host/actor-packet-relay.js +54 -99
  205. package/dist/runtime/host/actor-placement-coordinator.js +7 -5
  206. package/dist/runtime/host/actor-runtime-options-factory.d.ts +2 -0
  207. package/dist/runtime/host/actor-runtime-options-factory.js +17 -4
  208. package/dist/runtime/host/actor-transfer-runtime.d.ts +16 -18
  209. package/dist/runtime/host/actor-transfer-runtime.js +143 -176
  210. package/dist/runtime/host/application-job-queue.js +16 -33
  211. package/dist/runtime/host/bound-session-relay.js +1 -1
  212. package/dist/runtime/host/channel-runtime-options-factory.js +1 -1
  213. package/dist/runtime/host/index.d.ts +14 -13
  214. package/dist/runtime/host/index.js +190 -171
  215. package/dist/runtime/host/instance-activation-authority.d.ts +2 -3
  216. package/dist/runtime/host/instance-activation-authority.js +17 -45
  217. package/dist/runtime/host/location-runtime-owner.d.ts +1 -1
  218. package/dist/runtime/host/location-runtime-owner.js +2 -2
  219. package/dist/runtime/host/remote-actor-join-receiver.d.ts +2 -2
  220. package/dist/runtime/host/remote-actor-join-receiver.js +1 -14
  221. package/dist/runtime/host/remote-actor-packet-target-store.d.ts +3 -2
  222. package/dist/runtime/host/remote-actor-packet-target-store.js +8 -47
  223. package/dist/runtime/host/remote-bound-session-relay.d.ts +2 -3
  224. package/dist/runtime/host/remote-bound-session-relay.js +15 -28
  225. package/dist/runtime/host/route-mesh-runtime.d.ts +13 -11
  226. package/dist/runtime/host/route-mesh-runtime.js +171 -252
  227. package/dist/runtime/host/runtime-shutdown.d.ts +2 -0
  228. package/dist/runtime/host/runtime-shutdown.js +18 -21
  229. package/dist/runtime/host/service-relocation-control.js +6 -1
  230. package/dist/runtime/host/service-relocation-host-runtime.d.ts +21 -30
  231. package/dist/runtime/host/service-relocation-host-runtime.js +508 -416
  232. package/dist/runtime/host/spot-address-transport.d.ts +3 -12
  233. package/dist/runtime/host/spot-address-transport.js +78 -220
  234. package/dist/runtime/host/spot-node-runtime-options-factory.d.ts +1 -1
  235. package/dist/runtime/host/spot-node-runtime-options-factory.js +3 -2
  236. package/dist/runtime/host/spot-runtime-options-factory.d.ts +4 -10
  237. package/dist/runtime/host/spot-runtime-options-factory.js +50 -14
  238. package/dist/runtime/host/user-spot-creation-coordinator.d.ts +3 -3
  239. package/dist/runtime/host/user-spot-creation-coordinator.js +11 -8
  240. package/dist/runtime/locations/aggregate-inventory-store.js +13 -10
  241. package/dist/runtime/locations/authority-key-codec.js +4 -3
  242. package/dist/runtime/locations/auto-connect-reconciler.d.ts +4 -0
  243. package/dist/runtime/locations/auto-connect-reconciler.js +37 -25
  244. package/dist/runtime/locations/creation-operation-id.js +6 -4
  245. package/dist/runtime/locations/domain-store-contract.d.ts +3 -3
  246. package/dist/runtime/locations/in-memory-authority-store.js +31 -15
  247. package/dist/runtime/locations/in-memory-location-store.d.ts +2 -2
  248. package/dist/runtime/locations/in-memory-location-store.js +17 -14
  249. package/dist/runtime/locations/in-memory-provider-location-store.d.ts +1 -0
  250. package/dist/runtime/locations/in-memory-provider-location-store.js +72 -22
  251. package/dist/runtime/locations/key-codec.js +3 -2
  252. package/dist/runtime/locations/lease-tracker.d.ts +3 -5
  253. package/dist/runtime/locations/lease-tracker.js +7 -11
  254. package/dist/runtime/locations/lifecycle.d.ts +4 -9
  255. package/dist/runtime/locations/lifecycle.js +2 -31
  256. package/dist/runtime/locations/location-store-failure.d.ts +2 -0
  257. package/dist/runtime/locations/location-store-failure.js +7 -0
  258. package/dist/runtime/locations/location-store-pages.d.ts +3 -0
  259. package/dist/runtime/locations/location-store-pages.js +13 -0
  260. package/dist/runtime/locations/location-store-repository.d.ts +5 -7
  261. package/dist/runtime/locations/location-store-repository.js +309 -336
  262. package/dist/runtime/locations/relocation-blob.js +18 -5
  263. package/dist/runtime/locations/resolvers.d.ts +5 -5
  264. package/dist/runtime/locations/resolvers.js +37 -28
  265. package/dist/runtime/locations/runtime.d.ts +5 -4
  266. package/dist/runtime/locations/runtime.js +123 -92
  267. package/dist/runtime/locations/spot-location-claims.d.ts +6 -0
  268. package/dist/runtime/locations/spot-location-claims.js +42 -1
  269. package/dist/runtime/messaging/payload-codec.js +26 -20
  270. package/dist/runtime/messaging/request-deadline.d.ts +3 -0
  271. package/dist/runtime/messaging/request-deadline.js +39 -0
  272. package/dist/runtime/messaging/submission-result.d.ts +4 -0
  273. package/dist/runtime/messaging/submission-result.js +56 -1
  274. package/dist/runtime/protocol/service_wire_codec.generated.d.ts +1 -0
  275. package/dist/runtime/protocol/service_wire_codec.generated.js +12 -7
  276. package/dist/runtime/spots/formal-remote-actor-transfer-registry.d.ts +4 -1
  277. package/dist/runtime/spots/index.d.ts +14 -20
  278. package/dist/runtime/spots/index.js +302 -176
  279. package/dist/runtime/spots/spot-activation-registry.d.ts +3 -5
  280. package/dist/runtime/spots/spot-activation-registry.js +14 -50
  281. package/dist/runtime/spots/spot-activation-state.d.ts +1 -1
  282. package/dist/runtime/spots/spot-activation-state.js +2 -2
  283. package/dist/runtime/spots/spot-activation.d.ts +3 -4
  284. package/dist/runtime/spots/spot-activation.js +49 -32
  285. package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +1 -2
  286. package/dist/runtime/spots/spot-actor-admission-coordinator.js +3 -40
  287. package/dist/runtime/spots/spot-actor-join-dispatch.d.ts +10 -18
  288. package/dist/runtime/spots/spot-actor-join-dispatch.js +4 -52
  289. package/dist/runtime/spots/spot-actor-membership.d.ts +4 -6
  290. package/dist/runtime/spots/spot-actor-membership.js +22 -45
  291. package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +0 -1
  292. package/dist/runtime/spots/spot-actor-packet-dispatch.js +0 -9
  293. package/dist/runtime/spots/spot-actor-packet-relay-dispatch.d.ts +2 -2
  294. package/dist/runtime/spots/spot-actor-packet-relay-dispatch.js +1 -7
  295. package/dist/runtime/spots/spot-context.d.ts +2 -2
  296. package/dist/runtime/spots/spot-entry-activation.d.ts +2 -2
  297. package/dist/runtime/spots/spot-entry-activation.js +9 -20
  298. package/dist/runtime/spots/spot-lifecycle-metrics.js +3 -2
  299. package/dist/runtime/spots/spot-manager-public.d.ts +5 -6
  300. package/dist/runtime/spots/spot-manager-public.js +5 -4
  301. package/dist/runtime/spots/spot-node-autoconnect.js +22 -31
  302. package/dist/runtime/spots/spot-node-runtime-manager.d.ts +19 -18
  303. package/dist/runtime/spots/spot-node-runtime-manager.js +67 -72
  304. package/dist/runtime/spots/spot-outbound.d.ts +7 -8
  305. package/dist/runtime/spots/spot-outbound.js +21 -23
  306. package/dist/runtime/spots/spot-remote-codec.js +5 -3
  307. package/dist/runtime/spots/spot-route-packet-dispatch.d.ts +2 -2
  308. package/dist/runtime/spots/spot-route-packet-dispatch.js +8 -8
  309. package/dist/runtime/spots/spot-route-replies.d.ts +2 -2
  310. package/dist/runtime/spots/spot-route-replies.js +3 -1
  311. package/dist/runtime/spots/spot-routed-actor-admission.d.ts +3 -3
  312. package/dist/runtime/spots/spot-routed-actor-admission.js +3 -12
  313. package/dist/runtime/spots/spot-routed-frame-dispatch.d.ts +1 -2
  314. package/dist/runtime/spots/spot-routed-frame-dispatch.js +0 -1
  315. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.d.ts +4 -0
  316. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +65 -15
  317. package/dist/runtime/spots/spot-runtime-ports.d.ts +2 -16
  318. package/dist/runtime/spots/spot-serial-executor.js +2 -2
  319. package/dist/runtime/spots/spot-serial-turn-executor.d.ts +27 -7
  320. package/dist/runtime/spots/spot-serial-turn-executor.js +83 -11
  321. package/dist/runtime/spots/spot-timer.d.ts +3 -2
  322. package/dist/runtime/streams/actor-session-binding-registry.d.ts +16 -29
  323. package/dist/runtime/streams/actor-session-binding-registry.js +142 -212
  324. package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +1 -4
  325. package/dist/runtime/streams/bound-actor-relay-sender.d.ts +8 -4
  326. package/dist/runtime/streams/bound-actor-relay-sender.js +65 -41
  327. package/dist/runtime/streams/bound-session-service.d.ts +7 -0
  328. package/dist/runtime/streams/bound-session-service.js +12 -2
  329. package/dist/runtime/streams/index.d.ts +16 -17
  330. package/dist/runtime/streams/index.js +22 -23
  331. package/dist/runtime/streams/managed-stream.d.ts +5 -2
  332. package/dist/runtime/streams/managed-stream.js +20 -13
  333. package/dist/runtime/streams/native-fallback-bound-session.js +14 -19
  334. package/dist/runtime/streams/protocol.d.ts +6 -33
  335. package/dist/runtime/streams/protocol.js +38 -110
  336. package/dist/runtime/streams/session-actor-coordinator.d.ts +2 -3
  337. package/dist/runtime/streams/session-actor-coordinator.js +12 -4
  338. package/dist/runtime/streams/session-calls.d.ts +6 -8
  339. package/dist/runtime/streams/session-calls.js +6 -22
  340. package/dist/runtime/streams/session-context.d.ts +10 -10
  341. package/dist/runtime/streams/session-context.js +25 -10
  342. package/dist/runtime/streams/session-requests.js +2 -1
  343. package/dist/runtime/streams/stream-binding-runtime-ports.d.ts +16 -1
  344. package/dist/runtime/streams/stream-frame-factory.js +2 -2
  345. package/dist/runtime/streams/stream-session-runtime.d.ts +10 -11
  346. package/dist/runtime/streams/stream-session-runtime.js +25 -33
  347. package/dist/runtime/workers/index.d.ts +2 -2
  348. package/dist/runtime/workers/index.js +5 -4
  349. package/package.json +3 -3
  350. package/src/contracts/Actors/ZLinkActorClient.ts +1 -1
  351. package/src/contracts/Channels/Calls.ts +1 -1
  352. package/src/contracts/Common/CoreTypes.ts +7 -0
  353. package/src/contracts/Common/index.ts +1 -1
  354. package/src/contracts/Configuration/Builders.ts +0 -1
  355. package/src/contracts/Configuration/Configs.ts +0 -1
  356. package/src/contracts/Configuration/InternalDefaults.ts +12 -0
  357. package/src/contracts/Configuration/Registration.ts +92 -48
  358. package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +44 -2
  359. package/src/contracts/Configuration/RegistrationBuilders.ts +77 -71
  360. package/src/contracts/Configuration/RegistrationTypes.ts +1 -5
  361. package/src/contracts/Configuration/RegistrationValidators.ts +19 -17
  362. package/src/contracts/Configuration/TimerRegistrationValidator.ts +4 -2
  363. package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +1 -0
  364. package/src/contracts/Handlers/JsonContract.ts +14 -4
  365. package/src/contracts/Locations/Authority.ts +7 -3
  366. package/src/contracts/Locations/Options.ts +1 -1
  367. package/src/contracts/Locations/Stores.ts +14 -0
  368. package/src/contracts/Spots/Contracts.ts +2 -2
  369. package/src/contracts/Streams/BoundSessionContracts.ts +1 -1
  370. package/src/contracts/Streams/IZLinkSession.ts +2 -3
  371. package/src/contracts/Streams/IZLinkSessionActor.ts +2 -6
  372. package/src/internal.ts +14 -0
  373. package/src/nest-integration.ts +28 -10
  374. package/src/runtime/abort.ts +6 -5
  375. package/src/runtime/activation-admission.ts +2 -8
  376. package/src/runtime/actors/actor-authority-payload-codec.ts +58 -20
  377. package/src/runtime/actors/actor-client.ts +85 -218
  378. package/src/runtime/actors/actor-context.ts +39 -33
  379. package/src/runtime/actors/actor-handoff.ts +24 -22
  380. package/src/runtime/actors/actor-lifecycle-snapshot.ts +2 -1
  381. package/src/runtime/actors/actor-local-native-join.ts +172 -174
  382. package/src/runtime/actors/actor-native-lookup.ts +2 -9
  383. package/src/runtime/actors/actor-packet-relay-wire.ts +18 -12
  384. package/src/runtime/actors/actor-remote-joiner.ts +9 -11
  385. package/src/runtime/actors/actor-remote-wire.ts +5 -3
  386. package/src/runtime/actors/actor-request-deadline.ts +4 -0
  387. package/src/runtime/actors/actor-retry-delay.ts +2 -1
  388. package/src/runtime/actors/actor-routed-join-transport.ts +3 -5
  389. package/src/runtime/actors/actor-runtime-state.ts +85 -247
  390. package/src/runtime/actors/bound-session-wire.ts +2 -8
  391. package/src/runtime/actors/deferred-join-completion.ts +10 -6
  392. package/src/runtime/actors/index.ts +100 -79
  393. package/src/runtime/actors/spot-actor-dispatch.ts +60 -29
  394. package/src/runtime/actors/transferred-actor-rollback.ts +11 -62
  395. package/src/runtime/admission.ts +8 -1
  396. package/src/runtime/application-jobs/application-job-queue-scope.ts +4 -4
  397. package/src/runtime/backend/contracts/index.ts +14 -37
  398. package/src/runtime/backend/mesh-actor-session-node-adapter.ts +2 -18
  399. package/src/runtime/backend/mesh-dispatch-pump.ts +111 -117
  400. package/src/runtime/backend/node/node-backend-adapter-support.ts +67 -10
  401. package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +0 -2
  402. package/src/runtime/backend/node/node-event-loop-poller.ts +8 -12
  403. package/src/runtime/backend/node/node-monitor-backend-adapter.ts +1 -0
  404. package/src/runtime/backend/node/node-raw-binding-port.ts +44 -49
  405. package/src/runtime/backend/node/node-raw-mesh-backend.ts +227 -170
  406. package/src/runtime/backend/node/node-socket-backend-adapter.ts +4 -3
  407. package/src/runtime/backend/raw-binding-port.ts +1 -1
  408. package/src/runtime/backend/runtime-values.ts +4 -1
  409. package/src/runtime/channels/channel-clients.ts +139 -102
  410. package/src/runtime/channels/channel-envelope-inspection.ts +2 -1
  411. package/src/runtime/channels/channel-envelope.ts +74 -57
  412. package/src/runtime/channels/channel-outbound-operations.ts +40 -55
  413. package/src/runtime/channels/channel-receive-loops.ts +39 -7
  414. package/src/runtime/channels/channel-runtime-lifecycle.ts +60 -27
  415. package/src/runtime/channels/channel-runtime-manager.ts +12 -30
  416. package/src/runtime/channels/channel-socket-options.ts +8 -15
  417. package/src/runtime/channels/channel-socket-registry.ts +291 -196
  418. package/src/runtime/channels/channel-transports.ts +168 -145
  419. package/src/runtime/channels/client-server-location-runtime.ts +17 -17
  420. package/src/runtime/channels/client-server-service-wire.ts +40 -12
  421. package/src/runtime/channels/dispatch-error-reporter.ts +7 -5
  422. package/src/runtime/channels/fanout-location-runtime.ts +172 -91
  423. package/src/runtime/channels/local-spot-route-transport.ts +1 -5
  424. package/src/runtime/channels/router-socket-spot-route-transport.ts +2 -6
  425. package/src/runtime/channels/source-spot-router.ts +2 -9
  426. package/src/runtime/channels/spot-direct-envelope.ts +1 -1
  427. package/src/runtime/channels/spot-node-route-transport.ts +7 -9
  428. package/src/runtime/channels/spot-route-bridge-transport.ts +5 -12
  429. package/src/runtime/channels/spot-route-dispatch-strategy.ts +11 -30
  430. package/src/runtime/diagnostics/diagnostic-text.ts +4 -0
  431. package/src/runtime/diagnostics/dispatch-error-details.ts +36 -1
  432. package/src/runtime/diagnostics/flow-context.ts +16 -2
  433. package/src/runtime/diagnostics/index.ts +27 -17
  434. package/src/runtime/diagnostics/message-flow.ts +15 -25
  435. package/src/runtime/diagnostics/runtime-metrics.ts +181 -113
  436. package/src/runtime/diagnostics/runtime-observation-queue.ts +3 -2
  437. package/src/runtime/diagnostics/topology-runtime-projections.ts +194 -162
  438. package/src/runtime/disposal.ts +19 -0
  439. package/src/runtime/execution/index.ts +60 -20
  440. package/src/runtime/execution/serial-execution-queue.ts +131 -18
  441. package/src/runtime/execution/state-lane.ts +142 -4
  442. package/src/runtime/foundation/actor-join-recovery-codec.ts +13 -8
  443. package/src/runtime/foundation/event-loop-resources.ts +5 -122
  444. package/src/runtime/foundation/operation-identity.ts +11 -5
  445. package/src/runtime/foundation/operation-registry.ts +33 -50
  446. package/src/runtime/foundation/raw-service-mesh-runtime.ts +127 -125
  447. package/src/runtime/foundation/runtime-state-projections.ts +9 -1
  448. package/src/runtime/foundation/service-authority-payload-codec.ts +31 -13
  449. package/src/runtime/foundation/service-discovery-registry.ts +32 -3
  450. package/src/runtime/foundation/service-instance-activation-recovery-codec.ts +12 -4
  451. package/src/runtime/foundation/service-liveness-registry.ts +2 -1
  452. package/src/runtime/foundation/service-maintenance-runtime.ts +0 -10
  453. package/src/runtime/foundation/service-metadata-codec.ts +2 -2
  454. package/src/runtime/foundation/service-relocation-aggregate-committer.ts +3 -66
  455. package/src/runtime/foundation/service-relocation-object-owner.ts +5 -2
  456. package/src/runtime/foundation/service-relocation-runtime.ts +57 -35
  457. package/src/runtime/foundation/service-runtime-contracts.ts +46 -10
  458. package/src/runtime/foundation/service-session-binding-ingress-port.ts +0 -17
  459. package/src/runtime/foundation/service-stateful-registry.ts +14 -2
  460. package/src/runtime/foundation/service-stateful-runtime.ts +322 -276
  461. package/src/runtime/foundation/service-stateful-wire-codec.ts +128 -80
  462. package/src/runtime/foundation/service-topology-registry.ts +23 -32
  463. package/src/runtime/foundation/service-wire-binary-primitives.ts +6 -0
  464. package/src/runtime/foundation/service-wire-codec.ts +15 -8
  465. package/src/runtime/foundation/service-wire-constants.generated.ts +1 -0
  466. package/src/runtime/foundation/service-wire-m6a-codec.ts +29 -15
  467. package/src/runtime/framework-errors-internal.ts +380 -134
  468. package/src/runtime/handlers/handler-instance-scope.ts +68 -95
  469. package/src/runtime/host/actor-packet-relay.ts +63 -160
  470. package/src/runtime/host/actor-placement-coordinator.ts +8 -5
  471. package/src/runtime/host/actor-runtime-options-factory.ts +27 -8
  472. package/src/runtime/host/actor-transfer-runtime.ts +180 -260
  473. package/src/runtime/host/application-job-queue.ts +28 -34
  474. package/src/runtime/host/bound-session-relay.ts +1 -2
  475. package/src/runtime/host/channel-runtime-options-factory.ts +1 -2
  476. package/src/runtime/host/index.ts +327 -320
  477. package/src/runtime/host/instance-activation-authority.ts +89 -109
  478. package/src/runtime/host/location-runtime-owner.ts +4 -2
  479. package/src/runtime/host/remote-actor-join-receiver.ts +3 -31
  480. package/src/runtime/host/remote-actor-packet-target-store.ts +17 -58
  481. package/src/runtime/host/remote-bound-session-relay.ts +16 -57
  482. package/src/runtime/host/route-mesh-runtime.ts +228 -271
  483. package/src/runtime/host/runtime-shutdown.ts +17 -21
  484. package/src/runtime/host/service-relocation-control.ts +14 -1
  485. package/src/runtime/host/service-relocation-host-runtime.ts +699 -561
  486. package/src/runtime/host/spot-address-transport.ts +175 -356
  487. package/src/runtime/host/spot-node-runtime-options-factory.ts +6 -3
  488. package/src/runtime/host/spot-runtime-options-factory.ts +73 -22
  489. package/src/runtime/host/user-spot-creation-coordinator.ts +36 -22
  490. package/src/runtime/locations/aggregate-inventory-store.ts +16 -13
  491. package/src/runtime/locations/authority-key-codec.ts +7 -3
  492. package/src/runtime/locations/auto-connect-reconciler.ts +39 -26
  493. package/src/runtime/locations/creation-operation-id.ts +6 -3
  494. package/src/runtime/locations/domain-store-contract.ts +12 -3
  495. package/src/runtime/locations/in-memory-authority-store.ts +44 -15
  496. package/src/runtime/locations/in-memory-location-store.ts +50 -39
  497. package/src/runtime/locations/in-memory-provider-location-store.ts +100 -25
  498. package/src/runtime/locations/key-codec.ts +3 -2
  499. package/src/runtime/locations/lease-tracker.ts +8 -14
  500. package/src/runtime/locations/lifecycle.ts +13 -43
  501. package/src/runtime/locations/location-store-failure.ts +4 -0
  502. package/src/runtime/locations/location-store-pages.ts +18 -0
  503. package/src/runtime/locations/location-store-repository.ts +457 -482
  504. package/src/runtime/locations/relocation-blob.ts +17 -6
  505. package/src/runtime/locations/resolvers.ts +75 -49
  506. package/src/runtime/locations/runtime.ts +220 -110
  507. package/src/runtime/locations/spot-location-claims.ts +58 -1
  508. package/src/runtime/messaging/payload-codec.ts +35 -24
  509. package/src/runtime/messaging/request-deadline.ts +58 -0
  510. package/src/runtime/messaging/submission-result.ts +72 -2
  511. package/src/runtime/protocol/service_wire_codec.generated.ts +18 -8
  512. package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +1 -1
  513. package/src/runtime/spots/formal-remote-actor-transfer-registry.ts +4 -1
  514. package/src/runtime/spots/index.ts +433 -229
  515. package/src/runtime/spots/spot-activation-registry.ts +30 -69
  516. package/src/runtime/spots/spot-activation-state.ts +2 -2
  517. package/src/runtime/spots/spot-activation.ts +67 -37
  518. package/src/runtime/spots/spot-actor-admission-coordinator.ts +5 -57
  519. package/src/runtime/spots/spot-actor-join-dispatch.ts +24 -77
  520. package/src/runtime/spots/spot-actor-membership.ts +40 -72
  521. package/src/runtime/spots/spot-actor-packet-dispatch.ts +0 -16
  522. package/src/runtime/spots/spot-actor-packet-relay-dispatch.ts +3 -15
  523. package/src/runtime/spots/spot-context.ts +3 -3
  524. package/src/runtime/spots/spot-entry-activation.ts +13 -30
  525. package/src/runtime/spots/spot-lifecycle-metrics.ts +3 -2
  526. package/src/runtime/spots/spot-manager-public.ts +21 -17
  527. package/src/runtime/spots/spot-node-autoconnect.ts +20 -26
  528. package/src/runtime/spots/spot-node-runtime-manager.ts +136 -125
  529. package/src/runtime/spots/spot-outbound.ts +59 -47
  530. package/src/runtime/spots/spot-remote-codec.ts +7 -3
  531. package/src/runtime/spots/spot-route-packet-dispatch.ts +25 -24
  532. package/src/runtime/spots/spot-route-replies.ts +6 -4
  533. package/src/runtime/spots/spot-routed-actor-admission.ts +13 -26
  534. package/src/runtime/spots/spot-routed-frame-dispatch.ts +2 -3
  535. package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +95 -22
  536. package/src/runtime/spots/spot-runtime-ports.ts +5 -27
  537. package/src/runtime/spots/spot-serial-executor.ts +2 -2
  538. package/src/runtime/spots/spot-serial-turn-executor.ts +112 -11
  539. package/src/runtime/spots/spot-timer.ts +3 -2
  540. package/src/runtime/streams/actor-session-binding-registry.ts +179 -269
  541. package/src/runtime/streams/actor-session-binding-runtime-owner.ts +0 -8
  542. package/src/runtime/streams/bound-actor-relay-sender.ts +98 -66
  543. package/src/runtime/streams/bound-session-service.ts +22 -2
  544. package/src/runtime/streams/index.ts +78 -68
  545. package/src/runtime/streams/managed-stream.ts +32 -23
  546. package/src/runtime/streams/native-fallback-bound-session.ts +14 -28
  547. package/src/runtime/streams/protocol.ts +34 -88
  548. package/src/runtime/streams/session-actor-coordinator.ts +17 -5
  549. package/src/runtime/streams/session-calls.ts +11 -36
  550. package/src/runtime/streams/session-context.ts +60 -25
  551. package/src/runtime/streams/session-requests.ts +2 -1
  552. package/src/runtime/streams/stream-binding-runtime-ports.ts +22 -1
  553. package/src/runtime/streams/stream-frame-factory.ts +2 -3
  554. package/src/runtime/streams/stream-session-runtime.ts +57 -59
  555. package/src/runtime/workers/index.ts +13 -12
  556. package/dist/runtime/actors/post-commit-actor-location.d.ts +0 -19
  557. package/dist/runtime/actors/post-commit-actor-location.js +0 -72
  558. package/dist/runtime/spots/spot-native-actor-join-admission.d.ts +0 -26
  559. package/dist/runtime/spots/spot-native-actor-join-admission.js +0 -106
  560. package/src/runtime/actors/post-commit-actor-location.ts +0 -121
  561. package/src/runtime/spots/spot-native-actor-join-admission.ts +0 -155
@@ -1,83 +1,79 @@
1
+ import { UINT64_MAX, ZlinkStreamContentType } from '@zlink-systems/stream-wire';
1
2
  import { randomBytes } from 'node:crypto';
2
- import { SubmitResult } from '../backend/runtime-values';
3
- import type {
4
- RoutingId,
5
- Type,
6
- ZLinkActor,
7
- ZLinkActorRelocationAdapter,
8
- ZLinkMeshNodeDescriptor,
9
- ZLinkSpot,
10
- ZLinkSpotRelocationAdapter,
11
- ZLinkInstanceSpot
12
- } from '../../contracts';
13
- import type {
14
- ZLinkAuthorityKey,
15
- ZLinkAuthorityScanCursor,
16
- ZLinkAuthoritySnapshot,
17
- ZLinkCapacityVector,
18
- ZLinkLocationOwnerToken
19
- } from '../locations/internal-location-contracts';
20
3
  import {
4
+ type RoutingId,
5
+ type Type,
6
+ type ZLinkActor,
7
+ type ZLinkActorRelocationAdapter,
8
+ type ZLinkInstanceSpot,
9
+ type ZLinkMeshNodeDescriptor,
10
+ type ZLinkSpot,
11
+ type ZLinkSpotRelocationAdapter,
21
12
  ZLinkFrameworkErrorKind,
22
13
  ZLinkFrameworkException,
23
14
  ZLinkFrameworkRuntimeState,
24
15
  ZLinkObjectRole,
16
+ ZLinkSpotKind,
25
17
  ZLinkSpotRelocationCoordinationMode,
26
18
  ZLinkSpotRelocationReadyOutcome,
27
- ZLinkSpotKind,
28
19
  ZLinkUserSpotExecutionMode
29
20
  } from '../../contracts';
30
- import { zlinkRuntimeDefaultLocationOptions } from '../../contracts/Locations/Options';
31
- import {
32
- ZLinkFrameworkInternalErrorKind,
33
- createInternalFrameworkException
34
- } from '../framework-errors-internal';
35
- import type { ZLinkDomainLocationStore as ZLinkLocationStore } from '../locations/domain-store-contract';
36
- import type { ZLinkTrackedInstanceAuthority } from '../locations/spot-location-claims';
21
+
37
22
  import type { ZLinkProviderResolver } from '../../contracts/Common/ZLinkProviderResolver';
38
- import type { ZLinkRuntimeEventPublisher, ZLinkRuntimeMetrics } from '../diagnostics';
23
+ import { zlinkRuntimeDefaultLocationOptions } from '../../contracts/Locations/Options';
24
+ import { ZLINK_PROVIDER_MAX_PAGE_SIZE } from '../../contracts/Locations/Stores';
39
25
  import type { ZLinkActivationAdmission } from '../activation-admission';
40
- import type { ZLinkFrameworkRegistration } from '../configuration';
26
+ import type { DefaultZLinkActorManager } from '../actors';
27
+ import {
28
+ decodeRelocatingActorAuthorityIdentity,
29
+ rewriteActorAuthorityRoute
30
+ } from '../actors/actor-authority-publication';
31
+ import {
32
+ replayActorHandoffBacklog,
33
+ type ZLinkActorHandoffPacket,
34
+ type ZLinkActorHandoffResult
35
+ } from '../actors/actor-handoff';
36
+ import type { ZLinkActorJoinRelocation } from '../actors/actor-join-relocation';
37
+ import {
38
+ ZLINK_REMOTE_ACTOR_SOURCE_LEAVE_TERMINAL,
39
+ decodeRemoteActorSourceLeaveTerminal
40
+ } from '../actors/actor-remote-wire';
41
+ import {
42
+ toFrameworkActorRef,
43
+ type ZLinkActorRuntimeState,
44
+ type ZLinkRemoteBoundSessionTarget
45
+ } from '../actors/actor-runtime-state';
41
46
  import type { ZLinkBackendMeshNode, ZLinkMeshCompletionTable } from '../backend';
42
- import { ReceiveKind, type ReceiveRecord } from '../foundation/service-runtime-contracts';
43
- import { decodeRoutingId, encodeRoutingIdStorageHex, routingIdsEqual } from '../routing-id';
44
- import { ServiceWireProtocolError } from '../foundation/service-wire-m6a-codec';
45
- import type { ServiceSpotMessageFollowSeal } from '../foundation/service-stateful-runtime';
47
+ import { RequestResult, SubmitResult } from '../backend/runtime-values';
48
+ import type { ZLinkFrameworkRegistration } from '../configuration';
46
49
  import {
47
- ServiceRelocationAuthorityPayloadCodec,
48
- crc32c,
49
- decodeServiceRelocationEnvelope,
50
- encodeServiceRelocationEnvelope,
51
- inventoryDigest,
52
- projectServiceRelocationAuthorityTargetReady,
53
- replaceServiceRelocationAuthorityApplicationPayload,
54
- serviceRelocationAuthorityApplicationPayload,
55
- serviceRelocationAuthoritySlotIdentity,
56
- type ServiceRelocationEnvelope,
57
- type ServiceRelocationMembership,
58
- type ServiceRelocationParticipant,
59
- type ServiceRelocationPublication,
60
- type ServiceRelocationQueuedMessage,
61
- type ServiceRelocationTimer
62
- } from '../foundation/service-relocation-runtime';
50
+ type ZLinkRuntimeEventPublisher,
51
+ type ZLinkRuntimeMetrics,
52
+ isRelocationDebugEnabled,
53
+ relocationDebug
54
+ } from '../diagnostics';
55
+
56
+ import { METRIC_NAMES, MILLISECONDS_PER_SECOND } from '../diagnostics/runtime-metrics';
57
+ import { isStructuralGuardEnabled, trackDiagnosticCompletion } from '../execution/state-lane';
63
58
  import {
64
- ZLinkRelocationInFlightBudget,
65
- ZLinkRelocationPayloadAssembly,
66
- effectiveActorJoinChunkLimitBytes,
67
- effectiveRelocationBudgetBytes,
68
- planRelocationChunks,
69
- relocationChunkAt
70
- } from './relocation-direct-transfer';
59
+ RECREATE_RELOCATION_CONTENT_TYPE,
60
+ SNAPSHOT_RELOCATION_CONTENT_TYPE,
61
+ decodeCanonicalActorJoinRecoverySavedWork,
62
+ encodeCanonicalActorJoinRecoverySavedWork,
63
+ type CanonicalActorJoinRecovery
64
+ } from '../foundation/actor-join-recovery-codec';
65
+ import { OPERATION_IDENTITY_BYTES } from '../foundation/operation-identity';
66
+ import { rewriteServiceAuthorityRoute } from '../foundation/service-authority-payload-codec';
67
+ import { ServiceMaintenanceRuntime } from '../foundation/service-maintenance-runtime';
71
68
  import {
72
- captureRelocationAdapterState,
73
- restoreRelocationAdapterState,
74
- type ZLinkRelocationStateAdapterLike
75
- } from './relocation-state-adapter';
69
+ ServiceRelocationAggregateCommitter,
70
+ type ServicePreparedRelocationAggregate,
71
+ type ServiceRelocationAggregatePlan
72
+ } from '../foundation/service-relocation-aggregate-committer';
76
73
  import {
77
74
  ServiceRelocationAuthorityError,
78
75
  ServiceRelocationPostCommitError
79
76
  } from '../foundation/service-relocation-coordinator';
80
- import { ServiceMaintenanceRuntime } from '../foundation/service-maintenance-runtime';
81
77
  import {
82
78
  ServiceRelocationObjectCaptureOwner,
83
79
  ServiceRelocationObjectRestoreOwner,
@@ -88,89 +84,125 @@ import {
88
84
  type ServiceRelocationTargetObjectPort
89
85
  } from '../foundation/service-relocation-object-owner';
90
86
  import {
91
- ServiceRelocationAggregateCommitter,
92
- type ServicePreparedRelocationAggregate,
93
- type ServiceRelocationAggregatePlan
94
- } from '../foundation/service-relocation-aggregate-committer';
95
- import { createProviderInstance } from '../spots/spot-provider';
96
- import type { DefaultZLinkSpotManager, ZLinkSpotNodeRuntimeManager } from '../spots';
97
- import type { ZLinkSpotActivation } from '../spots/spot-activation-state';
98
- import type { DefaultZLinkActorManager } from '../actors';
99
- import {
100
- toFrameworkActorRef,
101
- type ZLinkActorRuntimeState,
102
- type ZLinkRemoteBoundSessionTarget
103
- } from '../actors/actor-runtime-state';
104
- import {
105
- replayActorHandoffBacklog,
106
- type ZLinkActorHandoffPacket,
107
- type ZLinkActorHandoffResult
108
- } from '../actors/actor-handoff';
109
- import { decodeHandoffBacklog } from '../spots/spot-remote-codec';
110
- import {
111
- decodeRelocatingActorAuthorityIdentity,
112
- rewriteActorAuthorityRoute
113
- } from '../actors/actor-authority-publication';
114
- import { rewriteServiceAuthorityRoute } from '../foundation/service-authority-payload-codec';
115
- import { committedActorOwnerFence, type ZLinkActorTransferRuntime } from './actor-transfer-runtime';
116
- import { decodeAuthorityKey, encodeAuthorityKey } from '../locations/authority-key-codec';
87
+ ServiceRelocationAuthorityPayloadCodec,
88
+ crc32c,
89
+ decodeServiceRelocationEnvelope,
90
+ encodeServiceRelocationEnvelope,
91
+ inventoryDigest,
92
+ projectServiceRelocationAuthorityTargetReady,
93
+ replaceServiceRelocationAuthorityApplicationPayload,
94
+ serviceRelocationAuthorityApplicationPayload,
95
+ serviceRelocationAuthoritySlotIdentity,
96
+ type ServiceRelocationEnvelope,
97
+ type ServiceRelocationMembership,
98
+ type ServiceRelocationParticipant,
99
+ type ServiceRelocationPublication,
100
+ type ServiceRelocationQueuedMessage,
101
+ type ServiceRelocationTimer
102
+ } from '../foundation/service-relocation-runtime';
117
103
  import {
118
- decodeServiceRelocationControlRequest,
119
- decodeServiceRelocationControlResponse,
120
- encodeServiceRelocationControlRequest,
121
- encodeServiceRelocationControlResponse,
122
- type ZLinkServiceRelocationControlRequest,
123
- type ZLinkServiceRelocationControlResponse
124
- } from './service-relocation-control';
104
+ MeshPeerRuntimeState,
105
+ ReceiveKind,
106
+ type ReceiveRecord
107
+ } from '../foundation/service-runtime-contracts';
108
+ import type { ServiceSpotMessageFollowSeal } from '../foundation/service-stateful-runtime';
125
109
  import {
110
+ M6bServiceWireCommand,
126
111
  decodeMaintenanceReplyRelay,
127
112
  decodeMaintenanceReplyRelayAck,
113
+ decodeServiceWireFrozenRecord,
128
114
  decodeSessionRelocationRoute,
129
115
  decodeSessionRelocationSeal,
130
116
  decodeSessionRelocationSealed,
131
117
  encodeMaintenanceReplyRelay,
132
118
  encodeMaintenanceReplyRelayAck,
119
+ encodeServiceWireFrozenActorApplicationRecord,
133
120
  encodeSessionRelocationRoute,
134
121
  encodeSessionRelocationSeal,
135
122
  encodeSessionRelocationSealed,
136
123
  serviceSessionRelocationIdentityKey,
137
- decodeServiceWireFrozenRecord,
138
- encodeServiceWireFrozenActorApplicationRecord,
139
- M6bServiceWireCommand,
140
- type ServiceMaintenanceReplyRelay,
141
- type ServiceMaintenanceReplyRelayAck,
142
124
  type ServiceMaintenanceRelocationControl,
143
125
  type ServiceMaintenanceRelocationCutover,
144
126
  type ServiceMaintenanceRelocationData,
145
127
  type ServiceMaintenanceRelocationFailed,
146
- type ServiceMaintenanceRelocationReady,
147
128
  type ServiceMaintenanceRelocationPrepare,
129
+ type ServiceMaintenanceRelocationReady,
148
130
  type ServiceMaintenanceRelocationState,
131
+ type ServiceMaintenanceReplyRelay,
132
+ type ServiceMaintenanceReplyRelayAck,
149
133
  type ServiceSessionRelocationRoute,
150
134
  type ServiceSessionRelocationSeal,
151
135
  type ServiceSessionRelocationSealed,
152
136
  type ServiceWireOperationId,
153
- type ServiceWireRequestSourceFence,
154
- type ServiceWireRelocationTarget,
155
137
  type ServiceWireRelocationCoordinatorFence,
156
- type ServiceWireRelocationObject
138
+ type ServiceWireRelocationObject,
139
+ type ServiceWireRelocationTarget,
140
+ type ServiceWireRequestSourceFence
157
141
  } from '../foundation/service-stateful-wire-codec';
158
142
  import { ServiceWireFrameworkErrorCode } from '../foundation/service-wire-constants.generated';
143
+ import { ServiceWireProtocolError } from '../foundation/service-wire-m6a-codec';
144
+ import {
145
+ ZLinkFrameworkInternalErrorKind,
146
+ createInternalFrameworkException,
147
+ frameworkRelocationFailureCode,
148
+ internalFrameworkErrorKindFromWireFailureCode
149
+ } from '../framework-errors-internal';
150
+ import { decodeAuthorityKey, encodeAuthorityKey } from '../locations/authority-key-codec';
151
+ import { isIndeterminateLocationStoreFailure } from '../locations/location-store-failure';
152
+ import type { ZLinkDomainLocationStore as ZLinkLocationStore } from '../locations/domain-store-contract';
153
+ import type {
154
+ ZLinkAuthorityKey,
155
+ ZLinkAuthorityScanCursor,
156
+ ZLinkAuthoritySnapshot,
157
+ ZLinkCapacityVector,
158
+ ZLinkLocationOwnerToken
159
+ } from '../locations/internal-location-contracts';
160
+ import type { ZLinkTrackedInstanceAuthority } from '../locations/spot-location-claims';
161
+ import { decodeRoutingId, encodeRoutingIdStorageHex, routingIdsEqual } from '../routing-id';
162
+ import type { DefaultZLinkSpotManager, ZLinkSpotNodeRuntimeManager } from '../spots';
163
+ import type { ZLinkSpotActivation } from '../spots/spot-activation-state';
164
+ import { createProviderInstance } from '../spots/spot-provider';
165
+ import { decodeHandoffBacklog } from '../spots/spot-remote-codec';
166
+ import { committedActorOwnerFence, type ZLinkActorTransferRuntime } from './actor-transfer-runtime';
159
167
  import { BoundedReplayMap } from './bounded-replay-map';
160
- import type { ZLinkActorJoinRelocation } from '../actors/actor-join-relocation';
168
+ import {
169
+ ZLinkRelocationInFlightBudget,
170
+ ZLinkRelocationPayloadAssembly,
171
+ effectiveActorJoinChunkLimitBytes,
172
+ effectiveRelocationBudgetBytes,
173
+ planRelocationChunks,
174
+ relocationChunkAt
175
+ } from './relocation-direct-transfer';
161
176
  import {
162
177
  ZLINK_INTERNAL_RELOCATION_INTEGRITY_FAULT_GATE,
163
178
  type ZLinkInternalRelocationIntegrityFaultGate
164
179
  } from './relocation-integrity-fault-gate';
165
180
  import {
166
- decodeRemoteActorSourceLeaveTerminal,
167
- ZLINK_REMOTE_ACTOR_SOURCE_LEAVE_TERMINAL
168
- } from '../actors/actor-remote-wire';
181
+ captureRelocationAdapterState,
182
+ restoreRelocationAdapterState,
183
+ type ZLinkRelocationStateAdapterLike
184
+ } from './relocation-state-adapter';
169
185
  import {
170
- decodeCanonicalActorJoinRecoverySavedWork,
171
- encodeCanonicalActorJoinRecoverySavedWork,
172
- type CanonicalActorJoinRecovery
173
- } from '../foundation/actor-join-recovery-codec';
186
+ decodeServiceRelocationControlRequest,
187
+ decodeServiceRelocationControlResponse,
188
+ encodeServiceRelocationControlRequest,
189
+ encodeServiceRelocationControlResponse,
190
+ type ZLinkServiceRelocationControlRequest,
191
+ type ZLinkServiceRelocationControlResponse
192
+ } from './service-relocation-control';
193
+ const RELOCATION_ATTEMPT_TIMEOUT_MS = 250;
194
+
195
+ const RELOCATION_AUTHORITY_RETRY_DELAY_MS = 25;
196
+
197
+ const RELOCATION_MAX_SEND_ATTEMPTS = 120;
198
+
199
+ const RELOCATION_AUTHORITY_POLL_INTERVAL_MS = 10;
200
+
201
+ const RELOCATION_RESEND_DELAY_MS = 250;
202
+
203
+ const RELOCATION_ABORTABLE_OPERATION_TIMEOUT_MS = 24 * 60 * 60 * 1000;
204
+
205
+ const RELOCATION_OPERATION_TIMEOUT_MS = 30_000;
174
206
 
175
207
  export class ZLinkRelocationStateIncompatibleError extends Error {
176
208
  constructor(message: string) {
@@ -189,6 +221,7 @@ interface ZLinkHostRelocationOptions {
189
221
  readonly providerResolver?: ZLinkProviderResolver;
190
222
  readonly locationStore: () => ZLinkLocationStore | undefined;
191
223
  readonly currentOwner: () => ZLinkLocationOwnerToken | undefined;
224
+ readonly targetAdmissionSealed?: () => boolean;
192
225
  readonly liveDescriptors: (
193
226
  meshName: string,
194
227
  signal?: AbortSignal
@@ -307,7 +340,7 @@ interface SourceActorJoinProfile {
307
340
  Parameters<ZLinkActorJoinRelocation['relocateActorJoin']>[0]['canonicalRecovery']
308
341
  >;
309
342
  readonly ready: Promise<void>;
310
- readonly resolveReady: () => void;
343
+ readonly resolveReady: (failure?: ServiceRelocationPostCommitError) => void;
311
344
  }
312
345
 
313
346
  interface PendingRelocationReplyRelay {
@@ -366,8 +399,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
366
399
  * Terminal restore failures (assembly/checksum/factory/restore error): the
367
400
  * target already sent relocationFailed (command 53) once. An exact-identity
368
401
  * Prepare resend replays the stored response rather than retrying the
369
- * restore; a different exact identity reusing the same RelocationId+attempt
370
- * key supersedes the stale entry (spec 28 §3, §9).
402
+ * restore. A different exact identity never changes this entry (spec 28 §4.3).
371
403
  */
372
404
  private readonly targetReadyFailures = new Map<
373
405
  string,
@@ -424,9 +456,12 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
424
456
  );
425
457
  }
426
458
  this.reserveExactRelocationId(input.relocationId);
427
- let resolveReady!: () => void;
428
- const ready = new Promise<void>((resolve) => {
429
- resolveReady = resolve;
459
+ let resolveReady!: (failure?: ServiceRelocationPostCommitError) => void;
460
+ const ready = new Promise<void>((resolve, reject) => {
461
+ resolveReady = (failure) => {
462
+ if (failure === undefined) resolve();
463
+ else reject(failure.cause);
464
+ };
430
465
  });
431
466
  this.sourceActorJoinProfiles.set(input.relocationId, {
432
467
  actor: input.actor,
@@ -438,8 +473,8 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
438
473
  relocationContentType:
439
474
  this.actorRegistration(input.state.meshName ?? input.meshName, input.state.actorType ?? '')
440
475
  .relocation.kind === 'snapshot'
441
- ? 'application/vnd.zlink.actor-relocation.snapshot'
442
- : 'application/vnd.zlink.actor-relocation.recreate',
476
+ ? SNAPSHOT_RELOCATION_CONTENT_TYPE
477
+ : RECREATE_RELOCATION_CONTENT_TYPE,
443
478
  completionOperationId: input.completionOperationId,
444
479
  canonicalRecovery: input.canonicalRecovery,
445
480
  ready,
@@ -469,8 +504,13 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
469
504
  );
470
505
  resolveReady();
471
506
  } catch (error) {
472
- this.sourceActorJoinProfiles.delete(input.relocationId);
473
- throw error;
507
+ if (error instanceof ServiceRelocationPostCommitError) {
508
+ resolveReady(error);
509
+ this.completeActorJoinSourceCleanup(input.state.actorId);
510
+ } else {
511
+ this.sourceActorJoinProfiles.delete(input.relocationId);
512
+ throw error;
513
+ }
474
514
  }
475
515
  return {
476
516
  actorRef: {
@@ -486,17 +526,10 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
486
526
  async dispose(): Promise<void> {
487
527
  this.disposed = true;
488
528
  const errors: unknown[] = [];
489
- for (const stage of this.targetStages.values()) {
490
- if (stage.fallback !== undefined) clearTimeout(stage.fallback);
491
- try {
492
- if (stage.finalize !== undefined) {
493
- await stage.finalize;
494
- } else if (stage.phase === 'ready') {
495
- await this.abortTargetStage(stage);
496
- }
497
- } catch (error) {
498
- errors.push(error);
499
- }
529
+ try {
530
+ await this.drainTargetAttempts();
531
+ } catch (error) {
532
+ errors.push(error);
500
533
  }
501
534
  this.targetStages.clear();
502
535
  this.terminalTargets.clear();
@@ -534,24 +567,78 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
534
567
  if (errors.length > 1) throw new AggregateError(errors, 'Relocation runtime stop failed.');
535
568
  }
536
569
 
570
+ /** Host shutdown waits for the existing attempt terminal before releasing its lease. */
571
+ async drainTargetAttempts(): Promise<void> {
572
+ const results = await Promise.allSettled(
573
+ [...this.targetStages.entries()].map(([stagingId, stage]) => {
574
+ if (stage.fallback !== undefined) clearTimeout(stage.fallback);
575
+ return stage.lane.finally(() => {
576
+ if (stage.phase === 'failed') return stage.finalize;
577
+ if (this.targetStageSealed(stage)) {
578
+ const terminal = this.discardTargetStage(stagingId, stage);
579
+ stage.finalize = terminal;
580
+ return terminal;
581
+ }
582
+ return this.beginTargetFinalize(
583
+ stage.offer.reservation.prepared.plan.targetDescriptor.meshName,
584
+ stagingId,
585
+ stage
586
+ );
587
+ });
588
+ })
589
+ );
590
+ const errors = results.flatMap((result) =>
591
+ result.status === 'rejected' ? [result.reason as unknown] : []
592
+ );
593
+ if (errors.length === 1) throw errors[0];
594
+ if (errors.length > 1) throw new AggregateError(errors, 'Relocation target drain failed.');
595
+ }
596
+
597
+ /** Spec 28 §4.4: the target owner alone orders shutdown seal and verified cutover. */
598
+ private targetStageSealed(stage: LocalStage): boolean {
599
+ return (
600
+ !stage.cutoverReceived && (this.disposed || this.options.targetAdmissionSealed?.() === true)
601
+ );
602
+ }
603
+
537
604
  completeActorJoinSourceCleanup(actorId: string): void {
538
605
  for (const [relocationId, profile] of this.sourceActorJoinProfiles) {
539
606
  if (profile.state.actorId !== actorId) continue;
540
607
  this.sourceActorJoinProfiles.delete(relocationId);
541
608
  this.terminalActorJoinSourceLeaves.remember(relocationId, actorId);
542
- void profile.ready
543
- .then(async () => {
544
- await this.options.actorTransfer.completeRelocationSourceLeave(
545
- profile.actor,
546
- profile.sourceSpotId
547
- );
548
- await this.options
549
- .actorManager()
550
- ?.completeRelocationSource(actorId, profile.sourceActorRef);
551
- })
552
- .catch((error) => {
553
- console.error('[zlink.runtime.relocation.source_cleanup_failed]', error);
554
- });
609
+ void this.finalizeActorJoinSource(profile);
610
+ }
611
+ }
612
+
613
+ private async finalizeActorJoinSource(profile: SourceActorJoinProfile): Promise<void> {
614
+ const failures: unknown[] = [];
615
+ try {
616
+ await profile.ready;
617
+ } catch (error) {
618
+ failures.push(error);
619
+ }
620
+ try {
621
+ await this.options.actorTransfer.completeRelocationSourceLeave(
622
+ profile.actor,
623
+ profile.sourceSpotId
624
+ );
625
+ } catch (error) {
626
+ failures.push(error);
627
+ }
628
+ try {
629
+ await this.options
630
+ .actorManager()
631
+ ?.completeRelocationSource(profile.state.actorId, profile.sourceActorRef);
632
+ } catch (error) {
633
+ failures.push(error);
634
+ }
635
+ if (failures.length > 0) {
636
+ console.error(
637
+ '[zlink.runtime.relocation.source_cleanup_failed]',
638
+ failures.length === 1
639
+ ? failures[0]
640
+ : new AggregateError(failures, 'Actor source retirement failed.')
641
+ );
555
642
  }
556
643
  }
557
644
 
@@ -671,13 +758,19 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
671
758
  ready: () => true,
672
759
  relocate: (relocationSignal) => {
673
760
  const run = unit.relocate(relocationSignal);
761
+ if (isStructuralGuardEnabled()) {
762
+ trackDiagnosticCompletion(run, `relocation ${unit.id}`);
763
+ }
674
764
  started.push(run);
675
765
  return run;
676
766
  }
677
767
  });
678
768
  }
679
769
  const operationSignal = signal ?? new AbortController().signal;
680
- const deadlineMs = signal === undefined ? 30_000 : 24 * 60 * 60 * 1000;
770
+ const deadlineMs =
771
+ signal === undefined
772
+ ? RELOCATION_OPERATION_TIMEOUT_MS
773
+ : RELOCATION_ABORTABLE_OPERATION_TIMEOUT_MS;
681
774
  let failure: unknown;
682
775
  try {
683
776
  const result = await raceAbort(
@@ -798,47 +891,57 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
798
891
  }
799
892
  const operationKey = relocationStagingId(request);
800
893
  const fingerprint = stringifyWire(request);
894
+ const readyFailure = this.targetReadyFailures.get(operationKey);
895
+ const readyPending = this.targetReadyResponses.get(operationKey);
896
+ let operation = this.targetPrepareOperations.get(operationKey);
897
+ const acceptedFingerprint =
898
+ readyFailure?.fingerprint ??
899
+ readyPending?.fingerprint ??
900
+ operation?.fingerprint ??
901
+ this.targetAssemblies.get(operationKey)?.fingerprint ??
902
+ this.targetStages.get(operationKey)?.offer.prepareFingerprint ??
903
+ this.terminalTargets.get(operationKey);
904
+ if (request.sourceNodeRid !== String(record.sourceNodeRid)) return true;
905
+ if (acceptedFingerprint !== undefined && acceptedFingerprint !== fingerprint) {
906
+ if (!samePrepareIdentity(acceptedFingerprint, request)) return true;
907
+ this.replyPrepare(
908
+ record,
909
+ relocationFailed(request, ServiceWireFrameworkErrorCode.relocationDataLost)
910
+ );
911
+ return true;
912
+ }
801
913
  // A restore that failed outright is terminal: the source observes the
802
914
  // same explicit relocationFailed on every identical Prepare resend
803
- // rather than a silent stall. A different exact identity reusing the
804
- // same RelocationId+attempt key supersedes the stale failure — the
805
- // newer attempt wins (spec 28 §3).
806
- const readyFailure = this.targetReadyFailures.get(operationKey);
915
+ // rather than a silent stall.
807
916
  if (readyFailure !== undefined) {
808
- if (readyFailure.fingerprint === fingerprint) {
809
- this.replyPrepare(record, readyFailure.response);
810
- return true;
811
- }
812
- this.targetReadyFailures.delete(operationKey);
917
+ this.replyPrepare(record, readyFailure.response);
918
+ return true;
813
919
  }
814
920
  // Spec 28: an exact-identity Restore resend against staging that
815
921
  // already restored successfully reuses that staging — it re-submits
816
922
  // READY rather than restarting the restore.
817
- const readyPending = this.targetReadyResponses.get(operationKey);
818
923
  if (readyPending !== undefined) {
819
- if (readyPending.fingerprint !== fingerprint) {
820
- throw new Error(`Relocation '${operationKey}' repeated Prepare with different bytes.`);
821
- }
822
924
  this.submitTargetReady(meshName, operationKey, record, readyPending.response);
823
925
  return true;
824
926
  }
825
- let operation = this.targetPrepareOperations.get(operationKey);
826
- if (operation !== undefined && operation.fingerprint !== fingerprint) {
827
- throw new Error(`Relocation '${operationKey}' repeated Prepare with different bytes.`);
828
- }
829
927
  if (operation === undefined) {
830
928
  // The prepare turn must not block the ordered dispatch lane: the
831
929
  // payload chunks that complete this operation arrive as later records
832
930
  // on the same connection. Register the assembly synchronously, then
833
931
  // finish the restore and the Ready reply asynchronously.
834
- this.registerTargetAssembly(operationKey, request, String(record.sourceNodeRid));
835
- const promise = this.handlePrepareControl(
836
- meshName,
837
- operationKey,
838
- request,
839
- record.sourceNodeRid,
840
- signal
841
- );
932
+ let promise: Promise<ServiceMaintenanceRelocationReady>;
933
+ try {
934
+ this.registerTargetAssembly(operationKey, request, String(record.sourceNodeRid));
935
+ promise = this.handlePrepareControl(
936
+ meshName,
937
+ operationKey,
938
+ request,
939
+ record.sourceNodeRid,
940
+ signal
941
+ );
942
+ } catch (error) {
943
+ promise = Promise.reject(error);
944
+ }
842
945
  operation = { fingerprint, promise };
843
946
  this.targetPrepareOperations.set(operationKey, operation);
844
947
  void promise
@@ -872,10 +975,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
872
975
  // restore or staging): this is terminal. Send relocationFailed
873
976
  // (command 53) once and remember it so an identical Prepare resend
874
977
  // replays the same response instead of retrying the restore.
875
- const failed = relocationFailed(
876
- request,
877
- relocationFailedFailureCode(error, request.object.kind)
878
- );
978
+ const failed = relocationFailed(request, relocationFailedFailureCode(error));
879
979
  this.targetReadyFailures.set(operationKey, {
880
980
  fingerprint: stringifyWire(request),
881
981
  response: failed
@@ -969,7 +1069,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
969
1069
  String(sourceNodeRid) !== pending.authenticatedSourceNodeRid ||
970
1070
  request.senderRole !== 'source' ||
971
1071
  !sameCoordinator(request.coordinator, pending.prepare.coordinator) ||
972
- stringifyWire(request.object) !== stringifyWire(pending.prepare.object)
1072
+ !sameRelocationObject(request.object, pending.prepare.object)
973
1073
  ) {
974
1074
  // Spec 28 §4.3 — a chunk with a different exact identity is never
975
1075
  // attached to an in-progress assembly; it is discarded.
@@ -993,14 +1093,6 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
993
1093
  ): TargetPayloadAssembly {
994
1094
  const existing = this.targetAssemblies.get(operationKey);
995
1095
  if (existing !== undefined) {
996
- if (existing.fingerprint !== stringifyWire(request)) {
997
- // Same exact identity with a different declared length or checksum is
998
- // an explicit conflict failure; the existing assembly is neither
999
- // reused nor overwritten (spec 28 §4.3).
1000
- throw existing.assembly.fail(
1001
- `Relocation '${operationKey}' repeated Prepare with a conflicting manifest.`
1002
- );
1003
- }
1004
1096
  return existing;
1005
1097
  }
1006
1098
  const pending: TargetPayloadAssembly = {
@@ -1015,15 +1107,10 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
1015
1107
  };
1016
1108
  this.targetAssemblies.set(operationKey, pending);
1017
1109
  if (this.relocationIntegrityFaultGate()?.consumeIdentityConflict() === true) {
1018
- // Route a same-identity, different-manifest delivery through the normal
1019
- // conflict branch so existing staging is neither reused nor overwritten.
1020
- return this.registerTargetAssembly(
1021
- operationKey,
1022
- {
1023
- ...request,
1024
- payloadChecksumCrc32c: request.payloadChecksumCrc32c ^ 1
1025
- },
1026
- authenticatedSourceNodeRid
1110
+ throw new ServiceRelocationDataLostError(
1111
+ pending.assembly.fail(
1112
+ `Relocation '${operationKey}' repeated Prepare with a conflicting manifest.`
1113
+ ).message
1027
1114
  );
1028
1115
  }
1029
1116
  return pending;
@@ -1201,7 +1288,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
1201
1288
  return;
1202
1289
  }
1203
1290
  if (this.pendingSessionRelocations.get(key) === pending) {
1204
- pending.retryTimer = setTimeout(() => void send(), 250);
1291
+ pending.retryTimer = setTimeout(() => void send(), RELOCATION_RESEND_DELAY_MS);
1205
1292
  }
1206
1293
  } catch (error) {
1207
1294
  pending.reject(
@@ -1420,7 +1507,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
1420
1507
  targetApplicationVersion: bigint | undefined,
1421
1508
  signal?: AbortSignal
1422
1509
  ): Promise<void> {
1423
- await activation.serial.executeLifecycleOperation(() =>
1510
+ await activation.serial.executeControlLifecycleOperation(() =>
1424
1511
  this.relocateSpotAggregateCore(
1425
1512
  meshName,
1426
1513
  activation,
@@ -1537,47 +1624,72 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
1537
1624
  captureApplicationState: (captureSignal) =>
1538
1625
  this.captureApplication(spotRegistration.relocation, activation.spot, captureSignal),
1539
1626
  commitSeal: async () => {
1540
- if (!spotSealCommitted) {
1541
- if (spotCapture === undefined || !(await activation.commitRelocation(spotCapture))) {
1542
- throw new Error(`Spot '${String(activation.spotId)}' relocation seal became stale.`);
1627
+ const failures: unknown[] = [];
1628
+ try {
1629
+ if (!spotSealCommitted) {
1630
+ if (spotCapture === undefined || !(await activation.commitRelocation(spotCapture))) {
1631
+ throw new Error(`Spot '${String(activation.spotId)}' relocation seal became stale.`);
1632
+ }
1633
+ spotSealCommitted = true;
1543
1634
  }
1544
- spotSealCommitted = true;
1545
- }
1546
- if (spotMessageFollowSeal !== undefined) {
1547
- await this.commitSpotMessageFollow(
1548
- meshName,
1549
- spotMessageFollowSeal,
1550
- spotKey,
1551
- activation,
1552
- target
1553
- );
1635
+ if (spotMessageFollowSeal !== undefined) {
1636
+ await this.commitSpotMessageFollow(
1637
+ meshName,
1638
+ spotMessageFollowSeal,
1639
+ spotKey,
1640
+ activation,
1641
+ target
1642
+ );
1643
+ }
1644
+ } catch (error) {
1645
+ failures.push(error);
1554
1646
  }
1555
1647
  for (const session of sessions) {
1556
- const committedAuthority = await requireAuthority(
1557
- this.requireLocationStore(),
1558
- encodeAuthorityKey('actor', session.state.actorId)
1559
- );
1560
- const targetActorRef = {
1561
- actorId: session.state.actorId,
1562
- objectGeneration: actorAuthorities.get(session.state.actorId)!.objectGeneration,
1563
- meshName,
1564
- nodeRid: target.rid
1565
- };
1566
- await session.prepared.commit(
1567
- {
1568
- routerChannelId: meshName,
1569
- targetNodeRid: target.rid,
1570
- spotId: activation.spotId,
1571
- spotKind: kind === 'user_spot' ? ZLinkSpotKind.User : ZLinkSpotKind.Instance,
1572
- authorityOwnerGeneration: committedAuthority.authorityOwnerGeneration
1573
- } as never,
1574
- targetActorRef,
1575
- committedActorOwnerFence(session.state.actorId, targetActorRef, committedAuthority)
1576
- );
1577
- activation.commitActorDeparture(session.state.actorId);
1578
- await this.requireActorManager().completeRelocationSource(session.state.actorId);
1648
+ try {
1649
+ const committedAuthority = await requireAuthority(
1650
+ this.requireLocationStore(),
1651
+ encodeAuthorityKey('actor', session.state.actorId)
1652
+ );
1653
+ const targetActorRef = {
1654
+ actorId: session.state.actorId,
1655
+ objectGeneration: actorAuthorities.get(session.state.actorId)!.objectGeneration,
1656
+ meshName,
1657
+ nodeRid: target.rid
1658
+ };
1659
+ await session.prepared.commit(
1660
+ {
1661
+ routerChannelId: meshName,
1662
+ targetNodeRid: target.rid,
1663
+ spotId: activation.spotId,
1664
+ spotKind: kind === 'user_spot' ? ZLinkSpotKind.User : ZLinkSpotKind.Instance,
1665
+ authorityOwnerGeneration: committedAuthority.authorityOwnerGeneration
1666
+ } as never,
1667
+ targetActorRef,
1668
+ committedActorOwnerFence(session.state.actorId, targetActorRef, committedAuthority)
1669
+ );
1670
+ } catch (error) {
1671
+ failures.push(error);
1672
+ }
1673
+ try {
1674
+ activation.commitActorDeparture(session.state.actorId);
1675
+ } catch (error) {
1676
+ failures.push(error);
1677
+ }
1678
+ try {
1679
+ await this.requireActorManager().completeRelocationSource(session.state.actorId);
1680
+ } catch (error) {
1681
+ failures.push(error);
1682
+ }
1579
1683
  }
1580
- await this.requireSpotManager().completeRelocationSource(activation);
1684
+ try {
1685
+ await this.requireSpotManager().completeRelocationSource(activation);
1686
+ } catch (error) {
1687
+ failures.push(error);
1688
+ }
1689
+ if (failures.length > 0)
1690
+ throw failures.length === 1
1691
+ ? failures[0]
1692
+ : new AggregateError(failures, 'Spot source retirement failed.');
1581
1693
  },
1582
1694
  abortSeal: async () => {
1583
1695
  const failures: unknown[] = [];
@@ -1723,7 +1835,9 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
1723
1835
  /** Target's advertised relocation state chunk cap (Actor Join only; spec 15 §4.2). */
1724
1836
  advertisedReceiveChunkLimitBytes?: number
1725
1837
  ): Promise<void> {
1726
- relocationDebug('standalone_actor.begin', { actorId: state.actorId });
1838
+ if (isRelocationDebugEnabled()) {
1839
+ relocationDebug('standalone_actor.begin', { actorId: state.actorId });
1840
+ }
1727
1841
  const authority = await requireAuthority(
1728
1842
  this.requireLocationStore(),
1729
1843
  encodeAuthorityKey('actor', state.actorId),
@@ -1780,12 +1894,16 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
1780
1894
  };
1781
1895
  let outcome = 'completed';
1782
1896
  try {
1783
- relocationDebug('standalone_actor.wait_budget', {
1784
- actorId: state.actorId,
1785
- targetRid: String(target.rid)
1786
- });
1897
+ if (isRelocationDebugEnabled()) {
1898
+ relocationDebug('standalone_actor.wait_budget', {
1899
+ actorId: state.actorId,
1900
+ targetRid: String(target.rid)
1901
+ });
1902
+ }
1787
1903
  await this.waitForRelocationBudgetHeadroom(String(target.rid), signal);
1788
- relocationDebug('standalone_actor.capture_begin', { actorId: state.actorId });
1904
+ if (isRelocationDebugEnabled()) {
1905
+ relocationDebug('standalone_actor.capture_begin', { actorId: state.actorId });
1906
+ }
1789
1907
  const captured = await new ServiceRelocationObjectCaptureOwner().captureStandaloneActor(
1790
1908
  aggregateId,
1791
1909
  1n,
@@ -1793,7 +1911,9 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
1793
1911
  membership,
1794
1912
  signal
1795
1913
  );
1796
- relocationDebug('standalone_actor.capture_complete', { actorId: state.actorId });
1914
+ if (isRelocationDebugEnabled()) {
1915
+ relocationDebug('standalone_actor.capture_complete', { actorId: state.actorId });
1916
+ }
1797
1917
  await this.runCoordinator(
1798
1918
  meshName,
1799
1919
  target,
@@ -1828,7 +1948,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
1828
1948
  targetApplicationVersion: bigint | undefined,
1829
1949
  signal?: AbortSignal
1830
1950
  ): Promise<void> {
1831
- await activation.serial.executeLifecycleOperation(() =>
1951
+ await activation.serial.executeControlLifecycleOperation(() =>
1832
1952
  this.relocatePerActorSpotShellCore(
1833
1953
  meshName,
1834
1954
  activation,
@@ -2026,32 +2146,45 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
2026
2146
  meshName === undefined
2027
2147
  )
2028
2148
  return;
2029
- const membershipSpotId =
2030
- targetMembership?.spotId ?? ((target.entrySpotId ?? String(target.rid)) as RoutingId);
2031
- const committedAuthority = await requireAuthority(
2032
- this.requireLocationStore(),
2033
- encodeAuthorityKey('actor', state.actorId)
2034
- );
2035
- const targetActorRef = {
2036
- actorId: state.actorId,
2037
- objectGeneration: authority.objectGeneration,
2038
- meshName,
2039
- nodeRid: target.rid
2040
- };
2041
- await ownSession.prepared.commit(
2042
- {
2043
- routerChannelId: meshName,
2044
- targetNodeRid: target.rid,
2045
- spotId: membershipSpotId,
2046
- spotKind: targetMembership?.spotKind ?? ZLinkSpotKind.Entry,
2047
- authorityOwnerGeneration: committedAuthority.authorityOwnerGeneration
2048
- } as never,
2049
- targetActorRef,
2050
- committedActorOwnerFence(state.actorId, targetActorRef, committedAuthority)
2051
- );
2149
+ const failures: unknown[] = [];
2150
+ try {
2151
+ const membershipSpotId =
2152
+ targetMembership?.spotId ?? ((target.entrySpotId ?? String(target.rid)) as RoutingId);
2153
+ const committedAuthority = await requireAuthority(
2154
+ this.requireLocationStore(),
2155
+ encodeAuthorityKey('actor', state.actorId)
2156
+ );
2157
+ const targetActorRef = {
2158
+ actorId: state.actorId,
2159
+ objectGeneration: authority.objectGeneration,
2160
+ meshName,
2161
+ nodeRid: target.rid
2162
+ };
2163
+ await ownSession.prepared.commit(
2164
+ {
2165
+ routerChannelId: meshName,
2166
+ targetNodeRid: target.rid,
2167
+ spotId: membershipSpotId,
2168
+ spotKind: targetMembership?.spotKind ?? ZLinkSpotKind.Entry,
2169
+ authorityOwnerGeneration: committedAuthority.authorityOwnerGeneration
2170
+ } as never,
2171
+ targetActorRef,
2172
+ committedActorOwnerFence(state.actorId, targetActorRef, committedAuthority)
2173
+ );
2174
+ } catch (error) {
2175
+ failures.push(error);
2176
+ }
2052
2177
  if (!retainSourceForActorJoin) {
2053
- await this.requireActorManager().completeRelocationSource(state.actorId);
2178
+ try {
2179
+ await this.requireActorManager().completeRelocationSource(state.actorId);
2180
+ } catch (error) {
2181
+ failures.push(error);
2182
+ }
2054
2183
  }
2184
+ if (failures.length > 0)
2185
+ throw failures.length === 1
2186
+ ? failures[0]
2187
+ : new AggregateError(failures, 'Actor source retirement failed.');
2055
2188
  },
2056
2189
  abortSeal: async () => {
2057
2190
  if (standalone && ownSession !== undefined) await ownSession.prepared.rollback();
@@ -2098,13 +2231,17 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
2098
2231
  /** Target's advertised relocation state chunk cap (Actor Join only; spec 15 §4.2). */
2099
2232
  advertisedReceiveChunkLimitBytes?: number
2100
2233
  ): Promise<void> {
2101
- relocationDebug('coordinator.begin', {
2102
- aggregateId: captured.envelope.aggregateId,
2103
- targetRid: String(target.rid)
2104
- });
2234
+ if (isRelocationDebugEnabled()) {
2235
+ relocationDebug('coordinator.begin', {
2236
+ aggregateId: captured.envelope.aggregateId,
2237
+ targetRid: String(target.rid)
2238
+ });
2239
+ }
2105
2240
  const localStatus = this.requireMeshNode(meshName).status();
2106
2241
  const controlDeadlineAtMs =
2107
- signal === undefined ? performance.now() + 30_000 : Number.MAX_SAFE_INTEGER;
2242
+ signal === undefined
2243
+ ? performance.now() + RELOCATION_OPERATION_TIMEOUT_MS
2244
+ : Number.MAX_SAFE_INTEGER;
2108
2245
  const coordinator = {
2109
2246
  ownerId: primary.ownerId,
2110
2247
  leaseGeneration: primary.ownerLeaseGeneration,
@@ -2169,7 +2306,6 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
2169
2306
  signal?.aborted === true || performance.now() >= controlDeadlineAtMs;
2170
2307
  let readyReceived = false;
2171
2308
  let settlement: 'target' | 'source' | 'lost' | undefined;
2172
- let sourceCommitted = false;
2173
2309
  try {
2174
2310
  const prepare = {
2175
2311
  kind: 'prepare',
@@ -2199,17 +2335,25 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
2199
2335
  encodePrepareSideband(captured.envelope)
2200
2336
  );
2201
2337
  try {
2202
- relocationDebug('coordinator.state_transfer_begin', {
2203
- aggregateId: captured.envelope.aggregateId
2204
- });
2338
+ if (isRelocationDebugEnabled()) {
2339
+ relocationDebug('coordinator.state_transfer_begin', {
2340
+ aggregateId: captured.envelope.aggregateId
2341
+ });
2342
+ }
2205
2343
  await this.sendRelocationStateChunks(meshName, target, prepare, encoded, plan, signal);
2206
2344
  } catch (chunkError) {
2207
2345
  readyOperation.catch(() => undefined);
2208
2346
  throw chunkError;
2209
2347
  }
2210
- relocationDebug('coordinator.await_ready', { aggregateId: captured.envelope.aggregateId });
2348
+ if (isRelocationDebugEnabled()) {
2349
+ relocationDebug('coordinator.await_ready', { aggregateId: captured.envelope.aggregateId });
2350
+ }
2211
2351
  const ready = await readyOperation;
2212
- relocationDebug('coordinator.ready_received', { aggregateId: captured.envelope.aggregateId });
2352
+ if (isRelocationDebugEnabled()) {
2353
+ relocationDebug('coordinator.ready_received', {
2354
+ aggregateId: captured.envelope.aggregateId
2355
+ });
2356
+ }
2213
2357
  validateControlResponse(prepare, ready);
2214
2358
  // Ready arms the target's cutover-wait fallback. From this point
2215
2359
  // forward the source can no longer reopen dispatch without risking two
@@ -2298,10 +2442,12 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
2298
2442
  } finally {
2299
2443
  this.closeSourceCutoverWindow(relayAuthorityId, window);
2300
2444
  }
2301
- relocationDebug('coordinator.authority_settled', {
2302
- aggregateId: captured.envelope.aggregateId,
2303
- settlement
2304
- });
2445
+ if (isRelocationDebugEnabled()) {
2446
+ relocationDebug('coordinator.authority_settled', {
2447
+ aggregateId: captured.envelope.aggregateId,
2448
+ settlement
2449
+ });
2450
+ }
2305
2451
  if (settlement === 'source') {
2306
2452
  // Preserve won: the captured queue, timers and held records return to
2307
2453
  // the source queue in their accepted order, and dispatch reopens.
@@ -2323,17 +2469,11 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
2323
2469
  }
2324
2470
  for (const session of sessions) session.prepared.setReplayResults([]);
2325
2471
  await captured.commitSource();
2326
- sourceCommitted = true;
2327
2472
  await this.options.reconcileStatefulAuthorityRoutes?.(signal);
2328
2473
  } catch (error) {
2329
2474
  if (settlement !== 'target') throw error;
2330
2475
  // Target commit is confirmed; later source cleanup failures cannot move
2331
- // the authority back (spec 28 §9).
2332
- if (!sourceCommitted) {
2333
- for (const session of sessions) session.prepared.setReplayResults([]);
2334
- await captured.commitSource().catch(() => undefined);
2335
- }
2336
- await this.options.reconcileStatefulAuthorityRoutes?.().catch(() => undefined);
2476
+ // the authority back (spec 28 §10).
2337
2477
  const authority = await requireAuthority(
2338
2478
  this.requireLocationStore(),
2339
2479
  { value: primaryKey(captured.envelope) } as ZLinkAuthorityKey,
@@ -2476,8 +2616,8 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
2476
2616
  // S1→S4 route convergence: the span the source must keep its Message
2477
2617
  // Follow route (spec 30 §7.1).
2478
2618
  this.options.metrics?.duration(
2479
- 'zlink.relocation.route_convergence',
2480
- Math.max(0, performance.now() - submittedAt) / 1000,
2619
+ METRIC_NAMES.RelocationRouteConvergence,
2620
+ Math.max(0, performance.now() - submittedAt) / MILLISECONDS_PER_SECOND,
2481
2621
  { mesh_name: meshName }
2482
2622
  );
2483
2623
  this.releaseSourceCutoverWindow(relocationKey, window);
@@ -2516,8 +2656,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
2516
2656
  (value) =>
2517
2657
  value.routingId !== null && String(value.routingId) === String(window.targetNodeRid)
2518
2658
  );
2519
- // Backend peer state 3 is Ready.
2520
- if (peer !== undefined && peer.state !== 3) {
2659
+ if (peer !== undefined && peer.state !== MeshPeerRuntimeState.Serving) {
2521
2660
  window.resendPending = true;
2522
2661
  return;
2523
2662
  }
@@ -2561,13 +2700,22 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
2561
2700
  if (this.disposed) throw new Error('Relocation runtime stopped.');
2562
2701
  await this.resendSourceCutover(window);
2563
2702
  const observed = await this.readSourceSettlement(envelope, primary, target).catch(
2564
- () => undefined
2703
+ (error: unknown) => {
2704
+ if (!isIndeterminateLocationStoreFailure(error)) throw error;
2705
+ return undefined;
2706
+ }
2565
2707
  );
2566
2708
  if (observed?.kind === 'target') return 'target';
2567
2709
  if (observed?.kind === 'other') return 'lost';
2568
2710
  if (restoreDeadlineReached() && observed?.kind === 'source') {
2569
2711
  // An unreadable lease is an uncertain result, not an expiry.
2570
- if (await this.exactSourceLeaseExpired(owner).catch(() => false)) return 'lost';
2712
+ if (
2713
+ await this.exactSourceLeaseExpired(owner).catch((error: unknown) => {
2714
+ if (!isIndeterminateLocationStoreFailure(error)) throw error;
2715
+ return false;
2716
+ })
2717
+ )
2718
+ return 'lost';
2571
2719
  const publication = this.codec.read(observed.current.payload);
2572
2720
  const preserved = await store
2573
2721
  .compareExchangeAuthority(
@@ -2582,11 +2730,16 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
2582
2730
  : this.codec.clear(observed.current.payload, publication.reference)
2583
2731
  }
2584
2732
  )
2585
- .catch(() => undefined);
2733
+ .catch((error: unknown) => {
2734
+ if (!isIndeterminateLocationStoreFailure(error)) throw error;
2735
+ return undefined;
2736
+ });
2586
2737
  if (preserved?.kind === 'stored') return 'source';
2587
2738
  }
2588
2739
  // The caller awaits this settlement, so the retry timer keeps the loop alive.
2589
- await new Promise<void>((resolve) => setTimeout(resolve, 10));
2740
+ await new Promise<void>((resolve) =>
2741
+ setTimeout(resolve, RELOCATION_AUTHORITY_POLL_INTERVAL_MS)
2742
+ );
2590
2743
  }
2591
2744
  }
2592
2745
 
@@ -2667,14 +2820,9 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
2667
2820
  meshName: string,
2668
2821
  stagingId: string,
2669
2822
  request: ServiceMaintenanceRelocationPrepare,
2670
- sourceNodeRid: RoutingId | null,
2823
+ sourceNodeRid: RoutingId,
2671
2824
  signal?: AbortSignal
2672
2825
  ): Promise<ServiceMaintenanceRelocationReady> {
2673
- if (sourceNodeRid === null || String(sourceNodeRid) !== request.sourceNodeRid) {
2674
- throw new Error(
2675
- 'Relocation prepare source node fence does not match the authenticated peer.'
2676
- );
2677
- }
2678
2826
  const targetStatus = this.requireMeshNode(meshName).status();
2679
2827
  const targetOwner = this.options.currentOwner();
2680
2828
  const targetDescriptor = this.options.localDescriptor?.(meshName);
@@ -2692,24 +2840,15 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
2692
2840
  const fingerprint = stringifyWire(request);
2693
2841
  const existing = this.targetStages.get(stagingId);
2694
2842
  if (existing !== undefined) {
2695
- if (
2696
- existing.offer.authenticatedSourceNodeRid !== String(sourceNodeRid) ||
2697
- existing.offer.prepareFingerprint !== fingerprint
2698
- ) {
2699
- throw new Error('Relocation prepare retry source node changed.');
2700
- }
2701
2843
  return relocationReady(request);
2702
2844
  }
2703
2845
  const terminal = this.terminalTargets.get(stagingId);
2704
2846
  if (terminal !== undefined) {
2705
- if (terminal !== fingerprint) {
2706
- throw new Error(`Relocation '${stagingId}' repeated Prepare with different bytes.`);
2707
- }
2708
2847
  this.terminalTargets.touch(stagingId);
2709
2848
  return relocationReady(request);
2710
2849
  }
2711
2850
  const pendingAssembly = this.targetAssemblies.get(stagingId);
2712
- if (pendingAssembly === undefined || pendingAssembly.fingerprint !== fingerprint) {
2851
+ if (pendingAssembly === undefined) {
2713
2852
  throw new Error(`Relocation '${stagingId}' has no matching payload assembly.`);
2714
2853
  }
2715
2854
  // The directly transferred payload replaces the shared durable root: the
@@ -2798,7 +2937,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
2798
2937
  stage.fallback = setTimeout(() => {
2799
2938
  if (stage.finalize !== undefined) return;
2800
2939
  console.warn('[zlink.runtime.relocation.cutover_timeout]', stagingId);
2801
- this.options.metrics?.count('zlink.relocation.cutover_timeout', 1, {
2940
+ this.options.metrics?.count(METRIC_NAMES.RelocationCutoverTimeout, 1, {
2802
2941
  mesh_name: meshName
2803
2942
  });
2804
2943
  void this.beginTargetFinalize(meshName, stagingId, stage).catch((error) =>
@@ -2820,7 +2959,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
2820
2959
  const stagingId = relocationStagingId(request);
2821
2960
  const stage = this.targetStages.get(stagingId);
2822
2961
  if (stage === undefined) {
2823
- if (this.terminalTargets.get(stagingId) !== undefined) {
2962
+ if (this.disposed || this.terminalTargets.get(stagingId) !== undefined) {
2824
2963
  if (request.kind === 'cutover') {
2825
2964
  console.warn('[zlink.runtime.relocation.late_cutover]', stagingId);
2826
2965
  }
@@ -2829,21 +2968,24 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
2829
2968
  throw new Error(`Relocation staging '${stagingId}' is missing.`);
2830
2969
  }
2831
2970
  validateTargetOneWayControl(stage, request, sourceNodeRid);
2832
- // A verified cutover closes the boundary batch. A later record or cutover
2833
- // is a duplicate retransmission and never changes the staged batch.
2834
- if (stage.cutoverReceived || (stage.phase !== 'ready' && stage.phase !== 'finalizing')) {
2835
- if (request.kind === 'cutover') {
2836
- console.warn('[zlink.runtime.relocation.late_cutover]', stagingId);
2971
+ stage.lane = stage.lane.then(() => {
2972
+ // A verified cutover closes the boundary batch. A later record or cutover
2973
+ // is a duplicate retransmission and never changes the staged batch.
2974
+ if (stage.cutoverReceived || (stage.phase !== 'ready' && stage.phase !== 'finalizing')) {
2975
+ if (request.kind === 'cutover') {
2976
+ console.warn('[zlink.runtime.relocation.late_cutover]', stagingId);
2977
+ }
2978
+ return;
2837
2979
  }
2838
- return;
2839
- }
2840
- if (request.kind === 'data') {
2841
- stage.lane = stage.lane.then(() => this.stageBoundaryRelay(stage, request));
2842
- await stage.lane;
2843
- return;
2844
- }
2845
- this.reconcileBoundaryRelay(stage, request, stagingId);
2846
- stage.cutoverReceived = true;
2980
+ if (request.kind === 'data') {
2981
+ return this.stageBoundaryRelay(stage, request);
2982
+ }
2983
+ if (this.targetStageSealed(stage)) return;
2984
+ this.reconcileBoundaryRelay(stage, request, stagingId);
2985
+ stage.cutoverReceived = true;
2986
+ });
2987
+ await stage.lane;
2988
+ if (request.kind === 'data') return;
2847
2989
  // A settlement started by the cutover wait Warning is still reading the
2848
2990
  // Store; it submits the CAS on its next round now that cutover verified.
2849
2991
  if (stage.finalize !== undefined) return;
@@ -2928,10 +3070,9 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
2928
3070
  try {
2929
3071
  authority = await this.commitTargetReservation(stage, stage.offer.reservation, signal);
2930
3072
  if (authority === undefined) {
2931
- // Source Preserve, a definitive conflict or the target lease ended
2932
- // this staging before any target commit (Location runtime §10).
2933
- console.warn('[zlink.runtime.relocation.target_staging_discarded]', stagingId);
2934
- throw new Error(`Relocation '${stagingId}' target staging lost the authority settlement.`);
3073
+ // The seal owner may have ended staging while a Store read was pending.
3074
+ if ((stage as LocalStage).phase === 'failed') return;
3075
+ return this.discardTargetStage(stagingId, stage, signal);
2935
3076
  }
2936
3077
  authorityCommitted = true;
2937
3078
  stage.releaseActivation();
@@ -2964,8 +3105,8 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
2964
3105
  await stage.owner.openAdmission(stage.staging, signal);
2965
3106
  // S2→S3: owner confirmation to application dispatch opening.
2966
3107
  this.options.metrics?.duration(
2967
- 'zlink.relocation.target_resume',
2968
- Math.max(0, performance.now() - resumeStartedAt) / 1000,
3108
+ METRIC_NAMES.RelocationTargetResume,
3109
+ Math.max(0, performance.now() - resumeStartedAt) / MILLISECONDS_PER_SECOND,
2969
3110
  { mesh_name: meshName }
2970
3111
  );
2971
3112
  await this.publishSessionRoutes(stage.staging);
@@ -2980,14 +3121,15 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
2980
3121
  this.targetStages.delete(stagingId);
2981
3122
  this.targetAssemblies.delete(stagingId);
2982
3123
  } catch (error) {
2983
- stage.phase = 'failed';
2984
3124
  this.terminalTargets.remember(stagingId, stage.offer.prepareFingerprint);
2985
3125
  this.targetStages.delete(stagingId);
2986
3126
  this.targetAssemblies.delete(stagingId);
2987
3127
  if (!authorityCommitted) {
2988
- await this.abortTargetStage(stage).catch(() => undefined);
3128
+ // abortTargetStage may already have assigned failed before throwing.
3129
+ if ((stage as LocalStage).phase !== 'failed') await this.abortTargetStage(stage);
2989
3130
  throw error;
2990
3131
  }
3132
+ stage.phase = 'failed';
2991
3133
  if (authority !== undefined) {
2992
3134
  throw new ServiceRelocationPostCommitError(authority, stage.staging, error);
2993
3135
  }
@@ -3123,19 +3265,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
3123
3265
  }
3124
3266
  this.sourceActorJoinProfiles.delete(input.transferId);
3125
3267
  this.terminalActorJoinSourceLeaves.remember(input.transferId, input.actorId);
3126
- void profile.ready
3127
- .then(async () => {
3128
- await this.options.actorTransfer.completeRelocationSourceLeave(
3129
- profile.actor,
3130
- profile.sourceSpotId
3131
- );
3132
- await this.options
3133
- .actorManager()
3134
- ?.completeRelocationSource(input.actorId, profile.sourceActorRef);
3135
- })
3136
- .catch((error) => {
3137
- console.error('[zlink.runtime.relocation.source_leave_failed]', error);
3138
- });
3268
+ void this.finalizeActorJoinSource(profile);
3139
3269
  return true;
3140
3270
  }
3141
3271
 
@@ -3309,7 +3439,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
3309
3439
  pending.resolve('sourceLeaseExpired');
3310
3440
  return;
3311
3441
  }
3312
- if (++attempts > 120) {
3442
+ if (++attempts > RELOCATION_MAX_SEND_ATTEMPTS) {
3313
3443
  pending.reject(new Error(`Relocation reply relay ACK '${key}' timed out.`));
3314
3444
  return;
3315
3445
  }
@@ -3319,7 +3449,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
3319
3449
  encodeMaintenanceReplyRelay(request)
3320
3450
  );
3321
3451
  if (this.pendingReplyRelays.get(key) === pending) {
3322
- pending.timer = setTimeout(() => void send(), 250);
3452
+ pending.timer = setTimeout(() => void send(), RELOCATION_RESEND_DELAY_MS);
3323
3453
  }
3324
3454
  } catch (error) {
3325
3455
  pending.reject(error);
@@ -3464,10 +3594,14 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
3464
3594
  private async publishSessionRoutes(
3465
3595
  staging: ServiceObjectRelocationStaging<LocalHidden>
3466
3596
  ): Promise<void> {
3467
- for (const hidden of staging.hidden.values()) {
3468
- if (hidden.actor !== undefined) {
3469
- await this.options.actorTransfer.publishRoutedActorOwnership(hidden.actor);
3470
- }
3597
+ for (const [key, hidden] of staging.hidden) {
3598
+ if (hidden.actor === undefined) continue;
3599
+ // The Session seal travels with the relocation envelope, not the Actor.
3600
+ const carried = staging.envelope.participants.find((value) => value.key === key);
3601
+ await this.options.actorTransfer.publishRoutedActorOwnership(
3602
+ hidden.actor,
3603
+ carried === undefined ? undefined : decodeActorSession(carried.boundSessionState)
3604
+ );
3471
3605
  }
3472
3606
  }
3473
3607
 
@@ -3476,7 +3610,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
3476
3610
  targetNodeRid: RoutingId,
3477
3611
  request: ZLinkServiceRelocationControlRequest,
3478
3612
  signal?: AbortSignal,
3479
- deadlineAtMs = performance.now() + 30_000,
3613
+ deadlineAtMs: number = performance.now() + RELOCATION_OPERATION_TIMEOUT_MS,
3480
3614
  sideband: readonly Uint8Array[] = []
3481
3615
  ): Promise<ReturnType<typeof decodeServiceRelocationControlResponse>> {
3482
3616
  const key = controlAckKey(request);
@@ -3496,7 +3630,10 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
3496
3630
  lastRequestError
3497
3631
  );
3498
3632
  }
3499
- const attemptTimeoutMs = Math.max(1, Math.min(250, Math.ceil(remainingMs)));
3633
+ const attemptTimeoutMs = Math.max(
3634
+ 1,
3635
+ Math.min(RELOCATION_ATTEMPT_TIMEOUT_MS, Math.ceil(remainingMs))
3636
+ );
3500
3637
  const startedAtMs = performance.now();
3501
3638
  try {
3502
3639
  const replyFrames = await this.requestInfrastructureControl(
@@ -3522,11 +3659,13 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
3522
3659
  throw error;
3523
3660
  }
3524
3661
  lastRequestError = error;
3525
- relocationDebug('control.request_retry', {
3526
- key,
3527
- kind: request.kind,
3528
- targetRid: String(targetNodeRid)
3529
- });
3662
+ if (isRelocationDebugEnabled()) {
3663
+ relocationDebug('control.request_retry', {
3664
+ key,
3665
+ kind: request.kind,
3666
+ targetRid: String(targetNodeRid)
3667
+ });
3668
+ }
3530
3669
  const retryDelayMs = Math.min(
3531
3670
  Math.max(0, attemptTimeoutMs - (performance.now() - startedAtMs)),
3532
3671
  Math.max(0, deadlineAtMs - performance.now())
@@ -3566,7 +3705,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
3566
3705
  peer.routingId !== null &&
3567
3706
  String(peer.routingId) === String(descriptor.rid) &&
3568
3707
  peer.lifecycleGeneration === descriptor.lifecycleGeneration &&
3569
- peer.state === 3
3708
+ peer.state === MeshPeerRuntimeState.Serving
3570
3709
  ) &&
3571
3710
  relocationTargetSupports(descriptor, requirements)
3572
3711
  )
@@ -3801,6 +3940,22 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
3801
3940
  }
3802
3941
  }
3803
3942
 
3943
+ private async discardTargetStage(
3944
+ stagingId: string,
3945
+ stage: LocalStage,
3946
+ signal?: AbortSignal
3947
+ ): Promise<void> {
3948
+ stage.phase = 'failed';
3949
+ console.warn('[zlink.runtime.relocation.target_staging_discarded]', stagingId);
3950
+ try {
3951
+ await this.abortTargetStage(stage, signal);
3952
+ } finally {
3953
+ this.terminalTargets.remember(stagingId, stage.offer.prepareFingerprint);
3954
+ this.targetStages.delete(stagingId);
3955
+ this.targetAssemblies.delete(stagingId);
3956
+ }
3957
+ }
3958
+
3804
3959
  private async commitTargetReservation(
3805
3960
  stage: LocalStage,
3806
3961
  reservation: TargetRelocationReservation,
@@ -3827,8 +3982,9 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
3827
3982
  ): Promise<ZLinkAuthoritySnapshot | undefined> {
3828
3983
  const target = stage.offer.prepare.target;
3829
3984
  for (;;) {
3985
+ if (stage.phase === 'failed') return undefined;
3830
3986
  signal?.throwIfAborted();
3831
- if (this.disposed) throw new Error('Relocation runtime stopped.');
3987
+ if (this.targetStageSealed(stage)) return undefined;
3832
3988
  let conflict = false;
3833
3989
  if (stage.cutoverReceived) {
3834
3990
  // The boundary relay span is applied to the temporary queue before
@@ -3840,13 +3996,17 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
3840
3996
  // A thrown provider call has an unknown result; the read below decides.
3841
3997
  const result = await this.requireLocationStore()
3842
3998
  .commitAggregate(prepared.fence, signal)
3843
- .catch(() => undefined);
3999
+ .catch((error: unknown) => {
4000
+ if (!isIndeterminateLocationStoreFailure(error, signal)) throw error;
4001
+ return undefined;
4002
+ });
3844
4003
  if (result?.kind === 'generationExhausted') {
3845
4004
  throw new Error('location_update_failed: relocation aggregate commit exhausted.');
3846
4005
  }
3847
4006
  conflict = result?.kind === 'stale';
3848
4007
  }
3849
4008
  const observed = await this.readAggregateForCommitRetry(prepared, signal);
4009
+ if ((stage as LocalStage).phase === 'failed') return undefined;
3850
4010
  if (observed.kind === 'committed') {
3851
4011
  const primary = observed.authorities.get(stage.staging.primaryAuthorityKey.value);
3852
4012
  if (primary === undefined) {
@@ -3860,11 +4020,14 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
3860
4020
  await this.exactSourceLeaseExpired(
3861
4021
  { ownerId: target.ownerId, leaseGeneration: target.ownerLeaseGeneration },
3862
4022
  signal
3863
- ).catch(() => false)
4023
+ ).catch((error: unknown) => {
4024
+ if (!isIndeterminateLocationStoreFailure(error, signal)) throw error;
4025
+ return false;
4026
+ })
3864
4027
  ) {
3865
4028
  return undefined;
3866
4029
  }
3867
- await waitForRelocationRetry(25, signal);
4030
+ await waitForRelocationRetry(RELOCATION_AUTHORITY_RETRY_DELAY_MS, signal);
3868
4031
  }
3869
4032
  }
3870
4033
 
@@ -3906,7 +4069,8 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
3906
4069
  return { kind: 'stale' };
3907
4070
  }
3908
4071
  }
3909
- } catch {
4072
+ } catch (error) {
4073
+ if (!isIndeterminateLocationStoreFailure(error, signal)) throw error;
3910
4074
  return { kind: 'unknown' };
3911
4075
  }
3912
4076
  if (committed === prepared.plan.participants.length) {
@@ -3958,7 +4122,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
3958
4122
  if (request.object.kind === 'userSpot' || request.object.kind === 'instanceSpot') {
3959
4123
  let cursor: ZLinkAuthorityScanCursor | undefined;
3960
4124
  for (;;) {
3961
- const page = await store.listAuthorities('', cursor, 1000, signal);
4125
+ const page = await store.listAuthorities('', cursor, ZLINK_PROVIDER_MAX_PAGE_SIZE, signal);
3962
4126
  if (page.kind === 'scanExpired') {
3963
4127
  throw new Error('Location Store authority scan expired during relocation.');
3964
4128
  }
@@ -4103,7 +4267,7 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
4103
4267
  );
4104
4268
  if (captured.byteLength > RELOCATION_PARTICIPANT_STATE_LIMIT_BYTES) {
4105
4269
  throw new ZLinkRelocationStateIncompatibleError(
4106
- 'Relocation application state exceeds the 64 MiB participant limit.'
4270
+ `Relocation application state exceeds the ${RELOCATION_PARTICIPANT_STATE_LIMIT_BYTES / (1024 * 1024)} MiB participant limit.`
4107
4271
  );
4108
4272
  }
4109
4273
  return captured;
@@ -4124,13 +4288,13 @@ export class ZLinkHostServiceRelocationRuntime implements ZLinkActorJoinRelocati
4124
4288
  startedAt: number,
4125
4289
  outcome: string
4126
4290
  ): void {
4127
- const seconds = Math.max(0, performance.now() - startedAt) / 1000;
4291
+ const seconds = Math.max(0, performance.now() - startedAt) / MILLISECONDS_PER_SECOND;
4128
4292
  const attributes = {
4129
4293
  unit_kind: unitKind,
4130
4294
  ...(executionMode === undefined ? {} : { execution_mode: executionMode })
4131
4295
  };
4132
- this.options.metrics?.duration('zlink.relocation.interruption', seconds, attributes);
4133
- this.options.metrics?.count('zlink.relocation.completed', 1, {
4296
+ this.options.metrics?.duration(METRIC_NAMES.RelocationInterruption, seconds, attributes);
4297
+ this.options.metrics?.count(METRIC_NAMES.RelocationCompleted, 1, {
4134
4298
  mesh_name: meshName,
4135
4299
  object_kind: unitKind,
4136
4300
  policy: unitKind === 'user_spot' && executionMode === 'per_actor' ? 'recreate' : 'configured',
@@ -4388,11 +4552,6 @@ function actorJoinTargetMembership(
4388
4552
  ];
4389
4553
  }
4390
4554
 
4391
- function relocationDebug(marker: string, detail: Record<string, unknown>): void {
4392
- if (process.env.ZLINK_DEBUG_FRAMEWORK_RELOCATION !== '1') return;
4393
- console.error('[zlink.runtime.relocation]', marker, detail);
4394
- }
4395
-
4396
4555
  class LocalTargetPort implements ServiceRelocationTargetObjectPort<LocalHidden> {
4397
4556
  constructor(
4398
4557
  private readonly options: ZLinkHostRelocationOptions,
@@ -4421,8 +4580,8 @@ class LocalTargetPort implements ServiceRelocationTargetObjectPort<LocalHidden>
4421
4580
  participant.stableType,
4422
4581
  participant.objectGeneration,
4423
4582
  participant.authorityOwnerGeneration + 1n,
4424
- (nativeEntrySpot ? localDescriptor.rid : spotIdentity) as RoutingId,
4425
- nativeEntrySpot ? localDescriptor.lifecycleGeneration : membership.spotObjectGeneration,
4583
+ nativeEntrySpot ? undefined : (spotIdentity as RoutingId),
4584
+ membership.spotObjectGeneration,
4426
4585
  membership.membershipEpoch,
4427
4586
  signal
4428
4587
  );
@@ -4562,11 +4721,22 @@ class LocalTargetPort implements ServiceRelocationTargetObjectPort<LocalHidden>
4562
4721
  hidden.participant.objectKind === 'user_spot' &&
4563
4722
  registration.options?.relocationCoordinationMode ===
4564
4723
  ZLinkSpotRelocationCoordinationMode.ApplicationSignaled;
4724
+ // createHidden could only predict the owner generation; the native Spot
4725
+ // takes the committed authority, as the Actor branch does above.
4726
+ const node = this.options.meshNode(this.meshName);
4727
+ node?.restoreSpotAuthority?.(
4728
+ String(hidden.activation.spotId),
4729
+ // createHidden stages an activation only for a Spot participant.
4730
+ hidden.participant.objectKind as 'user_spot' | 'instance_spot',
4731
+ hidden.participant.stableType,
4732
+ authority.objectGeneration,
4733
+ authority.authorityOwnerGeneration
4734
+ );
4565
4735
  await this.requireSpotManager().publishRelocationSpot(
4566
4736
  hidden.activation,
4567
4737
  applicationSignaled ? () => hidden.activation!.notifyRelocatedBoundary() : undefined
4568
4738
  );
4569
- this.options.meshNode(this.meshName)?.rememberSpotRoute?.({
4739
+ node?.rememberSpotRoute?.({
4570
4740
  spot: {
4571
4741
  spotId: String(hidden.activation.spotId),
4572
4742
  generation: authority.objectGeneration
@@ -4597,14 +4767,13 @@ class LocalTargetPort implements ServiceRelocationTargetObjectPort<LocalHidden>
4597
4767
  }
4598
4768
 
4599
4769
  async restoreBoundSession(hidden: LocalHidden, payload: Uint8Array): Promise<void> {
4600
- if (hidden.actor === undefined || payload.byteLength === 0) return;
4601
- const target = decodeActorSession(payload);
4602
- const state = this.requireActorManager().getState(hidden.actor.context.actorId)!;
4603
- state.setRemoteBoundSessionTarget(target);
4604
- state.setBoundSessionTransferTarget(target);
4605
- if (target.bindingGeneration !== undefined) {
4606
- state.setBoundSessionBindingGeneration(target.bindingGeneration);
4607
- }
4770
+ const carried = decodeActorSession(payload);
4771
+ if (hidden.actor === undefined || carried === undefined) return;
4772
+ // The relocation delivers the binding it carried; the target installs it
4773
+ // through the one install rule (Session–Actor binding §6, §8).
4774
+ this.requireActorManager()
4775
+ .getState(hidden.actor.context.actorId)!
4776
+ .installBoundSessionBinding(carried);
4608
4777
  }
4609
4778
 
4610
4779
  async replayQueuedMessage(
@@ -5060,9 +5229,11 @@ export function createServiceRelocationId(
5060
5229
  entropy: (size: number) => Uint8Array = randomBytes
5061
5230
  ): string {
5062
5231
  for (;;) {
5063
- const bytes = entropy(16);
5064
- if (bytes.byteLength !== 16) {
5065
- throw new Error('Relocation identity entropy must return exactly 16 bytes.');
5232
+ const bytes = entropy(OPERATION_IDENTITY_BYTES);
5233
+ if (bytes.byteLength !== OPERATION_IDENTITY_BYTES) {
5234
+ throw new Error(
5235
+ `Relocation identity entropy must return exactly ${OPERATION_IDENTITY_BYTES} bytes.`
5236
+ );
5066
5237
  }
5067
5238
  let nonZero = false;
5068
5239
  for (const byte of bytes) {
@@ -5103,13 +5274,52 @@ function sameCoordinator(
5103
5274
  ): boolean {
5104
5275
  return (
5105
5276
  left.ownerId === right.ownerId &&
5106
- left.leaseGeneration === right.leaseGeneration &&
5277
+ BigInt(left.leaseGeneration) === right.leaseGeneration &&
5107
5278
  left.nodeRid === right.nodeRid &&
5108
- left.nodeGeneration === right.nodeGeneration &&
5279
+ BigInt(left.nodeGeneration) === right.nodeGeneration &&
5109
5280
  left.expectedAuthorityStoreVersion === right.expectedAuthorityStoreVersion
5110
5281
  );
5111
5282
  }
5112
5283
 
5284
+ function sameRelocationTarget(
5285
+ left: ServiceWireRelocationTarget,
5286
+ right: ServiceWireRelocationTarget
5287
+ ): boolean {
5288
+ return (
5289
+ left.nodeRid === right.nodeRid &&
5290
+ BigInt(left.nodeGeneration) === right.nodeGeneration &&
5291
+ left.ownerId === right.ownerId &&
5292
+ BigInt(left.ownerLeaseGeneration) === right.ownerLeaseGeneration
5293
+ );
5294
+ }
5295
+
5296
+ function sameRelocationObject(
5297
+ left: ServiceWireRelocationObject,
5298
+ right: ServiceWireRelocationObject
5299
+ ): boolean {
5300
+ if (left.kind !== right.kind || BigInt(left.objectGeneration) !== right.objectGeneration) {
5301
+ return false;
5302
+ }
5303
+ if (left.kind === 'actor' && right.kind === 'actor') {
5304
+ return (
5305
+ left.actorId === right.actorId &&
5306
+ BigInt(left.expectedAuthorityOwnerGeneration) === right.expectedAuthorityOwnerGeneration
5307
+ );
5308
+ }
5309
+ if (left.kind === 'userSpot' && right.kind === 'userSpot') {
5310
+ return (
5311
+ left.spotId === right.spotId &&
5312
+ BigInt(left.expectedAuthorityOwnerGeneration) === right.expectedAuthorityOwnerGeneration
5313
+ );
5314
+ }
5315
+ return (
5316
+ left.kind === 'instanceSpot' &&
5317
+ right.kind === 'instanceSpot' &&
5318
+ left.spotId === right.spotId &&
5319
+ left.stableType === right.stableType
5320
+ );
5321
+ }
5322
+
5113
5323
  function isExactSourceAuthority(
5114
5324
  current: ZLinkAuthoritySnapshot,
5115
5325
  expected: ZLinkAuthoritySnapshot
@@ -5206,14 +5416,16 @@ function maintenanceReplyRelay(
5206
5416
  replyRouteId: BigInt(completion.source.replyRouteId),
5207
5417
  participantId,
5208
5418
  sequence: BigInt(completion.index + 1),
5209
- terminalResult: completion.result.ok ? 0 : 105,
5210
- failureCode: completion.result.ok ? 0 : 17,
5419
+ terminalResult: completion.result.ok ? RequestResult.Ok : RequestResult.InternalError,
5420
+ failureCode: completion.result.ok
5421
+ ? ServiceWireFrameworkErrorCode.none
5422
+ : ServiceWireFrameworkErrorCode.requestFailed,
5211
5423
  ...(value === undefined
5212
5424
  ? {}
5213
5425
  : {
5214
5426
  payload: {
5215
- packetName: 'zlink.relocation.reply',
5216
- contentType: 'application/json',
5427
+ packetName: SERVICE_RELOCATION_REPLY_PACKET_NAME,
5428
+ contentType: ZlinkStreamContentType.Json,
5217
5429
  bytes: Buffer.from(JSON.stringify(value), 'utf8')
5218
5430
  }
5219
5431
  })
@@ -5227,16 +5439,16 @@ function handoffResultFromRelay(relay: ServiceMaintenanceReplyRelay): ZLinkActor
5227
5439
  let value: unknown;
5228
5440
  if (relay.payload !== undefined) {
5229
5441
  if (
5230
- relay.terminalResult !== 0 ||
5231
- relay.payload.packetName !== 'zlink.relocation.reply' ||
5232
- relay.payload.contentType !== 'application/json'
5442
+ relay.terminalResult !== RequestResult.Ok ||
5443
+ relay.payload.packetName !== SERVICE_RELOCATION_REPLY_PACKET_NAME ||
5444
+ relay.payload.contentType !== ZlinkStreamContentType.Json
5233
5445
  ) {
5234
5446
  throw new TypeError('Relocation terminal payload boundary is invalid.');
5235
5447
  }
5236
5448
  value = JSON.parse(Buffer.from(relay.payload.bytes).toString('utf8')) as unknown;
5237
5449
  }
5238
5450
  const index = Number(relay.sequence - 1n);
5239
- return relay.terminalResult === 0
5451
+ return relay.terminalResult === RequestResult.Ok
5240
5452
  ? { index, ok: true, ...(value === undefined ? {} : { response: value }) }
5241
5453
  : { index, ok: false, error: `Actor handoff failed with framework code ${relay.failureCode}.` };
5242
5454
  }
@@ -5252,76 +5464,15 @@ function wireIdText(value: { readonly high: bigint; readonly low: bigint }): str
5252
5464
  */
5253
5465
  export class ServiceRelocationDataLostError extends Error {}
5254
5466
 
5255
- /**
5256
- * Maps a target-side relocation Prepare failure to the closest wire
5257
- * framework-error code the generated schema
5258
- * ({@link ServiceWireFrameworkErrorCode}) defines — mirrors the java
5259
- * reference mapping (commit 97fc074058) and the dotnet/cpp ports. The wire
5260
- * vocabulary predates the framework's typed error kinds and has no
5261
- * one-to-one code for every kind, so several kinds share the nearest fit
5262
- * (documented per case below); unresolvable vocabulary gaps belong at the
5263
- * schema level, not invented here. {@link ServiceRelocationDataLostError}
5264
- * is this runtime's dedicated tag for a verified checksum/assembly/digest
5265
- * integrity failure — the case that keeps relocationDataLost(35). An
5266
- * unclassified error carries no evidence of integrity loss and takes the
5267
- * generic opaque requestFailed(17). `objectKind` (the Prepare's
5268
- * ObjectFence.kind, spec 28 §4.2) picks between an Actor- and
5269
- * Spot-specific code where the schema splits by object kind.
5270
- */
5271
- export function relocationFailedFailureCode(
5272
- error: unknown,
5273
- objectKind: ServiceWireRelocationObject['kind']
5274
- ): number {
5467
+ /** Classifies relocation failure with the error model §2.1 mapping. */
5468
+ export function relocationFailedFailureCode(error: unknown): number {
5275
5469
  if (error instanceof ServiceRelocationDataLostError) {
5276
- return ServiceWireFrameworkErrorCode.relocationDataLost;
5470
+ return frameworkRelocationFailureCode(ZLinkFrameworkErrorKind.DataLost);
5277
5471
  }
5278
5472
  if (!(error instanceof ZLinkFrameworkException)) {
5279
- return ServiceWireFrameworkErrorCode.requestFailed;
5280
- }
5281
- switch (error.kind) {
5282
- case ZLinkFrameworkErrorKind.DataLost:
5283
- return ServiceWireFrameworkErrorCode.relocationDataLost;
5284
- case ZLinkFrameworkErrorKind.Rejected:
5285
- return ServiceWireFrameworkErrorCode.requestRejected;
5286
- case ZLinkFrameworkErrorKind.ProtocolError:
5287
- return ServiceWireFrameworkErrorCode.requestProtocolError;
5288
- // No dedicated "deadline exceeded" wire code exists; a worker timeout
5289
- // is the closest timeout-shaped signal.
5290
- case ZLinkFrameworkErrorKind.DeadlineExceeded:
5291
- return ServiceWireFrameworkErrorCode.workerTimedOut;
5292
- // A stale generation/fence is the concrete cause of InvalidOperation
5293
- // along this path (spec 15 failure table); pick the
5294
- // object-kind-specific stale code.
5295
- case ZLinkFrameworkErrorKind.InvalidOperation:
5296
- return objectKind === 'actor'
5297
- ? ServiceWireFrameworkErrorCode.actorLocationStale
5298
- : ServiceWireFrameworkErrorCode.spotGenerationStale;
5299
- // No dedicated generic "unavailable" wire code exists; a disconnected
5300
- // route is the closest "cannot reach/use the target" signal.
5301
- case ZLinkFrameworkErrorKind.Unavailable:
5302
- return ServiceWireFrameworkErrorCode.routeNotConnected;
5303
- case ZLinkFrameworkErrorKind.NotFound:
5304
- return ServiceWireFrameworkErrorCode.requestTargetNotFound;
5305
- // The only "already exists" wire code is Actor-specific; not expected
5306
- // along this target-failure path, mapped for completeness.
5307
- case ZLinkFrameworkErrorKind.AlreadyExists:
5308
- return ServiceWireFrameworkErrorCode.actorAlreadyExists;
5309
- case ZLinkFrameworkErrorKind.TypeMismatch:
5310
- return objectKind === 'actor'
5311
- ? ServiceWireFrameworkErrorCode.actorTypeMismatch
5312
- : ServiceWireFrameworkErrorCode.spotTypeMismatch;
5313
- // No dedicated "not configured" wire code exists; a missing configured
5314
- // handler is the closest analog.
5315
- case ZLinkFrameworkErrorKind.NotConfigured:
5316
- return ServiceWireFrameworkErrorCode.handlerNotFound;
5317
- // No dedicated generic "internal failure" or "shutting down" wire code
5318
- // exists; the generic opaque request-failure code is the closest fit
5319
- // for both (ShuttingDown included — re-judged 2026-08-19, C-10).
5320
- case ZLinkFrameworkErrorKind.ShuttingDown:
5321
- case ZLinkFrameworkErrorKind.InternalFailure:
5322
- default:
5323
- return ServiceWireFrameworkErrorCode.requestFailed;
5473
+ return frameworkRelocationFailureCode(ZLinkFrameworkErrorKind.InternalFailure);
5324
5474
  }
5475
+ return frameworkRelocationFailureCode(error);
5325
5476
  }
5326
5477
 
5327
5478
  function relocationStagingId(value: {
@@ -5434,7 +5585,7 @@ function validatePrepareEnvelope(
5434
5585
  if (
5435
5586
  !sameWireId(request.relocation, relocationWireId(envelope.aggregateId)) ||
5436
5587
  request.applicationVersion !== envelope.applicationVersion ||
5437
- stringifyWire(request.object) !== stringifyWire(relocationObject(envelope))
5588
+ !sameRelocationObject(request.object, relocationObject(envelope))
5438
5589
  ) {
5439
5590
  throw new Error('Relocation Prepare does not match its immutable root identity.');
5440
5591
  }
@@ -5451,17 +5602,10 @@ function validateTargetOneWayControl(
5451
5602
  !sameWireId(request.relocation, prepare.relocation) ||
5452
5603
  request.targetAttemptGeneration !== prepare.targetAttemptGeneration ||
5453
5604
  !sameCoordinator(request.coordinator, prepare.coordinator) ||
5454
- stringifyWire(request.object) !==
5455
- stringifyWire(request.kind === 'data' ? request.object : prepare.object)
5605
+ (request.kind === 'cutover' && !sameRelocationObject(request.object, prepare.object))
5456
5606
  ) {
5457
5607
  throw new Error('Relocation one-way control changed its exact Prepare fence.');
5458
5608
  }
5459
- if (
5460
- request.kind === 'cutover' &&
5461
- stringifyWire(request.object) !== stringifyWire(prepare.object)
5462
- ) {
5463
- throw new Error('Relocation Cutover changed its prepared object.');
5464
- }
5465
5609
  }
5466
5610
 
5467
5611
  function relocationPublication(
@@ -5566,7 +5710,7 @@ function canonicalQueuedFrozenRecord(
5566
5710
  ...(packet.returnResponse ? { replyRouteId: BigInt(packet.source!.replyRouteId) } : {}),
5567
5711
  payload: {
5568
5712
  packetName: '__zlink.actor.handoff.accepted',
5569
- contentType: 'application/json',
5713
+ contentType: ZlinkStreamContentType.Json,
5570
5714
  bytes: message.payload
5571
5715
  }
5572
5716
  });
@@ -5590,6 +5734,20 @@ function stringifyWire(value: unknown): string {
5590
5734
  return JSON.stringify(value, (_key, item) => (typeof item === 'bigint' ? item.toString() : item));
5591
5735
  }
5592
5736
 
5737
+ function samePrepareIdentity(
5738
+ acceptedFingerprint: string,
5739
+ incoming: ServiceMaintenanceRelocationPrepare
5740
+ ): boolean {
5741
+ const accepted = JSON.parse(acceptedFingerprint) as ServiceMaintenanceRelocationPrepare;
5742
+ return (
5743
+ accepted.sourceNodeRid === incoming.sourceNodeRid &&
5744
+ BigInt(accepted.sourceNodeGeneration) === incoming.sourceNodeGeneration &&
5745
+ sameCoordinator(accepted.coordinator, incoming.coordinator) &&
5746
+ sameRelocationTarget(accepted.target, incoming.target) &&
5747
+ sameRelocationObject(accepted.object, incoming.object)
5748
+ );
5749
+ }
5750
+
5593
5751
  function validateControlResponse(
5594
5752
  request: ZLinkServiceRelocationControlRequest,
5595
5753
  response: ZLinkServiceRelocationControlResponse
@@ -5600,8 +5758,8 @@ function validateControlResponse(
5600
5758
  !sameWireId(response.relocation, request.relocation) ||
5601
5759
  response.targetAttemptGeneration !== request.targetAttemptGeneration ||
5602
5760
  !sameCoordinator(response.coordinator, request.coordinator) ||
5603
- stringifyWire(response.target) !== stringifyWire(request.target) ||
5604
- stringifyWire(response.object) !== stringifyWire(request.object) ||
5761
+ !sameRelocationTarget(response.target, request.target) ||
5762
+ !sameRelocationObject(response.object, request.object) ||
5605
5763
  response.senderRole !== 'target'
5606
5764
  ) {
5607
5765
  throw new Error('Relocation control response does not match the request fence.');
@@ -5624,82 +5782,19 @@ function validateControlFailureResponse(
5624
5782
  !sameWireId(response.relocation, request.relocation) ||
5625
5783
  response.targetAttemptGeneration !== request.targetAttemptGeneration ||
5626
5784
  !sameCoordinator(response.coordinator, request.coordinator) ||
5627
- stringifyWire(response.target) !== stringifyWire(request.target) ||
5628
- stringifyWire(response.object) !== stringifyWire(request.object) ||
5785
+ !sameRelocationTarget(response.target, request.target) ||
5786
+ !sameRelocationObject(response.object, request.object) ||
5629
5787
  response.senderRole !== 'target'
5630
5788
  ) {
5631
5789
  throw new Error('Relocation control response does not match the request fence.');
5632
5790
  }
5633
5791
  }
5634
5792
 
5635
- /**
5636
- * Maps a relocationFailed(53) wire failureCode (the generated
5637
- * ServiceWireFrameworkErrorCode vocabulary) to its internal error kind, so a
5638
- * source-side reject carries the same classification the target chose
5639
- * instead of a generic Error. Direct 1:1 correspondence with the generated
5640
- * names; an unrecognised or absent code falls back to RequestFailed
5641
- * (InternalFailure) — the closest existing kind (spec 15 §"Failed.Kind").
5642
- */
5643
- function relocationFailureCodeKind(failureCode: number): ZLinkFrameworkInternalErrorKind {
5644
- switch (failureCode) {
5645
- case 1:
5646
- return ZLinkFrameworkInternalErrorKind.ActorRouteNotFound;
5647
- case 2:
5648
- return ZLinkFrameworkInternalErrorKind.ActorCreateFailed;
5649
- case 3:
5650
- return ZLinkFrameworkInternalErrorKind.ActorAlreadyExists;
5651
- case 4:
5652
- return ZLinkFrameworkInternalErrorKind.ActorTypeMismatch;
5653
- case 5:
5654
- return ZLinkFrameworkInternalErrorKind.SpotCreateFailed;
5655
- case 6:
5656
- return ZLinkFrameworkInternalErrorKind.SpotRouteNotFound;
5657
- case 7:
5658
- return ZLinkFrameworkInternalErrorKind.SpotTypeMismatch;
5659
- case 8:
5660
- return ZLinkFrameworkInternalErrorKind.ActorSessionNotBound;
5661
- case 9:
5662
- return ZLinkFrameworkInternalErrorKind.HandlerNotFound;
5663
- case 10:
5664
- return ZLinkFrameworkInternalErrorKind.RouteHandlerNotFound;
5665
- case 11:
5666
- return ZLinkFrameworkInternalErrorKind.ActorDispatchHandlerNotFound;
5667
- case 12:
5668
- return ZLinkFrameworkInternalErrorKind.PayloadDecodeFailed;
5669
- case 13:
5670
- return ZLinkFrameworkInternalErrorKind.RouteNotConnected;
5671
- case 14:
5672
- return ZLinkFrameworkInternalErrorKind.RequestTargetNotFound;
5673
- case 15:
5674
- return ZLinkFrameworkInternalErrorKind.RequestRejected;
5675
- case 16:
5676
- return ZLinkFrameworkInternalErrorKind.RequestProtocolError;
5677
- case 18:
5678
- return ZLinkFrameworkInternalErrorKind.WorkerQueueFull;
5679
- case 19:
5680
- return ZLinkFrameworkInternalErrorKind.WorkerTimedOut;
5681
- case 20:
5682
- return ZLinkFrameworkInternalErrorKind.WorkerFailed;
5683
- case 21:
5684
- return ZLinkFrameworkInternalErrorKind.ActorLocationStale;
5685
- case 22:
5686
- return ZLinkFrameworkInternalErrorKind.ActorCreateRejected;
5687
- case 33:
5688
- return ZLinkFrameworkInternalErrorKind.SpotGenerationStale;
5689
- case 34:
5690
- return ZLinkFrameworkInternalErrorKind.SpotMoving;
5691
- case 35:
5692
- return ZLinkFrameworkInternalErrorKind.RelocationDataLost;
5693
- case 17:
5694
- default:
5695
- return ZLinkFrameworkInternalErrorKind.RequestFailed;
5696
- }
5697
- }
5698
-
5699
5793
  /** Builds the typed exception a Prepare waiter rejects with on an explicit Failed(53). */
5700
5794
  function relocationFailureException(response: ServiceMaintenanceRelocationFailed) {
5701
5795
  return createInternalFrameworkException(
5702
- relocationFailureCodeKind(response.failureCode),
5796
+ internalFrameworkErrorKindFromWireFailureCode(response.failureCode) ??
5797
+ ZLinkFrameworkInternalErrorKind.RequestFailed,
5703
5798
  `Relocation '${response.relocation.high}:${response.relocation.low}:` +
5704
5799
  `${response.targetAttemptGeneration}' failed with wire failureCode ${response.failureCode}.`,
5705
5800
  true
@@ -5879,7 +5974,7 @@ function queuedMessageU64(value: unknown, field: string): bigint {
5879
5974
  throw new TypeError(`Relocation Actor Message Follow ${field} is invalid.`);
5880
5975
  }
5881
5976
  const result = BigInt(value);
5882
- if (result > 0xffff_ffff_ffff_ffffn) {
5977
+ if (result > UINT64_MAX) {
5883
5978
  throw new TypeError(`Relocation Actor Message Follow ${field} is outside u64.`);
5884
5979
  }
5885
5980
  return result;
@@ -5903,6 +5998,15 @@ function toServiceTimer(
5903
5998
  };
5904
5999
  }
5905
6000
 
6001
+ const PREPARE_SIDEBAND_MAGIC = 'ZLNI';
6002
+ const PREPARE_SIDEBAND_VERSION = 1;
6003
+ const PREPARE_SIDEBAND_HEADER_BYTES = 11;
6004
+ const PREPARE_SIDEBAND_VERSION_OFFSET = 4;
6005
+ const PREPARE_SIDEBAND_KEY_LENGTH_OFFSET = 5;
6006
+ const PREPARE_SIDEBAND_PAYLOAD_LENGTH_OFFSET = 7;
6007
+ const ACTOR_SESSION_JOURNAL_VERSION = 1;
6008
+ const SERVICE_RELOCATION_REPLY_PACKET_NAME = 'zlink.relocation.reply';
6009
+
5906
6010
  /**
5907
6011
  * NODE-INTERNAL Prepare sideband. Frame zero remains the exact canonical
5908
6012
  * command-40 schema record; each following ZLNI frame carries one sealed
@@ -5918,11 +6022,11 @@ function encodePrepareSideband(envelope: ServiceRelocationEnvelope): readonly Bu
5918
6022
  if (key.byteLength === 0 || key.byteLength > 0xffff || payload.byteLength > 0xffff_ffff) {
5919
6023
  throw new TypeError('Bound-session relocation sideband is out of bounds.');
5920
6024
  }
5921
- const header = Buffer.allocUnsafe(11);
5922
- header.write('ZLNI', 0, 'ascii');
5923
- header[4] = 1;
5924
- header.writeUInt16BE(key.byteLength, 5);
5925
- header.writeUInt32BE(payload.byteLength, 7);
6025
+ const header = Buffer.allocUnsafe(PREPARE_SIDEBAND_HEADER_BYTES);
6026
+ header.write(PREPARE_SIDEBAND_MAGIC, 0, 'ascii');
6027
+ header[PREPARE_SIDEBAND_VERSION_OFFSET] = PREPARE_SIDEBAND_VERSION;
6028
+ header.writeUInt16BE(key.byteLength, PREPARE_SIDEBAND_KEY_LENGTH_OFFSET);
6029
+ header.writeUInt32BE(payload.byteLength, PREPARE_SIDEBAND_PAYLOAD_LENGTH_OFFSET);
5926
6030
  return Buffer.concat([header, key, payload]);
5927
6031
  });
5928
6032
  }
@@ -5938,19 +6042,29 @@ function decodePrepareSideband(frames: readonly Uint8Array[]):
5938
6042
  for (const frame of frames) {
5939
6043
  const bytes = Buffer.from(frame);
5940
6044
  if (
5941
- bytes.byteLength < 11 ||
5942
- bytes.subarray(0, 4).toString('ascii') !== 'ZLNI' ||
5943
- bytes[4] !== 1
6045
+ bytes.byteLength < PREPARE_SIDEBAND_HEADER_BYTES ||
6046
+ bytes.subarray(0, PREPARE_SIDEBAND_VERSION_OFFSET).toString('ascii') !==
6047
+ PREPARE_SIDEBAND_MAGIC ||
6048
+ bytes[PREPARE_SIDEBAND_VERSION_OFFSET] !== PREPARE_SIDEBAND_VERSION
5944
6049
  ) {
5945
6050
  return undefined;
5946
6051
  }
5947
- const keyLength = bytes.readUInt16BE(5);
5948
- const payloadLength = bytes.readUInt32BE(7);
5949
- if (11 + keyLength + payloadLength !== bytes.byteLength || keyLength === 0) return undefined;
5950
- const participantKey = bytes.subarray(11, 11 + keyLength).toString('utf8');
6052
+ const keyLength = bytes.readUInt16BE(PREPARE_SIDEBAND_KEY_LENGTH_OFFSET);
6053
+ const payloadLength = bytes.readUInt32BE(PREPARE_SIDEBAND_PAYLOAD_LENGTH_OFFSET);
6054
+ if (
6055
+ PREPARE_SIDEBAND_HEADER_BYTES + keyLength + payloadLength !== bytes.byteLength ||
6056
+ keyLength === 0
6057
+ )
6058
+ return undefined;
6059
+ const participantKey = bytes
6060
+ .subarray(PREPARE_SIDEBAND_HEADER_BYTES, PREPARE_SIDEBAND_HEADER_BYTES + keyLength)
6061
+ .toString('utf8');
5951
6062
  if (keys.has(participantKey)) return undefined;
5952
6063
  keys.add(participantKey);
5953
- result.push({ participantKey, payload: Buffer.from(bytes.subarray(11 + keyLength)) });
6064
+ result.push({
6065
+ participantKey,
6066
+ payload: Buffer.from(bytes.subarray(PREPARE_SIDEBAND_HEADER_BYTES + keyLength))
6067
+ });
5954
6068
  }
5955
6069
  return result;
5956
6070
  }
@@ -5981,13 +6095,16 @@ function encodeActorSession(target: ZLinkRemoteBoundSessionTarget | undefined):
5981
6095
  if (target === undefined) return Buffer.alloc(0);
5982
6096
  return Buffer.from(
5983
6097
  JSON.stringify({
5984
- version: 1,
6098
+ version: ACTOR_SESSION_JOURNAL_VERSION,
5985
6099
  routerChannelId: target.routerChannelId,
5986
6100
  targetNodeRid: String(target.targetNodeRid),
5987
6101
  spotId: String(target.spotId),
5988
6102
  sessionNodeRid:
5989
6103
  target.sessionNodeRid === undefined ? undefined : String(target.sessionNodeRid),
5990
6104
  sessionRid: target.sessionRid === undefined ? undefined : String(target.sessionRid),
6105
+ sessionOwnerNodeGeneration: target.sessionOwnerNodeGeneration?.toString(),
6106
+ sessionOwnerId: target.sessionOwnerId,
6107
+ sessionOwnerLeaseGeneration: target.sessionOwnerLeaseGeneration?.toString(),
5991
6108
  bindingGeneration: target.bindingGeneration?.toString(),
5992
6109
  previousAuthorityOwnerGeneration: target.previousAuthorityOwnerGeneration?.toString(),
5993
6110
  previousOwnerLeaseGeneration: target.previousOwnerLeaseGeneration?.toString(),
@@ -6020,12 +6137,13 @@ function encodeActorSession(target: ZLinkRemoteBoundSessionTarget | undefined):
6020
6137
  );
6021
6138
  }
6022
6139
 
6023
- function decodeActorSession(payload: Uint8Array): ZLinkRemoteBoundSessionTarget {
6140
+ function decodeActorSession(payload: Uint8Array): ZLinkRemoteBoundSessionTarget | undefined {
6141
+ if (payload.byteLength === 0) return undefined;
6024
6142
  const value = JSON.parse(Buffer.from(payload).toString('utf8')) as Record<string, unknown>;
6025
6143
  const optionalBigInt = (field: string) =>
6026
6144
  typeof value[field] === 'string' ? BigInt(value[field] as string) : undefined;
6027
6145
  if (
6028
- value.version !== 1 ||
6146
+ value.version !== ACTOR_SESSION_JOURNAL_VERSION ||
6029
6147
  typeof value.routerChannelId !== 'string' ||
6030
6148
  typeof value.targetNodeRid !== 'string' ||
6031
6149
  typeof value.spotId !== 'string'
@@ -6041,6 +6159,13 @@ function decodeActorSession(payload: Uint8Array): ZLinkRemoteBoundSessionTarget
6041
6159
  ? { sessionNodeRid: value.sessionNodeRid as RoutingId }
6042
6160
  : {}),
6043
6161
  ...(typeof value.sessionRid === 'string' ? { sessionRid: value.sessionRid as RoutingId } : {}),
6162
+ ...(optionalBigInt('sessionOwnerNodeGeneration') === undefined
6163
+ ? {}
6164
+ : { sessionOwnerNodeGeneration: optionalBigInt('sessionOwnerNodeGeneration') }),
6165
+ ...(typeof value.sessionOwnerId === 'string' ? { sessionOwnerId: value.sessionOwnerId } : {}),
6166
+ ...(optionalBigInt('sessionOwnerLeaseGeneration') === undefined
6167
+ ? {}
6168
+ : { sessionOwnerLeaseGeneration: optionalBigInt('sessionOwnerLeaseGeneration') }),
6044
6169
  ...(optionalBigInt('bindingGeneration') === undefined
6045
6170
  ? {}
6046
6171
  : { bindingGeneration: optionalBigInt('bindingGeneration') }),
@@ -6153,3 +6278,16 @@ function addCapacity(left: ZLinkCapacityVector, right: ZLinkCapacityVector): ZLi
6153
6278
  })
6154
6279
  };
6155
6280
  }
6281
+
6282
+ if (isStructuralGuardEnabled()) {
6283
+ const relocateActorJoin = ZLinkHostServiceRelocationRuntime.prototype.relocateActorJoin;
6284
+ ZLinkHostServiceRelocationRuntime.prototype.relocateActorJoin = function (
6285
+ this: ZLinkHostServiceRelocationRuntime,
6286
+ input: Parameters<ZLinkActorJoinRelocation['relocateActorJoin']>[0]
6287
+ ): ReturnType<ZLinkActorJoinRelocation['relocateActorJoin']> {
6288
+ return trackDiagnosticCompletion(
6289
+ relocateActorJoin.call(this, input),
6290
+ `relocation join actor:${input.state.actorId}`
6291
+ );
6292
+ };
6293
+ }