@zlink-systems/framework 0.30.0 → 0.30.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (456) hide show
  1. package/LICENSE +150 -68
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/contracts/Actors/ZLinkActorClient.d.ts +2 -1
  4. package/dist/contracts/Channels/Calls.d.ts +2 -1
  5. package/dist/contracts/Common/ZLinkEncodedPayload.d.ts +6 -0
  6. package/dist/contracts/Common/ZLinkEncodedPayload.js +18 -3
  7. package/dist/contracts/Common/ZLinkMessageMetadata.js +11 -5
  8. package/dist/contracts/Common/encoded-payload-storage.d.ts +1 -1
  9. package/dist/contracts/Common/encoded-payload-storage.js +5 -2
  10. package/dist/contracts/Configuration/Builders.d.ts +1 -1
  11. package/dist/contracts/Configuration/RegistrationBuilderPolicy.d.ts +2 -1
  12. package/dist/contracts/Configuration/RegistrationBuilderPolicy.js +5 -1
  13. package/dist/contracts/Configuration/RegistrationBuilders.js +2 -2
  14. package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -0
  15. package/dist/contracts/Dispatch/ZLinkDispatchOptions.d.ts +2 -2
  16. package/dist/contracts/Handlers/Attributes.d.ts +5 -13
  17. package/dist/contracts/Handlers/Attributes.js +7 -11
  18. package/dist/contracts/Handlers/JsonContract.d.ts +2 -46
  19. package/dist/contracts/Handlers/JsonContract.js +4 -153
  20. package/dist/contracts/Locations/Rows.d.ts +2 -0
  21. package/dist/contracts/Spots/Contracts.d.ts +6 -1
  22. package/dist/contracts/Spots/ZLinkSpot.d.ts +3 -3
  23. package/dist/nest-integration.d.ts +1 -1
  24. package/dist/nest-integration.js +2 -1
  25. package/dist/runtime/abort.d.ts +5 -0
  26. package/dist/runtime/abort.js +10 -0
  27. package/dist/runtime/actors/actor-authority-publication.js +3 -2
  28. package/dist/runtime/actors/actor-client.d.ts +1 -2
  29. package/dist/runtime/actors/actor-client.js +52 -57
  30. package/dist/runtime/actors/actor-context.d.ts +2 -0
  31. package/dist/runtime/actors/actor-context.js +46 -9
  32. package/dist/runtime/actors/actor-handoff.d.ts +8 -4
  33. package/dist/runtime/actors/actor-handoff.js +219 -92
  34. package/dist/runtime/actors/actor-join-relocation.d.ts +3 -0
  35. package/dist/runtime/actors/actor-local-native-join.js +13 -12
  36. package/dist/runtime/actors/actor-mailbox.js +27 -1
  37. package/dist/runtime/actors/actor-remote-joiner.js +3 -1
  38. package/dist/runtime/actors/actor-remote-wire.js +15 -0
  39. package/dist/runtime/actors/actor-reply.d.ts +4 -0
  40. package/dist/runtime/actors/actor-reply.js +29 -0
  41. package/dist/runtime/actors/actor-routed-join-transport.d.ts +6 -2
  42. package/dist/runtime/actors/actor-routed-json-request.d.ts +2 -0
  43. package/dist/runtime/actors/actor-runtime-contracts.d.ts +2 -0
  44. package/dist/runtime/actors/actor-runtime-state.js +2 -20
  45. package/dist/runtime/actors/actor-source-transfer.d.ts +1 -17
  46. package/dist/runtime/actors/index.d.ts +8 -3
  47. package/dist/runtime/actors/index.js +55 -27
  48. package/dist/runtime/actors/session-disconnected-wire.d.ts +8 -0
  49. package/dist/runtime/actors/session-disconnected-wire.js +48 -0
  50. package/dist/runtime/actors/spot-actor-dispatch.js +2 -2
  51. package/dist/runtime/admission.d.ts +9 -1
  52. package/dist/runtime/admission.js +56 -23
  53. package/dist/runtime/application-jobs/application-ingress-record-owner.d.ts +6 -8
  54. package/dist/runtime/application-jobs/application-ingress-record-owner.js +39 -22
  55. package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +15 -1
  56. package/dist/runtime/application-jobs/application-job-queue-scope.js +61 -20
  57. package/dist/runtime/application-jobs/contracts.d.ts +12 -1
  58. package/dist/runtime/backend/contracts/index.d.ts +37 -12
  59. package/dist/runtime/backend/mesh-actor-session-node-adapter.js +2 -2
  60. package/dist/runtime/backend/mesh-completion-table.d.ts +9 -1
  61. package/dist/runtime/backend/mesh-completion-table.js +154 -49
  62. package/dist/runtime/backend/mesh-dispatch-pump.d.ts +28 -1
  63. package/dist/runtime/backend/mesh-dispatch-pump.js +208 -101
  64. package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +2 -2
  65. package/dist/runtime/backend/node/node-backend-adapter-support.js +16 -9
  66. package/dist/runtime/backend/node/node-dealer-channel-client-transport.d.ts +1 -1
  67. package/dist/runtime/backend/node/node-dealer-channel-client-transport.js +5 -2
  68. package/dist/runtime/backend/node/node-raw-binding-port.js +124 -72
  69. package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +46 -13
  70. package/dist/runtime/backend/node/node-raw-mesh-backend.js +181 -164
  71. package/dist/runtime/backend/node/node-socket-backend-adapter.d.ts +1 -1
  72. package/dist/runtime/backend/node/node-socket-backend-adapter.js +11 -11
  73. package/dist/runtime/backend/raw-binding-port.d.ts +2 -2
  74. package/dist/runtime/backend/runtime-message.d.ts +1 -0
  75. package/dist/runtime/backend/runtime-message.js +5 -0
  76. package/dist/runtime/backend/runtime-values.d.ts +1 -0
  77. package/dist/runtime/backend/runtime-values.js +2 -1
  78. package/dist/runtime/channels/channel-clients.d.ts +2 -0
  79. package/dist/runtime/channels/channel-clients.js +75 -23
  80. package/dist/runtime/channels/channel-dispatch-pipeline.d.ts +25 -5
  81. package/dist/runtime/channels/channel-dispatch-pipeline.js +111 -56
  82. package/dist/runtime/channels/channel-dispatch-services.d.ts +1 -0
  83. package/dist/runtime/channels/channel-dispatch-services.js +45 -0
  84. package/dist/runtime/channels/channel-dispatchers.d.ts +4 -3
  85. package/dist/runtime/channels/channel-dispatchers.js +62 -54
  86. package/dist/runtime/channels/channel-envelope-inspection.d.ts +1 -2
  87. package/dist/runtime/channels/channel-envelope-inspection.js +1 -16
  88. package/dist/runtime/channels/channel-envelope.d.ts +2 -0
  89. package/dist/runtime/channels/channel-envelope.js +146 -28
  90. package/dist/runtime/channels/channel-outbound-operations.d.ts +2 -2
  91. package/dist/runtime/channels/channel-outbound-operations.js +8 -8
  92. package/dist/runtime/channels/channel-runtime-lifecycle.d.ts +4 -3
  93. package/dist/runtime/channels/channel-runtime-lifecycle.js +19 -24
  94. package/dist/runtime/channels/channel-runtime-manager.d.ts +9 -8
  95. package/dist/runtime/channels/channel-runtime-manager.js +16 -16
  96. package/dist/runtime/channels/channel-transports.d.ts +18 -16
  97. package/dist/runtime/channels/channel-transports.js +77 -58
  98. package/dist/runtime/channels/client-server-location-runtime.js +5 -4
  99. package/dist/runtime/channels/dispatch-error-reporter.d.ts +2 -1
  100. package/dist/runtime/channels/dispatch-error-reporter.js +2 -1
  101. package/dist/runtime/channels/fanout-location-runtime.d.ts +1 -1
  102. package/dist/runtime/channels/fanout-location-runtime.js +3 -3
  103. package/dist/runtime/channels/local-spot-route-transport.d.ts +1 -1
  104. package/dist/runtime/channels/local-spot-route-transport.js +2 -1
  105. package/dist/runtime/channels/router-socket-spot-route-transport.d.ts +2 -2
  106. package/dist/runtime/channels/router-socket-spot-route-transport.js +4 -4
  107. package/dist/runtime/channels/source-spot-router.d.ts +2 -2
  108. package/dist/runtime/channels/source-spot-router.js +4 -4
  109. package/dist/runtime/channels/spot-node-route-transport.d.ts +2 -2
  110. package/dist/runtime/channels/spot-node-route-transport.js +4 -4
  111. package/dist/runtime/channels/spot-route-bridge-transport.d.ts +2 -2
  112. package/dist/runtime/channels/spot-route-bridge-transport.js +4 -4
  113. package/dist/runtime/channels/spot-route-dispatch-strategy.d.ts +5 -4
  114. package/dist/runtime/channels/spot-route-dispatch-strategy.js +18 -18
  115. package/dist/runtime/diagnostics/flow-context.js +19 -7
  116. package/dist/runtime/diagnostics/index.js +4 -9
  117. package/dist/runtime/diagnostics/message-flow.d.ts +8 -0
  118. package/dist/runtime/diagnostics/message-flow.js +35 -5
  119. package/dist/runtime/diagnostics/runtime-metrics.d.ts +2 -2
  120. package/dist/runtime/diagnostics/runtime-metrics.js +10 -8
  121. package/dist/runtime/execution/index.d.ts +4 -2
  122. package/dist/runtime/execution/index.js +33 -10
  123. package/dist/runtime/execution/serial-execution-queue.d.ts +5 -0
  124. package/dist/runtime/execution/serial-execution-queue.js +22 -2
  125. package/dist/runtime/execution/state-lane.d.ts +2 -0
  126. package/dist/runtime/execution/state-lane.js +5 -0
  127. package/dist/runtime/foundation/actor-join-recovery-codec.js +2 -2
  128. package/dist/runtime/foundation/durable-service-request.d.ts +14 -0
  129. package/dist/runtime/foundation/durable-service-request.js +98 -0
  130. package/dist/runtime/foundation/operation-identity.d.ts +1 -0
  131. package/dist/runtime/foundation/operation-identity.js +5 -1
  132. package/dist/runtime/foundation/operation-registry.d.ts +25 -1
  133. package/dist/runtime/foundation/operation-registry.js +86 -18
  134. package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +61 -8
  135. package/dist/runtime/foundation/raw-service-mesh-runtime.js +486 -266
  136. package/dist/runtime/foundation/service-liveness-registry.d.ts +12 -1
  137. package/dist/runtime/foundation/service-liveness-registry.js +38 -0
  138. package/dist/runtime/foundation/service-mailbox.d.ts +7 -0
  139. package/dist/runtime/foundation/service-maintenance-runtime.js +1 -6
  140. package/dist/runtime/foundation/service-relocation-object-owner.d.ts +3 -3
  141. package/dist/runtime/foundation/service-relocation-object-owner.js +48 -34
  142. package/dist/runtime/foundation/service-relocation-runtime.d.ts +2 -0
  143. package/dist/runtime/foundation/service-relocation-runtime.js +20 -4
  144. package/dist/runtime/foundation/service-runtime-contracts.d.ts +10 -1
  145. package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +2 -1
  146. package/dist/runtime/foundation/service-stateful-registry.d.ts +5 -4
  147. package/dist/runtime/foundation/service-stateful-registry.js +24 -26
  148. package/dist/runtime/foundation/service-stateful-runtime.d.ts +75 -9
  149. package/dist/runtime/foundation/service-stateful-runtime.js +486 -218
  150. package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +14 -6
  151. package/dist/runtime/foundation/service-stateful-wire-codec.js +48 -27
  152. package/dist/runtime/foundation/service-topology-registry.d.ts +12 -2
  153. package/dist/runtime/foundation/service-topology-registry.js +61 -27
  154. package/dist/runtime/foundation/service-wire-binary-primitives.d.ts +6 -1
  155. package/dist/runtime/foundation/service-wire-binary-primitives.js +27 -11
  156. package/dist/runtime/foundation/service-wire-constants.generated.d.ts +1 -0
  157. package/dist/runtime/foundation/service-wire-constants.generated.js +1 -0
  158. package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +13 -3
  159. package/dist/runtime/foundation/service-wire-m6a-codec.js +189 -78
  160. package/dist/runtime/handlers/handler-instance-scope.d.ts +8 -0
  161. package/dist/runtime/handlers/handler-instance-scope.js +54 -11
  162. package/dist/runtime/host/actor-packet-relay.d.ts +6 -4
  163. package/dist/runtime/host/actor-packet-relay.js +59 -72
  164. package/dist/runtime/host/actor-placement-coordinator.js +25 -8
  165. package/dist/runtime/host/actor-runtime-options-factory.js +2 -2
  166. package/dist/runtime/host/actor-transfer-runtime.d.ts +7 -31
  167. package/dist/runtime/host/actor-transfer-runtime.js +85 -331
  168. package/dist/runtime/host/application-job-queue.d.ts +40 -7
  169. package/dist/runtime/host/application-job-queue.js +137 -42
  170. package/dist/runtime/host/entry-actor-runtime.d.ts +1 -0
  171. package/dist/runtime/host/entry-actor-runtime.js +3 -0
  172. package/dist/runtime/host/index.d.ts +12 -2
  173. package/dist/runtime/host/index.js +300 -202
  174. package/dist/runtime/host/location-runtime-owner.js +2 -6
  175. package/dist/runtime/host/mesh-router-resolver.d.ts +4 -0
  176. package/dist/runtime/host/mesh-router-resolver.js +14 -6
  177. package/dist/runtime/host/remote-bound-session-relay.d.ts +2 -4
  178. package/dist/runtime/host/remote-bound-session-relay.js +73 -208
  179. package/dist/runtime/host/route-mesh-runtime.d.ts +2 -2
  180. package/dist/runtime/host/route-mesh-runtime.js +6 -4
  181. package/dist/runtime/host/runtime-shutdown.d.ts +1 -0
  182. package/dist/runtime/host/runtime-shutdown.js +3 -2
  183. package/dist/runtime/host/service-relocation-control.d.ts +1 -0
  184. package/dist/runtime/host/service-relocation-control.js +10 -4
  185. package/dist/runtime/host/service-relocation-host-runtime.d.ts +22 -14
  186. package/dist/runtime/host/service-relocation-host-runtime.js +754 -599
  187. package/dist/runtime/host/spot-address-transport.js +3 -2
  188. package/dist/runtime/host/spot-runtime-options-factory.js +16 -7
  189. package/dist/runtime/host/user-spot-creation-coordinator.js +33 -84
  190. package/dist/runtime/locations/actor-location-claims.d.ts +2 -2
  191. package/dist/runtime/locations/actor-location-claims.js +34 -19
  192. package/dist/runtime/locations/auto-connect-loop.d.ts +2 -0
  193. package/dist/runtime/locations/auto-connect-loop.js +22 -14
  194. package/dist/runtime/locations/auto-connect-reconciler.js +0 -6
  195. package/dist/runtime/locations/auto-connect-types.d.ts +0 -1
  196. package/dist/runtime/locations/descriptor-publication.d.ts +4 -0
  197. package/dist/runtime/locations/descriptor-publication.js +11 -0
  198. package/dist/runtime/locations/domain-store-contract.d.ts +1 -0
  199. package/dist/runtime/locations/in-memory-authority-store.d.ts +7 -1
  200. package/dist/runtime/locations/in-memory-authority-store.js +56 -19
  201. package/dist/runtime/locations/in-memory-location-store.js +1 -10
  202. package/dist/runtime/locations/index.d.ts +1 -0
  203. package/dist/runtime/locations/index.js +1 -0
  204. package/dist/runtime/locations/lease-tracker.js +1 -6
  205. package/dist/runtime/locations/lifecycle.d.ts +1 -2
  206. package/dist/runtime/locations/lifecycle.js +2 -5
  207. package/dist/runtime/locations/location-store-repository.d.ts +51 -1
  208. package/dist/runtime/locations/location-store-repository.js +363 -139
  209. package/dist/runtime/locations/relocation-blob.d.ts +18 -1
  210. package/dist/runtime/locations/relocation-blob.js +52 -1
  211. package/dist/runtime/locations/request-source-resolver.d.ts +37 -0
  212. package/dist/runtime/locations/request-source-resolver.js +80 -0
  213. package/dist/runtime/locations/resolvers.js +1 -1
  214. package/dist/runtime/locations/runtime.d.ts +7 -3
  215. package/dist/runtime/locations/runtime.js +61 -53
  216. package/dist/runtime/messaging/framework-json-v1.d.ts +4 -6
  217. package/dist/runtime/messaging/framework-json-v1.js +38 -294
  218. package/dist/runtime/messaging/packet-name.d.ts +1 -1
  219. package/dist/runtime/messaging/packet-name.js +8 -24
  220. package/dist/runtime/messaging/payload-codec.d.ts +7 -1
  221. package/dist/runtime/messaging/payload-codec.js +7 -6
  222. package/dist/runtime/messaging/request-result.d.ts +2 -0
  223. package/dist/runtime/messaging/request-result.js +57 -0
  224. package/dist/runtime/messaging/submission-result.d.ts +1 -0
  225. package/dist/runtime/messaging/submission-result.js +5 -2
  226. package/dist/runtime/protocol/service_wire_codec.generated.d.ts +34 -1
  227. package/dist/runtime/protocol/service_wire_codec.generated.js +229 -0
  228. package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +16 -1
  229. package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +37 -8
  230. package/dist/runtime/spots/formal-remote-actor-admission-registry.d.ts +7 -2
  231. package/dist/runtime/spots/formal-remote-actor-admission-registry.js +36 -21
  232. package/dist/runtime/spots/index.d.ts +21 -11
  233. package/dist/runtime/spots/index.js +243 -178
  234. package/dist/runtime/spots/spot-activation-registry.d.ts +4 -2
  235. package/dist/runtime/spots/spot-activation-registry.js +21 -11
  236. package/dist/runtime/spots/spot-activation-state.d.ts +1 -1
  237. package/dist/runtime/spots/spot-activation-state.js +7 -7
  238. package/dist/runtime/spots/spot-activation.d.ts +7 -3
  239. package/dist/runtime/spots/spot-activation.js +140 -52
  240. package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +1 -0
  241. package/dist/runtime/spots/spot-actor-admission-coordinator.js +13 -22
  242. package/dist/runtime/spots/spot-actor-membership.d.ts +0 -1
  243. package/dist/runtime/spots/spot-actor-membership.js +0 -8
  244. package/dist/runtime/spots/spot-actor-packet-dispatch.js +33 -8
  245. package/dist/runtime/spots/spot-actor-packet-drain.js +5 -33
  246. package/dist/runtime/spots/spot-entry-activation.d.ts +2 -0
  247. package/dist/runtime/spots/spot-entry-activation.js +20 -11
  248. package/dist/runtime/spots/spot-handler-registry.d.ts +7 -4
  249. package/dist/runtime/spots/spot-handler-registry.js +24 -10
  250. package/dist/runtime/spots/spot-manager-internal-contracts.d.ts +2 -2
  251. package/dist/runtime/spots/spot-manager-public.js +2 -2
  252. package/dist/runtime/spots/spot-node-autoconnect.d.ts +2 -1
  253. package/dist/runtime/spots/spot-node-autoconnect.js +22 -42
  254. package/dist/runtime/spots/spot-node-runtime-manager.d.ts +19 -2
  255. package/dist/runtime/spots/spot-node-runtime-manager.js +115 -50
  256. package/dist/runtime/spots/spot-outbound.d.ts +3 -0
  257. package/dist/runtime/spots/spot-outbound.js +27 -18
  258. package/dist/runtime/spots/spot-remote-codec.js +5 -1
  259. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.d.ts +1 -0
  260. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +1 -1
  261. package/dist/runtime/spots/spot-runtime-ports.d.ts +1 -1
  262. package/dist/runtime/spots/spot-serial-executor.d.ts +10 -0
  263. package/dist/runtime/spots/spot-serial-executor.js +61 -8
  264. package/dist/runtime/spots/spot-serial-turn-executor.js +19 -2
  265. package/dist/runtime/spots/spot-subscription-dispatch.js +1 -4
  266. package/dist/runtime/spots/spot-timer.d.ts +57 -5
  267. package/dist/runtime/spots/spot-timer.js +288 -103
  268. package/dist/runtime/streams/actor-session-binding-registry.d.ts +42 -11
  269. package/dist/runtime/streams/actor-session-binding-registry.js +165 -48
  270. package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +8 -4
  271. package/dist/runtime/streams/bound-actor-relay-sender.d.ts +2 -1
  272. package/dist/runtime/streams/bound-actor-relay-sender.js +15 -8
  273. package/dist/runtime/streams/bound-session-service.d.ts +1 -1
  274. package/dist/runtime/streams/bound-session-service.js +6 -11
  275. package/dist/runtime/streams/index.d.ts +3 -2
  276. package/dist/runtime/streams/index.js +6 -4
  277. package/dist/runtime/streams/managed-stream.js +3 -2
  278. package/dist/runtime/streams/native-fallback-bound-session.js +8 -73
  279. package/dist/runtime/streams/session-actor-coordinator.d.ts +2 -8
  280. package/dist/runtime/streams/session-actor-coordinator.js +15 -32
  281. package/dist/runtime/streams/stream-binding-runtime-ports.d.ts +3 -10
  282. package/dist/runtime/streams/stream-session-runtime.d.ts +1 -1
  283. package/dist/runtime/streams/stream-session-runtime.js +14 -31
  284. package/dist/runtime/workers/index.js +1 -1
  285. package/package.json +3 -3
  286. package/src/contracts/Actors/ZLinkActorClient.ts +2 -1
  287. package/src/contracts/Channels/Calls.ts +2 -1
  288. package/src/contracts/Common/ZLinkEncodedPayload.ts +24 -4
  289. package/src/contracts/Common/ZLinkMessageMetadata.ts +13 -8
  290. package/src/contracts/Common/encoded-payload-storage.ts +6 -3
  291. package/src/contracts/Configuration/Builders.ts +4 -1
  292. package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +7 -2
  293. package/src/contracts/Configuration/RegistrationBuilders.ts +6 -2
  294. package/src/contracts/Configuration/RegistrationTypes.ts +1 -0
  295. package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +2 -1
  296. package/src/contracts/Handlers/Attributes.ts +14 -21
  297. package/src/contracts/Handlers/JsonContract.ts +8 -216
  298. package/src/contracts/Locations/Rows.ts +2 -0
  299. package/src/contracts/Spots/Contracts.ts +10 -1
  300. package/src/contracts/Spots/ZLinkSpot.ts +3 -3
  301. package/src/nest-integration.ts +1 -0
  302. package/src/runtime/abort.ts +12 -0
  303. package/src/runtime/actors/actor-authority-publication.ts +3 -2
  304. package/src/runtime/actors/actor-client.ts +100 -85
  305. package/src/runtime/actors/actor-context.ts +49 -9
  306. package/src/runtime/actors/actor-handoff.ts +291 -110
  307. package/src/runtime/actors/actor-join-relocation.ts +3 -0
  308. package/src/runtime/actors/actor-local-native-join.ts +21 -26
  309. package/src/runtime/actors/actor-mailbox.ts +40 -2
  310. package/src/runtime/actors/actor-remote-joiner.ts +6 -1
  311. package/src/runtime/actors/actor-remote-wire.ts +17 -0
  312. package/src/runtime/actors/actor-reply.ts +42 -0
  313. package/src/runtime/actors/actor-routed-join-transport.ts +14 -4
  314. package/src/runtime/actors/actor-routed-json-request.ts +10 -2
  315. package/src/runtime/actors/actor-runtime-contracts.ts +2 -0
  316. package/src/runtime/actors/actor-runtime-state.ts +2 -20
  317. package/src/runtime/actors/actor-source-transfer.ts +1 -34
  318. package/src/runtime/actors/index.ts +60 -32
  319. package/src/runtime/actors/session-disconnected-wire.ts +66 -0
  320. package/src/runtime/actors/spot-actor-dispatch.ts +4 -2
  321. package/src/runtime/admission.ts +69 -21
  322. package/src/runtime/application-jobs/application-ingress-record-owner.ts +41 -25
  323. package/src/runtime/application-jobs/application-job-queue-scope.ts +83 -22
  324. package/src/runtime/application-jobs/contracts.ts +16 -1
  325. package/src/runtime/backend/contracts/index.ts +92 -18
  326. package/src/runtime/backend/mesh-actor-session-node-adapter.ts +5 -3
  327. package/src/runtime/backend/mesh-completion-table.ts +160 -57
  328. package/src/runtime/backend/mesh-dispatch-pump.ts +237 -108
  329. package/src/runtime/backend/node/node-backend-adapter-support.ts +17 -8
  330. package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +12 -2
  331. package/src/runtime/backend/node/node-raw-binding-port.ts +148 -85
  332. package/src/runtime/backend/node/node-raw-mesh-backend.ts +315 -201
  333. package/src/runtime/backend/node/node-socket-backend-adapter.ts +26 -11
  334. package/src/runtime/backend/raw-binding-port.ts +7 -2
  335. package/src/runtime/backend/runtime-message.ts +6 -0
  336. package/src/runtime/backend/runtime-values.ts +1 -0
  337. package/src/runtime/channels/channel-clients.ts +132 -58
  338. package/src/runtime/channels/channel-dispatch-pipeline.ts +198 -114
  339. package/src/runtime/channels/channel-dispatch-services.ts +69 -1
  340. package/src/runtime/channels/channel-dispatchers.ts +136 -90
  341. package/src/runtime/channels/channel-envelope-inspection.ts +2 -16
  342. package/src/runtime/channels/channel-envelope.ts +225 -31
  343. package/src/runtime/channels/channel-outbound-operations.ts +22 -8
  344. package/src/runtime/channels/channel-runtime-lifecycle.ts +13 -13
  345. package/src/runtime/channels/channel-runtime-manager.ts +41 -17
  346. package/src/runtime/channels/channel-transports.ts +171 -112
  347. package/src/runtime/channels/client-server-location-runtime.ts +11 -10
  348. package/src/runtime/channels/dispatch-error-reporter.ts +4 -2
  349. package/src/runtime/channels/fanout-location-runtime.ts +17 -9
  350. package/src/runtime/channels/local-spot-route-transport.ts +3 -1
  351. package/src/runtime/channels/router-socket-spot-route-transport.ts +13 -4
  352. package/src/runtime/channels/source-spot-router.ts +8 -4
  353. package/src/runtime/channels/spot-node-route-transport.ts +8 -4
  354. package/src/runtime/channels/spot-route-bridge-transport.ts +6 -4
  355. package/src/runtime/channels/spot-route-dispatch-strategy.ts +47 -18
  356. package/src/runtime/diagnostics/flow-context.ts +20 -7
  357. package/src/runtime/diagnostics/index.ts +1 -7
  358. package/src/runtime/diagnostics/message-flow.ts +47 -9
  359. package/src/runtime/diagnostics/runtime-metrics.ts +12 -10
  360. package/src/runtime/execution/index.ts +40 -14
  361. package/src/runtime/execution/serial-execution-queue.ts +33 -4
  362. package/src/runtime/execution/state-lane.ts +7 -0
  363. package/src/runtime/foundation/actor-join-recovery-codec.ts +2 -2
  364. package/src/runtime/foundation/durable-service-request.ts +137 -0
  365. package/src/runtime/foundation/operation-identity.ts +5 -1
  366. package/src/runtime/foundation/operation-registry.ts +98 -20
  367. package/src/runtime/foundation/raw-service-mesh-runtime.ts +704 -336
  368. package/src/runtime/foundation/service-liveness-registry.ts +39 -0
  369. package/src/runtime/foundation/service-mailbox.ts +8 -0
  370. package/src/runtime/foundation/service-maintenance-runtime.ts +1 -8
  371. package/src/runtime/foundation/service-relocation-object-owner.ts +55 -36
  372. package/src/runtime/foundation/service-relocation-runtime.ts +25 -4
  373. package/src/runtime/foundation/service-runtime-contracts.ts +19 -2
  374. package/src/runtime/foundation/service-session-binding-ingress-port.ts +2 -1
  375. package/src/runtime/foundation/service-stateful-registry.ts +38 -35
  376. package/src/runtime/foundation/service-stateful-runtime.ts +732 -275
  377. package/src/runtime/foundation/service-stateful-wire-codec.ts +49 -16
  378. package/src/runtime/foundation/service-topology-registry.ts +91 -36
  379. package/src/runtime/foundation/service-wire-binary-primitives.ts +35 -12
  380. package/src/runtime/foundation/service-wire-constants.generated.ts +1 -0
  381. package/src/runtime/foundation/service-wire-m6a-codec.ts +231 -76
  382. package/src/runtime/handlers/handler-instance-scope.ts +67 -16
  383. package/src/runtime/host/actor-packet-relay.ts +113 -94
  384. package/src/runtime/host/actor-placement-coordinator.ts +31 -8
  385. package/src/runtime/host/actor-runtime-options-factory.ts +13 -2
  386. package/src/runtime/host/actor-transfer-runtime.ts +104 -430
  387. package/src/runtime/host/application-job-queue.ts +160 -41
  388. package/src/runtime/host/entry-actor-runtime.ts +4 -0
  389. package/src/runtime/host/index.ts +473 -271
  390. package/src/runtime/host/location-runtime-owner.ts +2 -6
  391. package/src/runtime/host/mesh-router-resolver.ts +13 -5
  392. package/src/runtime/host/remote-bound-session-relay.ts +88 -271
  393. package/src/runtime/host/route-mesh-runtime.ts +12 -6
  394. package/src/runtime/host/runtime-shutdown.ts +15 -4
  395. package/src/runtime/host/service-relocation-control.ts +11 -5
  396. package/src/runtime/host/service-relocation-host-runtime.ts +1092 -759
  397. package/src/runtime/host/spot-address-transport.ts +4 -2
  398. package/src/runtime/host/spot-runtime-options-factory.ts +20 -7
  399. package/src/runtime/host/user-spot-creation-coordinator.ts +41 -100
  400. package/src/runtime/locations/actor-location-claims.ts +52 -30
  401. package/src/runtime/locations/auto-connect-loop.ts +22 -14
  402. package/src/runtime/locations/auto-connect-reconciler.ts +0 -6
  403. package/src/runtime/locations/auto-connect-types.ts +0 -1
  404. package/src/runtime/locations/descriptor-publication.ts +7 -0
  405. package/src/runtime/locations/domain-store-contract.ts +5 -0
  406. package/src/runtime/locations/in-memory-authority-store.ts +85 -23
  407. package/src/runtime/locations/in-memory-location-store.ts +1 -12
  408. package/src/runtime/locations/index.ts +1 -0
  409. package/src/runtime/locations/lease-tracker.ts +2 -9
  410. package/src/runtime/locations/lifecycle.ts +8 -26
  411. package/src/runtime/locations/location-store-repository.ts +628 -152
  412. package/src/runtime/locations/relocation-blob.ts +75 -1
  413. package/src/runtime/locations/request-source-resolver.ts +138 -0
  414. package/src/runtime/locations/resolvers.ts +2 -2
  415. package/src/runtime/locations/runtime.ts +98 -64
  416. package/src/runtime/messaging/framework-json-v1.ts +5 -325
  417. package/src/runtime/messaging/packet-name.ts +5 -25
  418. package/src/runtime/messaging/payload-codec.ts +8 -11
  419. package/src/runtime/messaging/request-result.ts +62 -0
  420. package/src/runtime/messaging/submission-result.ts +5 -1
  421. package/src/runtime/protocol/service_wire_codec.generated.ts +218 -5
  422. package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +16 -13
  423. package/src/runtime/spots/formal-remote-actor-admission-registry.ts +46 -25
  424. package/src/runtime/spots/index.ts +389 -283
  425. package/src/runtime/spots/spot-activation-registry.ts +25 -13
  426. package/src/runtime/spots/spot-activation-state.ts +12 -19
  427. package/src/runtime/spots/spot-activation.ts +198 -96
  428. package/src/runtime/spots/spot-actor-admission-coordinator.ts +25 -55
  429. package/src/runtime/spots/spot-actor-membership.ts +0 -15
  430. package/src/runtime/spots/spot-actor-packet-dispatch.ts +56 -11
  431. package/src/runtime/spots/spot-actor-packet-drain.ts +9 -52
  432. package/src/runtime/spots/spot-entry-activation.ts +33 -21
  433. package/src/runtime/spots/spot-handler-registry.ts +56 -12
  434. package/src/runtime/spots/spot-manager-internal-contracts.ts +2 -2
  435. package/src/runtime/spots/spot-manager-public.ts +2 -2
  436. package/src/runtime/spots/spot-node-autoconnect.ts +28 -47
  437. package/src/runtime/spots/spot-node-runtime-manager.ts +197 -67
  438. package/src/runtime/spots/spot-outbound.ts +39 -19
  439. package/src/runtime/spots/spot-remote-codec.ts +9 -2
  440. package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +2 -1
  441. package/src/runtime/spots/spot-runtime-ports.ts +1 -1
  442. package/src/runtime/spots/spot-serial-executor.ts +97 -25
  443. package/src/runtime/spots/spot-serial-turn-executor.ts +22 -3
  444. package/src/runtime/spots/spot-subscription-dispatch.ts +1 -4
  445. package/src/runtime/spots/spot-timer.ts +418 -158
  446. package/src/runtime/streams/actor-session-binding-registry.ts +236 -64
  447. package/src/runtime/streams/actor-session-binding-runtime-owner.ts +16 -8
  448. package/src/runtime/streams/bound-actor-relay-sender.ts +23 -9
  449. package/src/runtime/streams/bound-session-service.ts +7 -10
  450. package/src/runtime/streams/index.ts +12 -6
  451. package/src/runtime/streams/managed-stream.ts +4 -2
  452. package/src/runtime/streams/native-fallback-bound-session.ts +14 -103
  453. package/src/runtime/streams/session-actor-coordinator.ts +39 -88
  454. package/src/runtime/streams/stream-binding-runtime-ports.ts +3 -9
  455. package/src/runtime/streams/stream-session-runtime.ts +13 -34
  456. package/src/runtime/workers/index.ts +1 -1
@@ -1,3 +1,7 @@
1
+ import { encodeActorReply } from '../actors/actor-reply';
2
+ import { boundSessionErrorPayload } from '../streams/bound-session-response-target';
3
+ import { RELOCATED_REQUEST_OWNED_BY_REQUESTER } from '../actors/actor-handoff';
4
+ import { routingIdsEqual } from '../routing-id';
1
5
  import type { ApplicationJobOrigin } from '../application-jobs/contracts';
2
6
  import { dispatchReasonFromError } from '../diagnostics/dispatch-error-details';
3
7
  import type {
@@ -29,7 +33,7 @@ export { ZLinkSpotActorAdmissionCoordinator } from './spot-actor-admission-coord
29
33
  import type { ZLinkSpotRouteResolver, ZLinkSpotRouteTarget } from './spot-routing-internal';
30
34
  import type { Message } from '../../contracts/Common/Message';
31
35
  import type { ZLinkMessageFollowOrigin } from '../foundation/service-runtime-contracts';
32
- import { awaitWithAbort, isAbortError, throwIfAborted } from '../abort';
36
+ import { awaitWithAbort, throwIfAborted } from '../abort';
33
37
  import {
34
38
  ZLinkMessage,
35
39
  ZLinkFrameworkException,
@@ -81,7 +85,6 @@ import {
81
85
  } from '../actors';
82
86
  import type { ZLinkLocationLifecycle } from '../locations';
83
87
  import {
84
- encodeFrameworkPayload,
85
88
  encodeFrameworkPayloadMessage,
86
89
  frameworkPayloadContentType,
87
90
  wrapFrameworkPayloadMessage
@@ -92,13 +95,7 @@ import {
92
95
  encodeChannelErrorReplyParts,
93
96
  encodeChannelReplyParts
94
97
  } from '../channels/channel-envelope';
95
- import {
96
- decodeStreamHeader,
97
- encodeStreamHeader,
98
- streamCodecForContentType,
99
- ZLinkStreamHeaderFlags,
100
- ZLinkStreamMessageKind
101
- } from '../streams/protocol';
98
+ import { ZLinkStreamMessageKind } from '../streams/protocol';
102
99
  import {
103
100
  REMOTE_ACTOR_JOIN_PACKET,
104
101
  REMOTE_ACTOR_JOIN_ABORT,
@@ -135,6 +132,7 @@ export {
135
132
  export { ZLinkRuntimeSpotPublisherTransport } from './spot-publisher-transport';
136
133
  import { ZLinkSpotActivationRegistry } from './spot-activation-registry';
137
134
  import type { ZLinkSpotActivation } from './spot-activation-state';
135
+ import type { ZLinkSpotPreparationCompletion } from './spot-serial-executor';
138
136
  import { ZLinkSpotActivationLifecycle, type ZLinkNativeSpotAuthority } from './spot-activation';
139
137
  import { ZLinkSpotActorMembership } from './spot-actor-membership';
140
138
  import { ZLinkFormalRemoteActorTransferRegistry } from './formal-remote-actor-transfer-registry';
@@ -148,7 +146,7 @@ import type {
148
146
  ZLinkSpotActorTransferRuntime,
149
147
  ZLinkSpotBoundSessionRuntime
150
148
  } from './spot-runtime-ports';
151
- import type { ZLinkRuntimeAdmissionGate } from '../admission';
149
+ import type { ZLinkRuntimeAdmissionGate, ZLinkMeshDispatchAdmission } from '../admission';
152
150
  import type { ZLinkActivationAdmission } from '../activation-admission';
153
151
  import type { ZLinkDetachedTaskRunner } from './spot-actor-join-dispatch';
154
152
  import type { ZLinkLocalSpotCreateResult } from './spot-manager-internal-contracts';
@@ -159,6 +157,7 @@ import { ZLinkRoutedSpotPacketDispatch } from './spot-routed-spot-packet-dispatc
159
157
  export { ZLinkEntrySpotActivation } from './spot-entry-activation';
160
158
  export {
161
159
  createFrameworkEntrySpotId,
160
+ registrationAcceptsNewActor,
162
161
  ZLinkSpotNodeRuntimeManager,
163
162
  type ZLinkSpotNodeRuntimeManagerOptions
164
163
  } from './spot-node-runtime-manager';
@@ -209,12 +208,18 @@ export interface ZLinkSpotManagerOptions {
209
208
  actor: ZLinkActor,
210
209
  handoffBacklog?: readonly ZLinkActorHandoffPacket[]
211
210
  ) => Promise<void>;
211
+ readonly admitEntryActorPacketPrefix?: (
212
+ meshName: string,
213
+ actorId: string,
214
+ records: readonly ZLinkActorHandoffPrefixRecord[]
215
+ ) => ZLinkActorHandoffPrefixAdmission;
212
216
  readonly executeEntryActor?: <T>(
213
217
  meshName: string,
214
218
  actorId: string,
215
219
  operation: () => Promise<T>
216
220
  ) => Promise<T>;
217
221
  readonly actorCountProvider?: (spotId: RoutingId) => number;
222
+ readonly releaseActorMembers?: (meshName: string, spotId: RoutingId) => Promise<void>;
218
223
  readonly userSpotExecutionMode?: (
219
224
  meshName: string,
220
225
  spotType: Type<ZLinkSpot>
@@ -408,6 +413,7 @@ export class DefaultZLinkSpotManager {
408
413
  nodeRid: options.nodeRid,
409
414
  nodeRidProvider: options.nodeRidProvider,
410
415
  actorCountProvider: options.actorCountProvider,
416
+ releaseActorMembers: options.releaseActorMembers,
411
417
  userSpotExecutionMode: options.userSpotExecutionMode,
412
418
  userSpotRelocationCoordinationMode: options.userSpotRelocationCoordinationMode,
413
419
  channelClient: options.channelClient,
@@ -437,9 +443,16 @@ export class DefaultZLinkSpotManager {
437
443
  this.actorMembership.leaveActor(spotId, actor, signal, meshName),
438
444
  requestContextClose: (activation, objectGeneration, signal) =>
439
445
  this.closeFromContext(activation, objectGeneration, signal),
440
- registerActivation: (activation) => {
441
- this.activations.register(activation);
446
+ stageActivation: (activation) => {
447
+ this.activations.registerPreparing(activation);
448
+ },
449
+ discardActivation: (activation) => {
450
+ this.activations.finishClose(activation.meshName, activation.spotId);
451
+ },
452
+ registerActivation: async (activation) => {
453
+ const published = this.activations.register(activation);
442
454
  this.scheduleIdleSweep();
455
+ if (published?.domain.kind === 'user') await published.serialExecutor.finishPreparation();
443
456
  },
444
457
  // Spec 15 §4.2 relocation temporary queue: production ingress
445
458
  // consults the same admission attempts registered on Accepted
@@ -511,6 +524,7 @@ export class DefaultZLinkSpotManager {
511
524
  spotId: RoutingId,
512
525
  objectGeneration: bigint,
513
526
  authorityOwnerGeneration: bigint,
527
+ restoredTimers: readonly import('./spot-timer').ZLinkTimerRelocationState[],
514
528
  signal?: AbortSignal
515
529
  ): Promise<ZLinkSpotActivation> {
516
530
  this.activations.stage(meshName, spotId);
@@ -523,6 +537,7 @@ export class DefaultZLinkSpotManager {
523
537
  spotId,
524
538
  objectGeneration,
525
539
  authorityOwnerGeneration,
540
+ restoredTimers,
526
541
  signal
527
542
  );
528
543
  } catch (error) {
@@ -535,12 +550,19 @@ export class DefaultZLinkSpotManager {
535
550
  activation: ZLinkSpotActivation,
536
551
  beforeAdmission?: () => Promise<void>
537
552
  ): Promise<void> {
538
- await activation.serial.execute(() => activation.spot.onInitialize?.());
553
+ // Spot timer §1: OnInitialize before Ready reattaches restored keys; the
554
+ // relocation-ready completion and later callbacks use the ordinary rule.
555
+ await activation.serial.postBarrierTurn(() =>
556
+ activation.timers.runRelocationInitialization(() => activation.spot.onInitialize?.())
557
+ );
539
558
  await beforeAdmission?.();
540
559
  this.activations.publish(activation.meshName, activation.spotId);
560
+ await activation.serialExecutor.finishPreparation();
561
+ await activation.timers.publishRelocation();
541
562
  }
542
563
 
543
564
  async abortRelocationSpot(activation: ZLinkSpotActivation): Promise<void> {
565
+ await this.activationLifecycle.discardPreparation(activation);
544
566
  this.activations.detachRelocated(activation.meshName, activation.spotId);
545
567
  await activation.timers.dispose();
546
568
  await activation.nativeSpot?.dispose();
@@ -556,7 +578,8 @@ export class DefaultZLinkSpotManager {
556
578
  instanceType: string,
557
579
  spotId: RoutingId,
558
580
  objectGeneration: bigint,
559
- signal?: AbortSignal
581
+ signal?: AbortSignal,
582
+ completion: ZLinkSpotPreparationCompletion = 'publication'
560
583
  ): Promise<void> {
561
584
  const readyTarget = this.options.instanceSpotApplicationTargetProvider?.(meshName, spotId);
562
585
  const existing = this.pendingInstanceMaterializations.get(
@@ -574,7 +597,8 @@ export class DefaultZLinkSpotManager {
574
597
  spotId,
575
598
  objectGeneration,
576
599
  readyTarget?.objectGeneration === objectGeneration,
577
- signal
600
+ signal,
601
+ completion
578
602
  );
579
603
  } finally {
580
604
  release?.();
@@ -587,7 +611,8 @@ export class DefaultZLinkSpotManager {
587
611
  spotId: RoutingId,
588
612
  objectGeneration: bigint,
589
613
  requiresReadyTarget: boolean,
590
- signal?: AbortSignal
614
+ signal: AbortSignal | undefined,
615
+ completion: ZLinkSpotPreparationCompletion
591
616
  ): Promise<void> {
592
617
  const factory = this.requireInstanceFactory(meshName, instanceType);
593
618
  const key = `${meshName}\0${String(spotId)}`;
@@ -620,7 +645,7 @@ export class DefaultZLinkSpotManager {
620
645
  continue;
621
646
  }
622
647
 
623
- const current = this.activations.resolve(meshName, spotId);
648
+ const current = this.activations.activationForClose(meshName, spotId);
624
649
  if (current !== undefined) {
625
650
  if (current.spotType !== factory) {
626
651
  throw new ZLinkConfigurationException(
@@ -666,16 +691,16 @@ export class DefaultZLinkSpotManager {
666
691
  }
667
692
  }
668
693
  if (pending === undefined) {
669
- const metric = this.options.metrics?.startInstanceSpotActivation(meshName, instanceType);
694
+ if (completion === 'first-terminal') this.activations.stage(meshName, spotId);
670
695
  pending = this.activationLifecycle
671
696
  .materializeInstance(meshName, instanceType, factory, spotId, objectGeneration, signal)
672
697
  .then(
673
- (activation) => {
674
- metric?.complete('ready');
698
+ async (activation) => {
699
+ if (completion === 'publication') await activation.serialExecutor.finishPreparation();
675
700
  return activation;
676
701
  },
677
702
  (error) => {
678
- metric?.complete(instanceActivationOutcome(error));
703
+ this.activations.abandonStage(meshName, spotId);
679
704
  throw error;
680
705
  }
681
706
  );
@@ -723,10 +748,16 @@ export class DefaultZLinkSpotManager {
723
748
  ? this.activations.resolveUnique(spotId)
724
749
  : this.activations.resolve(meshName, spotId);
725
750
  if (current !== undefined) return current;
726
- if (meshName !== undefined)
727
- return this.closeOperations.get(`${meshName}\0${String(spotId)}`)?.activation;
751
+ if (meshName !== undefined) {
752
+ const closing = this.closeOperations.get(`${meshName}\0${String(spotId)}`);
753
+ return closing?.authority === undefined ? undefined : closing.activation;
754
+ }
728
755
  for (const operation of this.closeOperations.values()) {
729
- if (String(operation.activation.spotId) === String(spotId)) return operation.activation;
756
+ if (
757
+ operation.authority !== undefined &&
758
+ String(operation.activation.spotId) === String(spotId)
759
+ )
760
+ return operation.activation;
730
761
  }
731
762
  return undefined;
732
763
  }
@@ -735,6 +766,7 @@ export class DefaultZLinkSpotManager {
735
766
  const prefix = instanceMaterializationPrefix(meshName, spotId);
736
767
  return (
737
768
  (this.pendingInstanceMaterializationsByPrefix.get(prefix)?.size ?? 0) > 0 ||
769
+ this.activations.activationForClose(meshName, spotId)?.serialExecutor.isPreparing === true ||
738
770
  this.closeOperations.get(`${meshName}\0${String(spotId)}`)?.authority !== undefined
739
771
  );
740
772
  }
@@ -751,7 +783,7 @@ export class DefaultZLinkSpotManager {
751
783
  }
752
784
 
753
785
  async discardInstance(meshName: string, spotId: RoutingId): Promise<void> {
754
- const activation = this.activations.resolve(meshName, spotId);
786
+ const activation = this.activations.activationForClose(meshName, spotId);
755
787
  if (activation === undefined) return;
756
788
  activation.requestClose();
757
789
  const operation = this.activations.startClose(
@@ -801,6 +833,9 @@ export class DefaultZLinkSpotManager {
801
833
  objectGeneration: bigint
802
834
  ): Promise<boolean> {
803
835
  const key = `${meshName}\0${String(spotId)}`;
836
+ const activation = this.activations.activationForClose(meshName, spotId);
837
+ if (activation?.objectGeneration === objectGeneration)
838
+ await activation.serialExecutor.finishPreparation();
804
839
  const pending = this.pendingInstanceTerminals.get(key);
805
840
  if (pending === undefined) return false;
806
841
  this.removePendingInstanceTerminalGeneration(key, objectGeneration);
@@ -847,6 +882,17 @@ export class DefaultZLinkSpotManager {
847
882
  this.pendingInstanceTerminalGenerations.set(key, generations);
848
883
  }
849
884
 
885
+ publishInstance(
886
+ target: { readonly targetSpotId: string; readonly objectGeneration: bigint },
887
+ meshName: string
888
+ ): void {
889
+ const activation = this.activations.activationForClose(meshName, target.targetSpotId);
890
+ if (activation?.objectGeneration === target.objectGeneration) {
891
+ const published = this.activations.publish(meshName, target.targetSpotId);
892
+ published?.serialExecutor.openPreparationAdmission();
893
+ }
894
+ }
895
+
850
896
  private deferInstanceAuthorityRelease(key: string, objectGeneration: bigint): void {
851
897
  const generations = this.deferredInstanceAuthorityReleases.get(key) ?? new Set<bigint>();
852
898
  generations.add(objectGeneration);
@@ -1077,19 +1123,24 @@ export class DefaultZLinkSpotManager {
1077
1123
  }
1078
1124
 
1079
1125
  async drainForShutdown(meshName: string, signal?: AbortSignal, deadline?: Date): Promise<void> {
1080
- const results = await Promise.allSettled(
1081
- this.activations
1082
- .activeActivations()
1083
- .filter((activation) => activation.meshName === meshName)
1084
- .map((activation) =>
1085
- this.closeWithReason(
1086
- meshName,
1087
- activation.spotId,
1088
- signal,
1089
- ZLinkSpotCloseReason.HostShutdown,
1090
- deadline
1126
+ // The host bounds observation of the whole Close, including lifecycle admission.
1127
+ // The owned operation keeps the gate and scopes until its running turns settle.
1128
+ const results = await awaitWithAbort(
1129
+ Promise.allSettled(
1130
+ this.activations
1131
+ .activeActivations()
1132
+ .filter((activation) => activation.meshName === meshName)
1133
+ .map((activation) =>
1134
+ this.closeWithReason(
1135
+ meshName,
1136
+ activation.spotId,
1137
+ undefined,
1138
+ ZLinkSpotCloseReason.HostShutdown,
1139
+ deadline
1140
+ )
1091
1141
  )
1092
- )
1142
+ ),
1143
+ signal
1093
1144
  );
1094
1145
  const errors = results
1095
1146
  .filter((result): result is PromiseRejectedResult => result.status === 'rejected')
@@ -1127,7 +1178,10 @@ export class DefaultZLinkSpotManager {
1127
1178
  ): Promise<boolean> {
1128
1179
  const { meshName, spotId } = activation;
1129
1180
  const operation = this.closeOperations.get(`${meshName}\0${String(spotId)}`);
1130
- const current = operation?.activation ?? this.activations.resolve(meshName, spotId);
1181
+ const current =
1182
+ operation?.activation ??
1183
+ this.activations.resolve(meshName, spotId) ??
1184
+ (activation.serialExecutor.isPreparing ? activation : undefined);
1131
1185
  if (current === undefined) {
1132
1186
  return Promise.resolve(false);
1133
1187
  }
@@ -1150,7 +1204,8 @@ export class DefaultZLinkSpotManager {
1150
1204
  signal,
1151
1205
  ZLinkSpotCloseReason.ExplicitClose,
1152
1206
  undefined,
1153
- beginUserAuthority
1207
+ beginUserAuthority,
1208
+ activation
1154
1209
  );
1155
1210
  }
1156
1211
 
@@ -1164,13 +1219,14 @@ export class DefaultZLinkSpotManager {
1164
1219
  onCommitted: () => void
1165
1220
  ) => Promise<
1166
1221
  import('../locations/spot-location-claims').ZLinkInstanceClosingAuthority | undefined
1167
- >
1222
+ >,
1223
+ contextActivation?: ZLinkSpotActivation
1168
1224
  ): Promise<boolean> {
1169
1225
  requireMeshName(meshName);
1170
1226
  const key = `${meshName}\0${String(spotId)}`;
1171
1227
  let operation = this.closeOperations.get(key);
1172
1228
  if (operation === undefined) {
1173
- const activation = this.activations.resolve(meshName, spotId);
1229
+ const activation = this.activations.resolve(meshName, spotId) ?? contextActivation;
1174
1230
  if (activation === undefined) return false;
1175
1231
  if (
1176
1232
  activation.domain.kind === 'user' &&
@@ -1243,10 +1299,11 @@ export class DefaultZLinkSpotManager {
1243
1299
  signal?: AbortSignal,
1244
1300
  deadline?: Date
1245
1301
  ): Promise<boolean> {
1302
+ if (this.activations.resolve(meshName, spotId) !== operation.activation) return false;
1246
1303
  const seal = await this.beginCloseAuthority(meshName, spotId, operation, signal);
1247
1304
  if (seal === undefined) return false;
1248
1305
  if (seal !== true) {
1249
- await this.activationLifecycle.sealForClose(operation.activation, seal);
1306
+ await this.activationLifecycle.sealForClose(operation.activation, seal, signal);
1250
1307
  } else {
1251
1308
  await operation.activation.executionBarrier.waitForStartedTurns(signal);
1252
1309
  }
@@ -1418,12 +1475,19 @@ export class DefaultZLinkSpotManager {
1418
1475
  this.activations.stage(meshName, spotId);
1419
1476
  }
1420
1477
 
1421
- publishUserSpot(meshName: string, spotId: RoutingId): void {
1422
- this.activations.publish(meshName, spotId);
1478
+ async publishUserSpot(meshName: string, spotId: RoutingId): Promise<void> {
1479
+ const published = this.activations.publish(meshName, spotId);
1480
+ await published?.serialExecutor.finishPreparation();
1423
1481
  }
1424
1482
 
1425
- abortUserSpotPublication(meshName: string, spotId: RoutingId): void {
1483
+ async abortUserSpotPublication(meshName: string, spotId: RoutingId): Promise<void> {
1426
1484
  this.activations.abandonStage(meshName, spotId);
1485
+ const activation = this.activations.activationForClose(meshName, spotId);
1486
+ if (activation?.serialExecutor.isPreparing === true) {
1487
+ await this.activationLifecycle.cleanupFailedIncarnation(activation);
1488
+ this.activations.finishClose(meshName, spotId);
1489
+ await activation.serialExecutor.close();
1490
+ }
1427
1491
  }
1428
1492
 
1429
1493
  resolveLocalSpotRoute(spotId: RoutingId): ZLinkSpotRouteTarget | undefined {
@@ -1509,14 +1573,6 @@ export class DefaultZLinkSpotManager {
1509
1573
  await this.actorMembership.commitActorLeaveAfterTransfer(spotId, actorId);
1510
1574
  }
1511
1575
 
1512
- async restoreActorAfterFailedTransfer(
1513
- spotId: RoutingId,
1514
- actor: ZLinkActor,
1515
- signal?: AbortSignal
1516
- ): Promise<void> {
1517
- await this.actorMembership.restoreActorAfterFailedTransfer(spotId, actor, signal);
1518
- }
1519
-
1520
1576
  async beginActorTransfer(spotId: RoutingId, actorId: string): Promise<void> {
1521
1577
  await this.actorMembership.beginActorTransfer(spotId, actorId);
1522
1578
  }
@@ -1595,6 +1651,24 @@ export class DefaultZLinkSpotManager {
1595
1651
  return this.activationLifecycle.admitActorPacketPrefix(activation, actorId, records);
1596
1652
  }
1597
1653
 
1654
+ /** Resolves the current Actor FIFO owner for both Entry and User membership. */
1655
+ admitSourceActorPacketPrefix(
1656
+ actorId: string,
1657
+ records: readonly ZLinkActorHandoffPrefixRecord[]
1658
+ ): ZLinkActorHandoffPrefixAdmission {
1659
+ const owner = this.options.actorDispatchOwnerResolver?.(actorId);
1660
+ if (owner?.actorRef === undefined) {
1661
+ throw new ZLinkConfigurationException(`Actor '${actorId}' has no local FIFO owner.`);
1662
+ }
1663
+ if (owner.spotId === undefined) {
1664
+ if (this.options.admitEntryActorPacketPrefix === undefined) {
1665
+ throw new ZLinkConfigurationException(`Actor '${actorId}' has no Entry FIFO port.`);
1666
+ }
1667
+ return this.options.admitEntryActorPacketPrefix(owner.actorRef.meshName, actorId, records);
1668
+ }
1669
+ return this.admitRoutedActorPacketPrefix(owner.spotId, actorId, records);
1670
+ }
1671
+
1598
1672
  async dispatchRoutedSpotSend(
1599
1673
  spotId: RoutingId,
1600
1674
  packetName: string | undefined,
@@ -1620,6 +1694,7 @@ export class DefaultZLinkSpotManager {
1620
1694
  readonly workOptions?: import('../execution/serial-execution-queue').ZLinkSerialWorkOptions;
1621
1695
  readonly admissionTimeoutMs?: number;
1622
1696
  readonly signal?: AbortSignal;
1697
+ readonly onAdmitted?: () => void;
1623
1698
  }
1624
1699
  ): Promise<TReply> {
1625
1700
  return await this.routedSpotPackets.request<TReply>(spotId, packetName, request, context);
@@ -1628,14 +1703,15 @@ export class DefaultZLinkSpotManager {
1628
1703
  async dispatchMeshSpot(
1629
1704
  meshName: string,
1630
1705
  owner: ReadyRecord,
1631
- record: ReceiveRecord
1706
+ record: ReceiveRecord,
1707
+ admit?: ZLinkMeshDispatchAdmission
1632
1708
  ): Promise<void> {
1633
1709
  const spotId = owner.spotId as unknown as RoutingId | null;
1634
1710
  if (spotId === null) {
1635
1711
  throw new ZLinkConfigurationException('MeshNode Spot record is missing the owner Spot RID.');
1636
1712
  }
1637
1713
  if (record.kind === ReceiveKind.SpotMulticast) {
1638
- const activation = this.activations.resolve(meshName, spotId);
1714
+ const activation = this.activations.activationForClose(meshName, spotId);
1639
1715
  if (activation?.actorDispatch === undefined) {
1640
1716
  throw new ZLinkConfigurationException(
1641
1717
  `MeshNode Spot multicast target '${String(spotId)}' is not active.`
@@ -1646,11 +1722,13 @@ export class DefaultZLinkSpotManager {
1646
1722
  'MeshNode Spot multicast record is missing its topic.'
1647
1723
  );
1648
1724
  }
1649
- await activation.actorDispatch.dispatchSubscriptionRecord(
1650
- record.topic,
1651
- record.parts,
1652
- record.sourceNodeRid as unknown as RoutingId | null
1653
- );
1725
+ const dispatch = () =>
1726
+ activation.actorDispatch!.dispatchSubscriptionRecord(
1727
+ record.topic!,
1728
+ record.parts,
1729
+ record.sourceNodeRid as unknown as RoutingId | null
1730
+ );
1731
+ await (admit === undefined ? dispatch() : admit(dispatch));
1654
1732
  return;
1655
1733
  }
1656
1734
  const envelope = decodeChannelEnvelope(
@@ -1672,28 +1750,32 @@ export class DefaultZLinkSpotManager {
1672
1750
  record.applicationMetadata?.byteLength ?? zlinkMetadataByteLength(envelope.header.metadata)
1673
1751
  )
1674
1752
  };
1675
- if (record.kind === ReceiveKind.SpotSend) {
1676
- await this.ensureInstanceApplicationActivation(meshName, spotId);
1677
- await this.routedSpotPackets.sendEncoded(spotId, packetName, decodePayload, context);
1678
- return;
1679
- }
1680
- if (record.kind !== ReceiveKind.SpotRequest) {
1681
- throw new ZLinkConfigurationException(
1682
- `Unsupported MeshNode Spot record kind '${record.kind}'.`
1683
- );
1684
- }
1685
1753
  try {
1686
- await this.ensureInstanceApplicationActivation(meshName, spotId);
1687
- const response = await this.routedSpotPackets.requestEncoded(
1688
- spotId,
1689
- packetName,
1690
- decodePayload,
1691
- context
1692
- );
1693
- requireMeshSpotReply(
1694
- record.reply(encodeChannelReplyParts(envelope.header, response, codecs))
1695
- );
1754
+ const dispatch = async () => {
1755
+ if (record.kind === ReceiveKind.SpotSend) {
1756
+ await this.ensureInstanceApplicationActivation(meshName, spotId);
1757
+ await this.routedSpotPackets.sendEncoded(spotId, packetName, decodePayload, context);
1758
+ return;
1759
+ }
1760
+ if (record.kind !== ReceiveKind.SpotRequest) {
1761
+ throw new ZLinkConfigurationException(
1762
+ `Unsupported MeshNode Spot record kind '${record.kind}'.`
1763
+ );
1764
+ }
1765
+ await this.ensureInstanceApplicationActivation(meshName, spotId);
1766
+ const response = await this.routedSpotPackets.requestEncoded(
1767
+ spotId,
1768
+ packetName,
1769
+ decodePayload,
1770
+ context
1771
+ );
1772
+ requireMeshSpotReply(
1773
+ record.reply(encodeChannelReplyParts(envelope.header, response, codecs))
1774
+ );
1775
+ };
1776
+ await (admit === undefined ? dispatch() : admit(dispatch));
1696
1777
  } catch (error) {
1778
+ if (record.kind !== ReceiveKind.SpotRequest) throw error;
1697
1779
  requireMeshSpotReply(record.reply(encodeChannelErrorReplyParts(envelope.header, error)));
1698
1780
  }
1699
1781
  }
@@ -1728,7 +1810,8 @@ export class DefaultZLinkSpotManager {
1728
1810
  async dispatchMeshInstance(
1729
1811
  meshName: string,
1730
1812
  owner: ReadyRecord,
1731
- record: ReceiveRecord
1813
+ record: ReceiveRecord,
1814
+ admit?: ZLinkMeshDispatchAdmission
1732
1815
  ): Promise<void> {
1733
1816
  const spotId = owner.spotId as unknown as RoutingId | null;
1734
1817
  if (spotId === null) {
@@ -1758,75 +1841,111 @@ export class DefaultZLinkSpotManager {
1758
1841
  'activating'
1759
1842
  );
1760
1843
  try {
1761
- await this.ensureInstanceApplicationActivation(meshName, spotId);
1762
- const activation = this.resolveApplicationActivation(spotId, meshName);
1763
- if (activation === undefined || activation.domain.kind !== 'instance') {
1764
- throw new ZLinkConfigurationException(
1765
- `MeshNode Instance Spot target '${String(spotId)}' is not active.`
1766
- );
1767
- }
1768
- const target = this.options.instanceSpotApplicationTargetProvider?.(meshName, spotId);
1769
- if (
1770
- target !== undefined &&
1771
- activation.domain.objectGeneration !== target.objectGeneration
1772
- ) {
1773
- throw createInternalFrameworkException(
1774
- ZLinkFrameworkInternalErrorKind.SpotGenerationStale,
1775
- `Instance Spot target '${String(spotId)}' application generation is stale.`
1844
+ const dispatch = async () => {
1845
+ await this.ensureInstanceApplicationActivation(meshName, spotId);
1846
+ const activation = this.resolveApplicationActivation(spotId, meshName);
1847
+ if (activation === undefined || activation.domain.kind !== 'instance') {
1848
+ throw new ZLinkConfigurationException(
1849
+ `MeshNode Instance Spot target '${String(spotId)}' is not active.`
1850
+ );
1851
+ }
1852
+ const target = this.options.instanceSpotApplicationTargetProvider?.(meshName, spotId);
1853
+ if (
1854
+ target !== undefined &&
1855
+ activation.domain.objectGeneration !== target.objectGeneration
1856
+ ) {
1857
+ throw createInternalFrameworkException(
1858
+ ZLinkFrameworkInternalErrorKind.SpotGenerationStale,
1859
+ `Instance Spot target '${String(spotId)}' application generation is stale.`
1860
+ );
1861
+ }
1862
+ const codecs =
1863
+ this.options.messageSerializers === undefined
1864
+ ? undefined
1865
+ : { serializers: this.options.messageSerializers };
1866
+ const decodePayload = () => decodeChannelPayload(envelope, codecs);
1867
+ const context = {
1868
+ channelName: envelope.header.channelName,
1869
+ contentType: envelope.header.contentType,
1870
+ awaitFirstHandlerTurn: record.kind === ReceiveKind.InstanceSpotActivation,
1871
+ activationRecord: record,
1872
+ onOneWayError:
1873
+ this.options.dispatchErrors?.captureEnabled() === true
1874
+ ? (error: unknown) =>
1875
+ this.reportInstanceDispatchFailure(
1876
+ meshName,
1877
+ spotId,
1878
+ record,
1879
+ envelope,
1880
+ false,
1881
+ error
1882
+ )
1883
+ : undefined,
1884
+ workOptions: zlinkSerialWorkOptions(
1885
+ envelope.payload.byteLength,
1886
+ record.applicationMetadata?.byteLength ??
1887
+ zlinkMetadataByteLength(envelope.header.metadata)
1888
+ )
1889
+ };
1890
+ // Spot messaging §7 step 3: an Instance intent request that reaches an
1891
+ // incarnation whose Close ended admission is refused before admission
1892
+ // with the owner fence terminal, so its caller re-reads authority.
1893
+ const instanceIntent =
1894
+ record.activationRecord?.activation === 'missing' ||
1895
+ (record.activationRecord?.activation === 'ready' &&
1896
+ record.activationRecord.instanceIntent);
1897
+ const refusal = activation.serial.applicationAdmissionRefusal(instanceIntent === true);
1898
+ if (request && refusal !== undefined && record.replyFailure !== undefined) {
1899
+ this.reportInstanceDispatchFailure(
1900
+ meshName,
1901
+ spotId,
1902
+ record,
1903
+ envelope,
1904
+ request,
1905
+ refusal
1906
+ );
1907
+ const terminal = internalFrameworkWireReply(refusal);
1908
+ requireMeshSpotReply(
1909
+ record.replyFailure(terminal.terminalResult, terminal.failureCode)
1910
+ );
1911
+ return;
1912
+ }
1913
+ this.traceInstanceMessage(
1914
+ ZLinkMessageFlowOutcome.Admitted,
1915
+ meshName,
1916
+ spotId,
1917
+ record,
1918
+ envelope,
1919
+ 'ready',
1920
+ target?.stableType
1776
1921
  );
1777
- }
1778
- const codecs =
1779
- this.options.messageSerializers === undefined
1780
- ? undefined
1781
- : { serializers: this.options.messageSerializers };
1782
- const decodePayload = () => decodeChannelPayload(envelope, codecs);
1783
- const context = {
1784
- channelName: envelope.header.channelName,
1785
- contentType: envelope.header.contentType,
1786
- awaitFirstHandlerTurn: record.kind === ReceiveKind.InstanceSpotActivation,
1787
- activationRecord: record,
1788
- onOneWayError:
1789
- this.options.dispatchErrors?.captureEnabled() === true
1790
- ? (error: unknown) =>
1791
- this.reportInstanceDispatchFailure(
1792
- meshName,
1793
- spotId,
1794
- record,
1795
- envelope,
1796
- false,
1797
- error
1798
- )
1799
- : undefined,
1800
- workOptions: zlinkSerialWorkOptions(
1801
- envelope.payload.byteLength,
1802
- record.applicationMetadata?.byteLength ??
1803
- zlinkMetadataByteLength(envelope.header.metadata)
1804
- )
1805
- };
1806
- // Spot messaging §7 step 3: an Instance intent request that reaches an
1807
- // incarnation whose Close ended admission is refused before admission
1808
- // with the owner fence terminal, so its caller re-reads authority.
1809
- const instanceIntent =
1810
- record.activationRecord?.activation === 'missing' ||
1811
- (record.activationRecord?.activation === 'ready' &&
1812
- record.activationRecord.instanceIntent);
1813
- const refusal = activation.serial.applicationAdmissionRefusal(instanceIntent === true);
1814
- if (request && refusal !== undefined && record.replyFailure !== undefined) {
1815
- this.reportInstanceDispatchFailure(meshName, spotId, record, envelope, request, refusal);
1816
- const terminal = internalFrameworkWireReply(refusal);
1817
- requireMeshSpotReply(record.replyFailure(terminal.terminalResult, terminal.failureCode));
1818
- return;
1819
- }
1820
- this.traceInstanceMessage(
1821
- ZLinkMessageFlowOutcome.Admitted,
1822
- meshName,
1823
- spotId,
1824
- record,
1825
- envelope,
1826
- 'ready',
1827
- target?.stableType
1828
- );
1829
- if (!request) {
1922
+ if (!request) {
1923
+ this.traceInstanceMessage(
1924
+ ZLinkMessageFlowOutcome.Dispatched,
1925
+ meshName,
1926
+ spotId,
1927
+ record,
1928
+ envelope,
1929
+ 'ready',
1930
+ target?.stableType
1931
+ );
1932
+ await this.routedSpotPackets.sendEncoded(
1933
+ spotId,
1934
+ envelope.packetName,
1935
+ decodePayload,
1936
+ context
1937
+ );
1938
+ this.traceInstanceMessage(
1939
+ ZLinkMessageFlowOutcome.Completed,
1940
+ meshName,
1941
+ spotId,
1942
+ record,
1943
+ envelope,
1944
+ 'ready',
1945
+ target?.stableType
1946
+ );
1947
+ return;
1948
+ }
1830
1949
  this.traceInstanceMessage(
1831
1950
  ZLinkMessageFlowOutcome.Dispatched,
1832
1951
  meshName,
@@ -1836,14 +1955,17 @@ export class DefaultZLinkSpotManager {
1836
1955
  'ready',
1837
1956
  target?.stableType
1838
1957
  );
1839
- await this.routedSpotPackets.sendEncoded(
1958
+ const response = await this.routedSpotPackets.requestEncoded(
1840
1959
  spotId,
1841
1960
  envelope.packetName,
1842
1961
  decodePayload,
1843
1962
  context
1844
1963
  );
1964
+ requireMeshSpotReply(
1965
+ record.reply(encodeChannelReplyParts(envelope.header, response, codecs))
1966
+ );
1845
1967
  this.traceInstanceMessage(
1846
- ZLinkMessageFlowOutcome.Completed,
1968
+ ZLinkMessageFlowOutcome.Replied,
1847
1969
  meshName,
1848
1970
  spotId,
1849
1971
  record,
@@ -1851,35 +1973,8 @@ export class DefaultZLinkSpotManager {
1851
1973
  'ready',
1852
1974
  target?.stableType
1853
1975
  );
1854
- return;
1855
- }
1856
- this.traceInstanceMessage(
1857
- ZLinkMessageFlowOutcome.Dispatched,
1858
- meshName,
1859
- spotId,
1860
- record,
1861
- envelope,
1862
- 'ready',
1863
- target?.stableType
1864
- );
1865
- const response = await this.routedSpotPackets.requestEncoded(
1866
- spotId,
1867
- envelope.packetName,
1868
- decodePayload,
1869
- context
1870
- );
1871
- requireMeshSpotReply(
1872
- record.reply(encodeChannelReplyParts(envelope.header, response, codecs))
1873
- );
1874
- this.traceInstanceMessage(
1875
- ZLinkMessageFlowOutcome.Replied,
1876
- meshName,
1877
- spotId,
1878
- record,
1879
- envelope,
1880
- 'ready',
1881
- target?.stableType
1882
- );
1976
+ };
1977
+ await (admit === undefined ? dispatch() : admit(dispatch));
1883
1978
  } catch (error) {
1884
1979
  this.reportInstanceDispatchFailure(meshName, spotId, record, envelope, request, error);
1885
1980
  const reason = dispatchReasonFromError(error);
@@ -1974,7 +2069,8 @@ export class DefaultZLinkSpotManager {
1974
2069
  origin: ApplicationJobOrigin,
1975
2070
  meshName: string,
1976
2071
  owner: ReadyRecord,
1977
- record: ReceiveRecord
2072
+ record: ReceiveRecord,
2073
+ admit?: ZLinkMeshDispatchAdmission
1978
2074
  ): Promise<void> {
1979
2075
  const spotId = owner.spotId as unknown as RoutingId | null;
1980
2076
  const entrySpotId = this.options.entryNodeRidProvider?.() ?? this.options.entryNodeRid;
@@ -1985,12 +2081,15 @@ export class DefaultZLinkSpotManager {
1985
2081
  throw new ZLinkConfigurationException('MeshNode Actor record is missing its Actor owner.');
1986
2082
  }
1987
2083
  const request = record.kind === ReceiveKind.ActorRequest;
1988
- const resolvedOwner = this.options.actorDispatchOwnerResolver?.(actor.actorId);
1989
- const resolvedActorRef = resolvedOwner?.actorRef ?? {
1990
- actorId: actor.actorId,
1991
- objectGeneration: actor.generation,
2084
+ const nativeTarget = record.messageFollowOrigin?.target;
2085
+ const ingressActor = nativeTarget?.actor ?? actor;
2086
+ const resolvedActorRef = (nativeTarget === undefined
2087
+ ? this.options.actorDispatchOwnerResolver?.(actor.actorId).actorRef
2088
+ : undefined) ?? {
2089
+ actorId: ingressActor.actorId,
2090
+ objectGeneration: ingressActor.generation,
1992
2091
  meshName,
1993
- nodeRid: String(actor.nodeRid)
2092
+ nodeRid: ingressActor.nodeRid
1994
2093
  };
1995
2094
  const responseActorRef =
1996
2095
  record.sourceBindingGeneration > 0n
@@ -2029,43 +2128,49 @@ export class DefaultZLinkSpotManager {
2029
2128
  )
2030
2129
  : undefined;
2031
2130
  try {
2032
- if (this.formalRemoteTransfers.has(actor.actorId)) {
2033
- throw new Error(`Actor '${actor.actorId}' target transfer reconciliation is not complete.`);
2034
- }
2035
- const response = targetsEntrySpot
2036
- ? await this.options.dispatchEntryActorPacket?.(
2037
- origin,
2038
- actor.actorId,
2039
- record.parts,
2040
- request,
2041
- undefined,
2042
- ownerActorRef,
2043
- requestTerminal,
2044
- record.messageFollowOrigin
2045
- )
2046
- : await this.dispatchMeshActorPacket(
2047
- origin,
2048
- meshName,
2049
- spotId,
2050
- actor.actorId,
2051
- record.parts,
2052
- request,
2053
- ownerActorRef,
2054
- requestTerminal,
2055
- record.messageFollowOrigin
2131
+ const dispatch = async () => {
2132
+ if (this.formalRemoteTransfers.has(actor.actorId)) {
2133
+ throw new Error(
2134
+ `Actor '${actor.actorId}' target transfer reconciliation is not complete.`
2056
2135
  );
2057
- if (targetsEntrySpot && this.options.dispatchEntryActorPacket === undefined) {
2058
- throw new ZLinkConfigurationException(
2059
- 'MeshNode Entry Spot Actor dispatch is not configured.'
2060
- );
2061
- }
2062
- if (request && !requestTerminalState.submitted) {
2063
- requireMeshSpotReply(
2064
- record.reply(
2065
- this.encodeMeshActorReply(record.parts[0], ZLinkStreamMessageKind.Response, response)
2066
- )
2067
- );
2068
- }
2136
+ }
2137
+ const response = targetsEntrySpot
2138
+ ? await this.options.dispatchEntryActorPacket?.(
2139
+ origin,
2140
+ actor.actorId,
2141
+ record.parts,
2142
+ request,
2143
+ undefined,
2144
+ ownerActorRef,
2145
+ requestTerminal,
2146
+ record.messageFollowOrigin
2147
+ )
2148
+ : await this.dispatchMeshActorPacket(
2149
+ origin,
2150
+ meshName,
2151
+ spotId,
2152
+ actor.actorId,
2153
+ record.parts,
2154
+ request,
2155
+ ownerActorRef,
2156
+ requestTerminal,
2157
+ record.messageFollowOrigin
2158
+ );
2159
+ if (targetsEntrySpot && this.options.dispatchEntryActorPacket === undefined) {
2160
+ throw new ZLinkConfigurationException(
2161
+ 'MeshNode Entry Spot Actor dispatch is not configured.'
2162
+ );
2163
+ }
2164
+ if (response === RELOCATED_REQUEST_OWNED_BY_REQUESTER) return;
2165
+ if (request && !requestTerminalState.submitted) {
2166
+ requireMeshSpotReply(
2167
+ record.reply(
2168
+ this.encodeMeshActorReply(record.parts[0], ZLinkStreamMessageKind.Response, response)
2169
+ )
2170
+ );
2171
+ }
2172
+ };
2173
+ await (admit === undefined ? dispatch() : admit(dispatch));
2069
2174
  } catch (error) {
2070
2175
  if (!request) {
2071
2176
  throw error;
@@ -2075,10 +2180,11 @@ export class DefaultZLinkSpotManager {
2075
2180
  }
2076
2181
  requireMeshSpotReply(
2077
2182
  record.reply(
2078
- this.encodeMeshActorReply(record.parts[0], ZLinkStreamMessageKind.Error, {
2079
- message: error instanceof Error ? error.message : String(error),
2080
- kind: spotActorFailureKind(error)
2081
- })
2183
+ this.encodeMeshActorReply(
2184
+ record.parts[0],
2185
+ ZLinkStreamMessageKind.Error,
2186
+ boundSessionErrorPayload(error)
2187
+ )
2082
2188
  )
2083
2189
  );
2084
2190
  }
@@ -2866,11 +2972,7 @@ export class DefaultZLinkSpotManager {
2866
2972
  control.previousMembershipEpoch
2867
2973
  );
2868
2974
  };
2869
- if (this.options.actorTransferRuntime === undefined) {
2870
- await callback();
2871
- } else {
2872
- await this.options.actorTransferRuntime.notifyCoreSourceLeave(actor, callback);
2873
- }
2975
+ await callback();
2874
2976
  return;
2875
2977
  }
2876
2978
  if (spotId === null) {
@@ -2961,7 +3063,7 @@ export class DefaultZLinkSpotManager {
2961
3063
  // ingress hold) migrate into the real Actor queue next, in the
2962
3064
  // order they parked — after the relayed backlog above, before
2963
3065
  // regular ingress opens.
2964
- await this.migrateActorJoinPrewarm(activation, actor, pendingTransfer.transferId);
3066
+ this.migrateActorJoinPrewarm(activation, actor, pendingTransfer.transferId);
2965
3067
  // This registry owns target lifecycle and saved backlog
2966
3068
  // reconciliation only. Session route readiness is enforced by
2967
3069
  // the Session binding aggregate after this boundary.
@@ -3034,9 +3136,7 @@ export class DefaultZLinkSpotManager {
3034
3136
  if (sourceJoinedActor === undefined && pendingTransfer === undefined) {
3035
3137
  return;
3036
3138
  }
3037
- await this.options.actorTransferRuntime.notifyCoreSourceLeave(actor, () =>
3038
- activation.spot.onLeaveActor(actor)
3039
- );
3139
+ await activation.spot.onLeaveActor(actor);
3040
3140
  }
3041
3141
  activation.commitActorDeparture(actor.context.actorId);
3042
3142
  return;
@@ -3075,7 +3175,7 @@ export class DefaultZLinkSpotManager {
3075
3175
  }
3076
3176
  const outcome = admission.result ?? (await admission.resultTask);
3077
3177
  if ('error' in outcome) throw outcome.error;
3078
- if (!outcome.accepted || admission.state !== 'admitted') {
3178
+ if (!outcome.accepted || (admission.state !== 'admitted' && admission.state !== 'restoring')) {
3079
3179
  throw new Error(`Actor Join relocation '${relocationId}' has no accepted admission.`);
3080
3180
  }
3081
3181
  const entrySpotId = this.options.entryNodeRidProvider?.() ?? this.options.entryNodeRid;
@@ -3096,6 +3196,19 @@ export class DefaultZLinkSpotManager {
3096
3196
  }
3097
3197
  } catch (error) {
3098
3198
  lifecycleFailure = { error };
3199
+ const reporter = this.options.dispatchErrors;
3200
+ if (reporter?.captureEnabled() === true) {
3201
+ reporter.report({
3202
+ surface: ZLinkDispatchErrorSurface.ActorRelocation,
3203
+ messageKind: ZLinkDispatchMessageKind.Control,
3204
+ reason: dispatchReasonFromError(error),
3205
+ action: ZLinkDispatchErrorAction.FailCaller,
3206
+ packetName: 'OnJoinedActor',
3207
+ meshName,
3208
+ actorId: actor.context.actorId,
3209
+ error
3210
+ });
3211
+ }
3099
3212
  }
3100
3213
  if (lifecycleFailure === undefined) {
3101
3214
  const sourceLeave = submitSourceLeave(admission.admission.actorRef.nodeRid);
@@ -3114,7 +3227,7 @@ export class DefaultZLinkSpotManager {
3114
3227
  if (activation === undefined) {
3115
3228
  throw new Error(`Actor Join relocation '${relocationId}' target mailbox is missing.`);
3116
3229
  }
3117
- return activation.executeActor(actor.context.actorId, operation);
3230
+ return activation.executeActor(actor.context.actorId, operation, { lane: 'lifecycle' });
3118
3231
  };
3119
3232
  await this.options.actorTransferRuntime.deliverDeferredJoinCompletion(
3120
3233
  lifecycleFailure === undefined
@@ -3135,6 +3248,21 @@ export class DefaultZLinkSpotManager {
3135
3248
  return true;
3136
3249
  }
3137
3250
 
3251
+ beginActorJoinRelocation(relocationId: string): () => void {
3252
+ this.formalRemoteActorAdmissions.beginRestore(relocationId);
3253
+ return () => this.formalRemoteActorAdmissions.finishRestore(relocationId);
3254
+ }
3255
+
3256
+ /** @internal Transfers accepted ingress after the target Actor becomes visible. */
3257
+ openActorJoinRelocation(meshName: string, relocationId: string, actor: ZLinkActor): void {
3258
+ const admission = this.formalRemoteActorAdmissions.get(relocationId);
3259
+ if (admission === undefined) return;
3260
+ const activation = this.activations.resolve(meshName, admission.admission.spotId);
3261
+ if (activation !== undefined) {
3262
+ this.migrateActorJoinPrewarm(activation, actor, relocationId);
3263
+ }
3264
+ }
3265
+
3138
3266
  async restoreCanonicalActorJoinRecovery(
3139
3267
  recovery: CanonicalActorJoinRecovery,
3140
3268
  signal?: AbortSignal
@@ -3147,7 +3275,11 @@ export class DefaultZLinkSpotManager {
3147
3275
  );
3148
3276
  }
3149
3277
  const outcome = admission.result ?? (await admission.resultTask);
3150
- if ('error' in outcome || !outcome.accepted || admission.state !== 'admitted') {
3278
+ if (
3279
+ 'error' in outcome ||
3280
+ !outcome.accepted ||
3281
+ (admission.state !== 'admitted' && admission.state !== 'restoring')
3282
+ ) {
3151
3283
  throw new Error(
3152
3284
  `Actor Join recovery '${recovery.request.handoffId}' has no accepted admission.`
3153
3285
  );
@@ -3225,35 +3357,13 @@ export class DefaultZLinkSpotManager {
3225
3357
  kind: ZLinkStreamMessageKind.Response | ZLinkStreamMessageKind.Error,
3226
3358
  payload: unknown
3227
3359
  ): readonly Buffer[] {
3228
- // Spec 27 §4/§7: the decode gate strips the observation-only flow pair at
3229
- // Off (and skips its validation); when tracing is on the reply preserves
3230
- // the request's flow pair alongside its correlation.
3231
- const requestHeader = decodeStreamHeader(
3360
+ return encodeActorReply(
3232
3361
  requestHeaderPart.data(),
3362
+ kind,
3363
+ payload,
3364
+ this.options.messageSerializers,
3233
3365
  this.options.dispatchErrors?.flow.flowCreationEnabled() ?? true
3234
3366
  );
3235
- const encoded = encodeFrameworkPayload(payload, this.options.messageSerializers);
3236
- try {
3237
- // encodeStreamHeader returns a fresh, unaliased array; view it without
3238
- // re-copying. The payload copy stays: encoded.message closes below.
3239
- const replyHeader = encodeStreamHeader({
3240
- kind,
3241
- codec: streamCodecForContentType(encoded.contentType),
3242
- flags: ZLinkStreamHeaderFlags.None,
3243
- requestSeq: requestHeader.requestSeq,
3244
- name: '',
3245
- metadata: new Map(),
3246
- correlationId: requestHeader.correlationId,
3247
- flowId: requestHeader.flowId,
3248
- flowOrigin: requestHeader.flowOrigin
3249
- });
3250
- return [
3251
- Buffer.from(replyHeader.buffer, replyHeader.byteOffset, replyHeader.byteLength),
3252
- Buffer.from(encoded.message.data())
3253
- ];
3254
- } finally {
3255
- encoded.message.close();
3256
- }
3257
3367
  }
3258
3368
 
3259
3369
  private async createActivation<TSpot extends ZLinkSpot>(
@@ -3315,13 +3425,14 @@ export class DefaultZLinkSpotManager {
3315
3425
  * either lands in the snapshot or resolves the Actor directly through
3316
3426
  * ordinary ingress — never both, never neither.
3317
3427
  */
3318
- private async migrateActorJoinPrewarm(
3428
+ private migrateActorJoinPrewarm(
3319
3429
  activation: ZLinkSpotActivation,
3320
3430
  actor: ZLinkActor,
3321
3431
  transferId: string
3322
- ): Promise<void> {
3432
+ ): void {
3323
3433
  const drained = this.formalRemoteActorAdmissions.completeMigration(transferId);
3324
- for (const arrival of drained) {
3434
+ if (drained.length === 0) return;
3435
+ const terminals = drained.map(async (arrival) => {
3325
3436
  try {
3326
3437
  const response = await this.dispatchActorPacket(
3327
3438
  arrival.origin,
@@ -3337,7 +3448,16 @@ export class DefaultZLinkSpotManager {
3337
3448
  } catch (error) {
3338
3449
  arrival.reject(error);
3339
3450
  }
3340
- }
3451
+ });
3452
+ // Reserve every retained arrival's FIFO position before ordinary ingress
3453
+ // can resume. Handler terminals must not hold the relocation finalize that
3454
+ // releases an earlier saved-work prefix.
3455
+ this.options.detachedTaskRunner.runDetached(
3456
+ `actor Join ingress migration ${actor.context.actorId}`,
3457
+ async () => {
3458
+ await Promise.all(terminals);
3459
+ }
3460
+ );
3341
3461
  }
3342
3462
 
3343
3463
  private async dispatchMeshActorPacket(
@@ -3555,7 +3675,7 @@ function validateRemoteAdmissionCommit(
3555
3675
  expected.targetSpotGeneration !== (control.currentSpotGeneration ?? 0n) ||
3556
3676
  actorRef === undefined ||
3557
3677
  actorRef.actorId !== expected.actorRef.actorId ||
3558
- String(actorRef.nodeRid) !== String(expected.actorRef.nodeRid) ||
3678
+ !routingIdsEqual(actorRef.nodeRid, expected.actorRef.nodeRid) ||
3559
3679
  actorRef.objectGeneration !== expected.actorRef.objectGeneration
3560
3680
  ) {
3561
3681
  throw new ZLinkConfigurationException(
@@ -3603,17 +3723,3 @@ function isAbortSignal(value: unknown): value is AbortSignal {
3603
3723
  typeof (value as { addEventListener?: unknown }).addEventListener === 'function'
3604
3724
  );
3605
3725
  }
3606
-
3607
- function instanceActivationOutcome(error: unknown): string {
3608
- if (isAbortError(error)) return 'shutdown';
3609
- if (error instanceof ZLinkFrameworkException) {
3610
- if (error.kind === ZLinkFrameworkErrorKind.DeadlineExceeded) return 'timed_out';
3611
- if (error.kind === ZLinkFrameworkErrorKind.AlreadyExists) return 'conflict';
3612
- if (
3613
- error.kind === ZLinkFrameworkErrorKind.InvalidOperation ||
3614
- error.kind === ZLinkFrameworkErrorKind.Unavailable
3615
- )
3616
- return 'fenced';
3617
- }
3618
- return 'failed';
3619
- }