@zlink-systems/framework 0.30.1 → 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 (340) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/contracts/Common/ZLinkEncodedPayload.d.ts +6 -0
  3. package/dist/contracts/Common/ZLinkEncodedPayload.js +18 -3
  4. package/dist/contracts/Common/encoded-payload-storage.d.ts +1 -1
  5. package/dist/contracts/Common/encoded-payload-storage.js +5 -2
  6. package/dist/contracts/Configuration/Builders.d.ts +1 -1
  7. package/dist/contracts/Configuration/RegistrationBuilderPolicy.d.ts +2 -1
  8. package/dist/contracts/Configuration/RegistrationBuilderPolicy.js +5 -1
  9. package/dist/contracts/Configuration/RegistrationBuilders.js +2 -2
  10. package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -0
  11. package/dist/contracts/Dispatch/ZLinkDispatchOptions.d.ts +2 -2
  12. package/dist/contracts/Locations/Rows.d.ts +2 -0
  13. package/dist/contracts/Spots/Contracts.d.ts +4 -0
  14. package/dist/contracts/Spots/ZLinkSpot.d.ts +3 -3
  15. package/dist/runtime/abort.d.ts +5 -0
  16. package/dist/runtime/abort.js +10 -0
  17. package/dist/runtime/actors/actor-authority-publication.js +3 -2
  18. package/dist/runtime/actors/actor-client.d.ts +0 -1
  19. package/dist/runtime/actors/actor-client.js +38 -45
  20. package/dist/runtime/actors/actor-context.d.ts +2 -0
  21. package/dist/runtime/actors/actor-context.js +46 -9
  22. package/dist/runtime/actors/actor-handoff.d.ts +7 -3
  23. package/dist/runtime/actors/actor-handoff.js +212 -88
  24. package/dist/runtime/actors/actor-join-relocation.d.ts +2 -0
  25. package/dist/runtime/actors/actor-local-native-join.js +4 -0
  26. package/dist/runtime/actors/actor-mailbox.js +27 -1
  27. package/dist/runtime/actors/actor-remote-joiner.js +3 -1
  28. package/dist/runtime/actors/actor-reply.d.ts +4 -0
  29. package/dist/runtime/actors/actor-reply.js +29 -0
  30. package/dist/runtime/actors/actor-runtime-contracts.d.ts +2 -0
  31. package/dist/runtime/actors/actor-runtime-state.js +2 -20
  32. package/dist/runtime/actors/actor-source-transfer.d.ts +1 -17
  33. package/dist/runtime/actors/index.d.ts +6 -2
  34. package/dist/runtime/actors/index.js +37 -21
  35. package/dist/runtime/actors/session-disconnected-wire.d.ts +8 -0
  36. package/dist/runtime/actors/session-disconnected-wire.js +48 -0
  37. package/dist/runtime/admission.d.ts +9 -1
  38. package/dist/runtime/admission.js +55 -32
  39. package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +13 -0
  40. package/dist/runtime/application-jobs/application-job-queue-scope.js +27 -1
  41. package/dist/runtime/application-jobs/contracts.d.ts +2 -0
  42. package/dist/runtime/backend/contracts/index.d.ts +19 -3
  43. package/dist/runtime/backend/mesh-actor-session-node-adapter.js +2 -2
  44. package/dist/runtime/backend/mesh-completion-table.js +5 -0
  45. package/dist/runtime/backend/mesh-dispatch-pump.d.ts +26 -2
  46. package/dist/runtime/backend/mesh-dispatch-pump.js +193 -107
  47. package/dist/runtime/backend/node/node-raw-binding-port.js +90 -58
  48. package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +33 -8
  49. package/dist/runtime/backend/node/node-raw-mesh-backend.js +142 -143
  50. package/dist/runtime/backend/node/node-socket-backend-adapter.d.ts +1 -1
  51. package/dist/runtime/backend/node/node-socket-backend-adapter.js +5 -5
  52. package/dist/runtime/channels/channel-clients.d.ts +1 -0
  53. package/dist/runtime/channels/channel-clients.js +20 -5
  54. package/dist/runtime/channels/channel-dispatch-pipeline.d.ts +22 -3
  55. package/dist/runtime/channels/channel-dispatch-pipeline.js +103 -57
  56. package/dist/runtime/channels/channel-dispatchers.d.ts +3 -2
  57. package/dist/runtime/channels/channel-dispatchers.js +44 -37
  58. package/dist/runtime/channels/channel-envelope.d.ts +1 -0
  59. package/dist/runtime/channels/channel-envelope.js +74 -31
  60. package/dist/runtime/channels/channel-runtime-lifecycle.d.ts +4 -3
  61. package/dist/runtime/channels/channel-runtime-lifecycle.js +19 -24
  62. package/dist/runtime/channels/channel-runtime-manager.d.ts +3 -2
  63. package/dist/runtime/channels/channel-runtime-manager.js +4 -4
  64. package/dist/runtime/channels/channel-transports.d.ts +0 -1
  65. package/dist/runtime/channels/channel-transports.js +35 -33
  66. package/dist/runtime/channels/client-server-location-runtime.js +5 -4
  67. package/dist/runtime/channels/dispatch-error-reporter.d.ts +2 -1
  68. package/dist/runtime/channels/dispatch-error-reporter.js +2 -1
  69. package/dist/runtime/channels/fanout-location-runtime.d.ts +1 -1
  70. package/dist/runtime/channels/fanout-location-runtime.js +3 -3
  71. package/dist/runtime/diagnostics/flow-context.js +19 -7
  72. package/dist/runtime/diagnostics/index.js +4 -9
  73. package/dist/runtime/diagnostics/message-flow.d.ts +8 -0
  74. package/dist/runtime/diagnostics/message-flow.js +35 -5
  75. package/dist/runtime/diagnostics/runtime-metrics.d.ts +2 -2
  76. package/dist/runtime/diagnostics/runtime-metrics.js +10 -8
  77. package/dist/runtime/execution/index.d.ts +4 -2
  78. package/dist/runtime/execution/index.js +33 -10
  79. package/dist/runtime/execution/serial-execution-queue.d.ts +4 -0
  80. package/dist/runtime/execution/serial-execution-queue.js +21 -2
  81. package/dist/runtime/execution/state-lane.d.ts +2 -0
  82. package/dist/runtime/execution/state-lane.js +5 -0
  83. package/dist/runtime/foundation/operation-registry.d.ts +25 -1
  84. package/dist/runtime/foundation/operation-registry.js +86 -18
  85. package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +39 -3
  86. package/dist/runtime/foundation/raw-service-mesh-runtime.js +151 -55
  87. package/dist/runtime/foundation/service-liveness-registry.d.ts +12 -1
  88. package/dist/runtime/foundation/service-liveness-registry.js +38 -0
  89. package/dist/runtime/foundation/service-mailbox.d.ts +7 -0
  90. package/dist/runtime/foundation/service-maintenance-runtime.js +1 -6
  91. package/dist/runtime/foundation/service-relocation-object-owner.d.ts +2 -3
  92. package/dist/runtime/foundation/service-relocation-object-owner.js +48 -35
  93. package/dist/runtime/foundation/service-relocation-runtime.js +7 -3
  94. package/dist/runtime/foundation/service-runtime-contracts.d.ts +8 -1
  95. package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +2 -1
  96. package/dist/runtime/foundation/service-stateful-registry.d.ts +5 -4
  97. package/dist/runtime/foundation/service-stateful-registry.js +24 -26
  98. package/dist/runtime/foundation/service-stateful-runtime.d.ts +72 -6
  99. package/dist/runtime/foundation/service-stateful-runtime.js +444 -117
  100. package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +14 -1
  101. package/dist/runtime/foundation/service-stateful-wire-codec.js +48 -27
  102. package/dist/runtime/foundation/service-wire-binary-primitives.d.ts +6 -1
  103. package/dist/runtime/foundation/service-wire-binary-primitives.js +27 -11
  104. package/dist/runtime/foundation/service-wire-constants.generated.d.ts +1 -0
  105. package/dist/runtime/foundation/service-wire-constants.generated.js +1 -0
  106. package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +10 -0
  107. package/dist/runtime/foundation/service-wire-m6a-codec.js +166 -53
  108. package/dist/runtime/host/actor-packet-relay.d.ts +6 -4
  109. package/dist/runtime/host/actor-packet-relay.js +59 -72
  110. package/dist/runtime/host/actor-placement-coordinator.js +25 -8
  111. package/dist/runtime/host/actor-transfer-runtime.d.ts +7 -31
  112. package/dist/runtime/host/actor-transfer-runtime.js +85 -331
  113. package/dist/runtime/host/application-job-queue.d.ts +24 -3
  114. package/dist/runtime/host/application-job-queue.js +28 -41
  115. package/dist/runtime/host/index.d.ts +5 -1
  116. package/dist/runtime/host/index.js +171 -97
  117. package/dist/runtime/host/location-runtime-owner.js +2 -6
  118. package/dist/runtime/host/mesh-router-resolver.d.ts +4 -0
  119. package/dist/runtime/host/mesh-router-resolver.js +14 -6
  120. package/dist/runtime/host/remote-bound-session-relay.d.ts +2 -4
  121. package/dist/runtime/host/remote-bound-session-relay.js +71 -190
  122. package/dist/runtime/host/route-mesh-runtime.d.ts +2 -2
  123. package/dist/runtime/host/route-mesh-runtime.js +5 -3
  124. package/dist/runtime/host/runtime-shutdown.d.ts +1 -0
  125. package/dist/runtime/host/runtime-shutdown.js +3 -2
  126. package/dist/runtime/host/service-relocation-host-runtime.d.ts +17 -7
  127. package/dist/runtime/host/service-relocation-host-runtime.js +550 -367
  128. package/dist/runtime/host/spot-runtime-options-factory.js +15 -7
  129. package/dist/runtime/host/user-spot-creation-coordinator.js +33 -84
  130. package/dist/runtime/locations/auto-connect-loop.d.ts +2 -0
  131. package/dist/runtime/locations/auto-connect-loop.js +22 -14
  132. package/dist/runtime/locations/auto-connect-reconciler.js +0 -6
  133. package/dist/runtime/locations/auto-connect-types.d.ts +0 -1
  134. package/dist/runtime/locations/descriptor-publication.d.ts +4 -0
  135. package/dist/runtime/locations/descriptor-publication.js +11 -0
  136. package/dist/runtime/locations/domain-store-contract.d.ts +1 -0
  137. package/dist/runtime/locations/in-memory-authority-store.d.ts +7 -1
  138. package/dist/runtime/locations/in-memory-authority-store.js +56 -19
  139. package/dist/runtime/locations/in-memory-location-store.js +1 -10
  140. package/dist/runtime/locations/index.d.ts +1 -0
  141. package/dist/runtime/locations/index.js +1 -0
  142. package/dist/runtime/locations/lease-tracker.js +1 -6
  143. package/dist/runtime/locations/location-store-repository.d.ts +51 -1
  144. package/dist/runtime/locations/location-store-repository.js +363 -139
  145. package/dist/runtime/locations/relocation-blob.d.ts +18 -1
  146. package/dist/runtime/locations/relocation-blob.js +52 -1
  147. package/dist/runtime/locations/request-source-resolver.d.ts +37 -0
  148. package/dist/runtime/locations/request-source-resolver.js +80 -0
  149. package/dist/runtime/locations/resolvers.js +1 -1
  150. package/dist/runtime/locations/runtime.d.ts +6 -2
  151. package/dist/runtime/locations/runtime.js +37 -30
  152. package/dist/runtime/messaging/payload-codec.d.ts +7 -1
  153. package/dist/runtime/messaging/payload-codec.js +7 -6
  154. package/dist/runtime/messaging/request-result.js +29 -26
  155. package/dist/runtime/protocol/service_wire_codec.generated.d.ts +19 -1
  156. package/dist/runtime/protocol/service_wire_codec.generated.js +85 -0
  157. package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +7 -1
  158. package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +23 -7
  159. package/dist/runtime/spots/formal-remote-actor-admission-registry.js +3 -2
  160. package/dist/runtime/spots/index.d.ts +18 -11
  161. package/dist/runtime/spots/index.js +234 -176
  162. package/dist/runtime/spots/spot-activation-registry.d.ts +4 -2
  163. package/dist/runtime/spots/spot-activation-registry.js +21 -11
  164. package/dist/runtime/spots/spot-activation-state.d.ts +1 -1
  165. package/dist/runtime/spots/spot-activation-state.js +7 -7
  166. package/dist/runtime/spots/spot-activation.d.ts +6 -3
  167. package/dist/runtime/spots/spot-activation.js +123 -44
  168. package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +1 -0
  169. package/dist/runtime/spots/spot-actor-admission-coordinator.js +13 -22
  170. package/dist/runtime/spots/spot-actor-membership.d.ts +0 -1
  171. package/dist/runtime/spots/spot-actor-membership.js +0 -8
  172. package/dist/runtime/spots/spot-actor-packet-dispatch.js +33 -8
  173. package/dist/runtime/spots/spot-actor-packet-drain.js +5 -33
  174. package/dist/runtime/spots/spot-entry-activation.d.ts +2 -0
  175. package/dist/runtime/spots/spot-entry-activation.js +14 -9
  176. package/dist/runtime/spots/spot-handler-registry.d.ts +4 -3
  177. package/dist/runtime/spots/spot-handler-registry.js +6 -2
  178. package/dist/runtime/spots/spot-manager-internal-contracts.d.ts +2 -2
  179. package/dist/runtime/spots/spot-manager-public.js +2 -2
  180. package/dist/runtime/spots/spot-node-autoconnect.d.ts +2 -1
  181. package/dist/runtime/spots/spot-node-autoconnect.js +18 -39
  182. package/dist/runtime/spots/spot-node-runtime-manager.d.ts +19 -2
  183. package/dist/runtime/spots/spot-node-runtime-manager.js +115 -50
  184. package/dist/runtime/spots/spot-outbound.js +3 -3
  185. package/dist/runtime/spots/spot-remote-codec.js +5 -1
  186. package/dist/runtime/spots/spot-runtime-ports.d.ts +0 -1
  187. package/dist/runtime/spots/spot-serial-executor.d.ts +10 -0
  188. package/dist/runtime/spots/spot-serial-executor.js +61 -8
  189. package/dist/runtime/spots/spot-serial-turn-executor.js +19 -2
  190. package/dist/runtime/spots/spot-subscription-dispatch.js +1 -1
  191. package/dist/runtime/spots/spot-timer.d.ts +57 -5
  192. package/dist/runtime/spots/spot-timer.js +287 -103
  193. package/dist/runtime/streams/actor-session-binding-registry.d.ts +42 -11
  194. package/dist/runtime/streams/actor-session-binding-registry.js +165 -48
  195. package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +8 -4
  196. package/dist/runtime/streams/bound-actor-relay-sender.d.ts +2 -1
  197. package/dist/runtime/streams/bound-actor-relay-sender.js +15 -8
  198. package/dist/runtime/streams/bound-session-service.d.ts +1 -1
  199. package/dist/runtime/streams/bound-session-service.js +6 -11
  200. package/dist/runtime/streams/index.d.ts +3 -2
  201. package/dist/runtime/streams/index.js +6 -4
  202. package/dist/runtime/streams/managed-stream.js +3 -2
  203. package/dist/runtime/streams/native-fallback-bound-session.js +8 -73
  204. package/dist/runtime/streams/session-actor-coordinator.d.ts +2 -8
  205. package/dist/runtime/streams/session-actor-coordinator.js +15 -32
  206. package/dist/runtime/streams/stream-binding-runtime-ports.d.ts +3 -10
  207. package/dist/runtime/streams/stream-session-runtime.js +1 -4
  208. package/dist/runtime/workers/index.js +1 -1
  209. package/package.json +3 -3
  210. package/src/contracts/Common/ZLinkEncodedPayload.ts +24 -4
  211. package/src/contracts/Common/encoded-payload-storage.ts +6 -3
  212. package/src/contracts/Configuration/Builders.ts +4 -1
  213. package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +7 -2
  214. package/src/contracts/Configuration/RegistrationBuilders.ts +6 -2
  215. package/src/contracts/Configuration/RegistrationTypes.ts +1 -0
  216. package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +2 -1
  217. package/src/contracts/Locations/Rows.ts +2 -0
  218. package/src/contracts/Spots/Contracts.ts +8 -0
  219. package/src/contracts/Spots/ZLinkSpot.ts +3 -3
  220. package/src/runtime/abort.ts +12 -0
  221. package/src/runtime/actors/actor-authority-publication.ts +3 -2
  222. package/src/runtime/actors/actor-client.ts +61 -70
  223. package/src/runtime/actors/actor-context.ts +49 -9
  224. package/src/runtime/actors/actor-handoff.ts +282 -106
  225. package/src/runtime/actors/actor-join-relocation.ts +2 -0
  226. package/src/runtime/actors/actor-local-native-join.ts +4 -0
  227. package/src/runtime/actors/actor-mailbox.ts +40 -2
  228. package/src/runtime/actors/actor-remote-joiner.ts +6 -1
  229. package/src/runtime/actors/actor-reply.ts +42 -0
  230. package/src/runtime/actors/actor-runtime-contracts.ts +2 -0
  231. package/src/runtime/actors/actor-runtime-state.ts +2 -20
  232. package/src/runtime/actors/actor-source-transfer.ts +1 -34
  233. package/src/runtime/actors/index.ts +41 -27
  234. package/src/runtime/actors/session-disconnected-wire.ts +66 -0
  235. package/src/runtime/admission.ts +69 -34
  236. package/src/runtime/application-jobs/application-job-queue-scope.ts +33 -1
  237. package/src/runtime/application-jobs/contracts.ts +2 -0
  238. package/src/runtime/backend/contracts/index.ts +39 -4
  239. package/src/runtime/backend/mesh-actor-session-node-adapter.ts +5 -3
  240. package/src/runtime/backend/mesh-completion-table.ts +4 -0
  241. package/src/runtime/backend/mesh-dispatch-pump.ts +223 -124
  242. package/src/runtime/backend/node/node-raw-binding-port.ts +106 -70
  243. package/src/runtime/backend/node/node-raw-mesh-backend.ts +221 -170
  244. package/src/runtime/backend/node/node-socket-backend-adapter.ts +5 -5
  245. package/src/runtime/channels/channel-clients.ts +49 -24
  246. package/src/runtime/channels/channel-dispatch-pipeline.ts +173 -124
  247. package/src/runtime/channels/channel-dispatchers.ts +116 -72
  248. package/src/runtime/channels/channel-envelope.ts +105 -36
  249. package/src/runtime/channels/channel-runtime-lifecycle.ts +13 -13
  250. package/src/runtime/channels/channel-runtime-manager.ts +12 -5
  251. package/src/runtime/channels/channel-transports.ts +49 -58
  252. package/src/runtime/channels/client-server-location-runtime.ts +11 -10
  253. package/src/runtime/channels/dispatch-error-reporter.ts +4 -2
  254. package/src/runtime/channels/fanout-location-runtime.ts +17 -9
  255. package/src/runtime/diagnostics/flow-context.ts +20 -7
  256. package/src/runtime/diagnostics/index.ts +1 -7
  257. package/src/runtime/diagnostics/message-flow.ts +47 -9
  258. package/src/runtime/diagnostics/runtime-metrics.ts +12 -10
  259. package/src/runtime/execution/index.ts +40 -14
  260. package/src/runtime/execution/serial-execution-queue.ts +31 -4
  261. package/src/runtime/execution/state-lane.ts +7 -0
  262. package/src/runtime/foundation/operation-registry.ts +98 -20
  263. package/src/runtime/foundation/raw-service-mesh-runtime.ts +244 -67
  264. package/src/runtime/foundation/service-liveness-registry.ts +39 -0
  265. package/src/runtime/foundation/service-mailbox.ts +8 -0
  266. package/src/runtime/foundation/service-maintenance-runtime.ts +1 -8
  267. package/src/runtime/foundation/service-relocation-object-owner.ts +54 -37
  268. package/src/runtime/foundation/service-relocation-runtime.ts +7 -3
  269. package/src/runtime/foundation/service-runtime-contracts.ts +12 -1
  270. package/src/runtime/foundation/service-session-binding-ingress-port.ts +2 -1
  271. package/src/runtime/foundation/service-stateful-registry.ts +38 -35
  272. package/src/runtime/foundation/service-stateful-runtime.ts +667 -152
  273. package/src/runtime/foundation/service-stateful-wire-codec.ts +49 -11
  274. package/src/runtime/foundation/service-wire-binary-primitives.ts +35 -12
  275. package/src/runtime/foundation/service-wire-constants.generated.ts +1 -0
  276. package/src/runtime/foundation/service-wire-m6a-codec.ts +187 -51
  277. package/src/runtime/host/actor-packet-relay.ts +113 -94
  278. package/src/runtime/host/actor-placement-coordinator.ts +31 -8
  279. package/src/runtime/host/actor-transfer-runtime.ts +104 -430
  280. package/src/runtime/host/application-job-queue.ts +29 -44
  281. package/src/runtime/host/index.ts +286 -129
  282. package/src/runtime/host/location-runtime-owner.ts +2 -6
  283. package/src/runtime/host/mesh-router-resolver.ts +13 -5
  284. package/src/runtime/host/remote-bound-session-relay.ts +86 -248
  285. package/src/runtime/host/route-mesh-runtime.ts +11 -5
  286. package/src/runtime/host/runtime-shutdown.ts +15 -4
  287. package/src/runtime/host/service-relocation-host-runtime.ts +784 -475
  288. package/src/runtime/host/spot-runtime-options-factory.ts +18 -7
  289. package/src/runtime/host/user-spot-creation-coordinator.ts +41 -100
  290. package/src/runtime/locations/auto-connect-loop.ts +22 -14
  291. package/src/runtime/locations/auto-connect-reconciler.ts +0 -6
  292. package/src/runtime/locations/auto-connect-types.ts +0 -1
  293. package/src/runtime/locations/descriptor-publication.ts +7 -0
  294. package/src/runtime/locations/domain-store-contract.ts +5 -0
  295. package/src/runtime/locations/in-memory-authority-store.ts +85 -23
  296. package/src/runtime/locations/in-memory-location-store.ts +1 -12
  297. package/src/runtime/locations/index.ts +1 -0
  298. package/src/runtime/locations/lease-tracker.ts +2 -9
  299. package/src/runtime/locations/location-store-repository.ts +628 -152
  300. package/src/runtime/locations/relocation-blob.ts +75 -1
  301. package/src/runtime/locations/request-source-resolver.ts +138 -0
  302. package/src/runtime/locations/resolvers.ts +2 -2
  303. package/src/runtime/locations/runtime.ts +70 -40
  304. package/src/runtime/messaging/payload-codec.ts +8 -11
  305. package/src/runtime/messaging/request-result.ts +33 -29
  306. package/src/runtime/protocol/service_wire_codec.generated.ts +87 -4
  307. package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +13 -10
  308. package/src/runtime/spots/formal-remote-actor-admission-registry.ts +3 -2
  309. package/src/runtime/spots/index.ts +375 -281
  310. package/src/runtime/spots/spot-activation-registry.ts +25 -13
  311. package/src/runtime/spots/spot-activation-state.ts +12 -19
  312. package/src/runtime/spots/spot-activation.ts +170 -86
  313. package/src/runtime/spots/spot-actor-admission-coordinator.ts +25 -55
  314. package/src/runtime/spots/spot-actor-membership.ts +0 -15
  315. package/src/runtime/spots/spot-actor-packet-dispatch.ts +56 -11
  316. package/src/runtime/spots/spot-actor-packet-drain.ts +9 -52
  317. package/src/runtime/spots/spot-entry-activation.ts +24 -19
  318. package/src/runtime/spots/spot-handler-registry.ts +15 -4
  319. package/src/runtime/spots/spot-manager-internal-contracts.ts +2 -2
  320. package/src/runtime/spots/spot-manager-public.ts +2 -2
  321. package/src/runtime/spots/spot-node-autoconnect.ts +22 -45
  322. package/src/runtime/spots/spot-node-runtime-manager.ts +197 -67
  323. package/src/runtime/spots/spot-outbound.ts +3 -3
  324. package/src/runtime/spots/spot-remote-codec.ts +9 -2
  325. package/src/runtime/spots/spot-runtime-ports.ts +0 -1
  326. package/src/runtime/spots/spot-serial-executor.ts +97 -25
  327. package/src/runtime/spots/spot-serial-turn-executor.ts +22 -3
  328. package/src/runtime/spots/spot-subscription-dispatch.ts +1 -1
  329. package/src/runtime/spots/spot-timer.ts +413 -157
  330. package/src/runtime/streams/actor-session-binding-registry.ts +236 -64
  331. package/src/runtime/streams/actor-session-binding-runtime-owner.ts +16 -8
  332. package/src/runtime/streams/bound-actor-relay-sender.ts +23 -9
  333. package/src/runtime/streams/bound-session-service.ts +7 -10
  334. package/src/runtime/streams/index.ts +12 -6
  335. package/src/runtime/streams/managed-stream.ts +4 -2
  336. package/src/runtime/streams/native-fallback-bound-session.ts +14 -103
  337. package/src/runtime/streams/session-actor-coordinator.ts +39 -88
  338. package/src/runtime/streams/stream-binding-runtime-ports.ts +3 -9
  339. package/src/runtime/streams/stream-session-runtime.ts +1 -5
  340. 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,6 +208,11 @@ 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,
@@ -439,9 +443,16 @@ export class DefaultZLinkSpotManager {
439
443
  this.actorMembership.leaveActor(spotId, actor, signal, meshName),
440
444
  requestContextClose: (activation, objectGeneration, signal) =>
441
445
  this.closeFromContext(activation, objectGeneration, signal),
442
- registerActivation: (activation) => {
443
- 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);
444
454
  this.scheduleIdleSweep();
455
+ if (published?.domain.kind === 'user') await published.serialExecutor.finishPreparation();
445
456
  },
446
457
  // Spec 15 §4.2 relocation temporary queue: production ingress
447
458
  // consults the same admission attempts registered on Accepted
@@ -513,6 +524,7 @@ export class DefaultZLinkSpotManager {
513
524
  spotId: RoutingId,
514
525
  objectGeneration: bigint,
515
526
  authorityOwnerGeneration: bigint,
527
+ restoredTimers: readonly import('./spot-timer').ZLinkTimerRelocationState[],
516
528
  signal?: AbortSignal
517
529
  ): Promise<ZLinkSpotActivation> {
518
530
  this.activations.stage(meshName, spotId);
@@ -525,6 +537,7 @@ export class DefaultZLinkSpotManager {
525
537
  spotId,
526
538
  objectGeneration,
527
539
  authorityOwnerGeneration,
540
+ restoredTimers,
528
541
  signal
529
542
  );
530
543
  } catch (error) {
@@ -537,12 +550,19 @@ export class DefaultZLinkSpotManager {
537
550
  activation: ZLinkSpotActivation,
538
551
  beforeAdmission?: () => Promise<void>
539
552
  ): Promise<void> {
540
- 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
+ );
541
558
  await beforeAdmission?.();
542
559
  this.activations.publish(activation.meshName, activation.spotId);
560
+ await activation.serialExecutor.finishPreparation();
561
+ await activation.timers.publishRelocation();
543
562
  }
544
563
 
545
564
  async abortRelocationSpot(activation: ZLinkSpotActivation): Promise<void> {
565
+ await this.activationLifecycle.discardPreparation(activation);
546
566
  this.activations.detachRelocated(activation.meshName, activation.spotId);
547
567
  await activation.timers.dispose();
548
568
  await activation.nativeSpot?.dispose();
@@ -558,7 +578,8 @@ export class DefaultZLinkSpotManager {
558
578
  instanceType: string,
559
579
  spotId: RoutingId,
560
580
  objectGeneration: bigint,
561
- signal?: AbortSignal
581
+ signal?: AbortSignal,
582
+ completion: ZLinkSpotPreparationCompletion = 'publication'
562
583
  ): Promise<void> {
563
584
  const readyTarget = this.options.instanceSpotApplicationTargetProvider?.(meshName, spotId);
564
585
  const existing = this.pendingInstanceMaterializations.get(
@@ -576,7 +597,8 @@ export class DefaultZLinkSpotManager {
576
597
  spotId,
577
598
  objectGeneration,
578
599
  readyTarget?.objectGeneration === objectGeneration,
579
- signal
600
+ signal,
601
+ completion
580
602
  );
581
603
  } finally {
582
604
  release?.();
@@ -589,7 +611,8 @@ export class DefaultZLinkSpotManager {
589
611
  spotId: RoutingId,
590
612
  objectGeneration: bigint,
591
613
  requiresReadyTarget: boolean,
592
- signal?: AbortSignal
614
+ signal: AbortSignal | undefined,
615
+ completion: ZLinkSpotPreparationCompletion
593
616
  ): Promise<void> {
594
617
  const factory = this.requireInstanceFactory(meshName, instanceType);
595
618
  const key = `${meshName}\0${String(spotId)}`;
@@ -622,7 +645,7 @@ export class DefaultZLinkSpotManager {
622
645
  continue;
623
646
  }
624
647
 
625
- const current = this.activations.resolve(meshName, spotId);
648
+ const current = this.activations.activationForClose(meshName, spotId);
626
649
  if (current !== undefined) {
627
650
  if (current.spotType !== factory) {
628
651
  throw new ZLinkConfigurationException(
@@ -668,16 +691,16 @@ export class DefaultZLinkSpotManager {
668
691
  }
669
692
  }
670
693
  if (pending === undefined) {
671
- const metric = this.options.metrics?.startInstanceSpotActivation(meshName, instanceType);
694
+ if (completion === 'first-terminal') this.activations.stage(meshName, spotId);
672
695
  pending = this.activationLifecycle
673
696
  .materializeInstance(meshName, instanceType, factory, spotId, objectGeneration, signal)
674
697
  .then(
675
- (activation) => {
676
- metric?.complete('ready');
698
+ async (activation) => {
699
+ if (completion === 'publication') await activation.serialExecutor.finishPreparation();
677
700
  return activation;
678
701
  },
679
702
  (error) => {
680
- metric?.complete(instanceActivationOutcome(error));
703
+ this.activations.abandonStage(meshName, spotId);
681
704
  throw error;
682
705
  }
683
706
  );
@@ -725,10 +748,16 @@ export class DefaultZLinkSpotManager {
725
748
  ? this.activations.resolveUnique(spotId)
726
749
  : this.activations.resolve(meshName, spotId);
727
750
  if (current !== undefined) return current;
728
- if (meshName !== undefined)
729
- 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
+ }
730
755
  for (const operation of this.closeOperations.values()) {
731
- 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;
732
761
  }
733
762
  return undefined;
734
763
  }
@@ -737,6 +766,7 @@ export class DefaultZLinkSpotManager {
737
766
  const prefix = instanceMaterializationPrefix(meshName, spotId);
738
767
  return (
739
768
  (this.pendingInstanceMaterializationsByPrefix.get(prefix)?.size ?? 0) > 0 ||
769
+ this.activations.activationForClose(meshName, spotId)?.serialExecutor.isPreparing === true ||
740
770
  this.closeOperations.get(`${meshName}\0${String(spotId)}`)?.authority !== undefined
741
771
  );
742
772
  }
@@ -753,7 +783,7 @@ export class DefaultZLinkSpotManager {
753
783
  }
754
784
 
755
785
  async discardInstance(meshName: string, spotId: RoutingId): Promise<void> {
756
- const activation = this.activations.resolve(meshName, spotId);
786
+ const activation = this.activations.activationForClose(meshName, spotId);
757
787
  if (activation === undefined) return;
758
788
  activation.requestClose();
759
789
  const operation = this.activations.startClose(
@@ -803,6 +833,9 @@ export class DefaultZLinkSpotManager {
803
833
  objectGeneration: bigint
804
834
  ): Promise<boolean> {
805
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();
806
839
  const pending = this.pendingInstanceTerminals.get(key);
807
840
  if (pending === undefined) return false;
808
841
  this.removePendingInstanceTerminalGeneration(key, objectGeneration);
@@ -849,6 +882,17 @@ export class DefaultZLinkSpotManager {
849
882
  this.pendingInstanceTerminalGenerations.set(key, generations);
850
883
  }
851
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
+
852
896
  private deferInstanceAuthorityRelease(key: string, objectGeneration: bigint): void {
853
897
  const generations = this.deferredInstanceAuthorityReleases.get(key) ?? new Set<bigint>();
854
898
  generations.add(objectGeneration);
@@ -1079,19 +1123,24 @@ export class DefaultZLinkSpotManager {
1079
1123
  }
1080
1124
 
1081
1125
  async drainForShutdown(meshName: string, signal?: AbortSignal, deadline?: Date): Promise<void> {
1082
- const results = await Promise.allSettled(
1083
- this.activations
1084
- .activeActivations()
1085
- .filter((activation) => activation.meshName === meshName)
1086
- .map((activation) =>
1087
- this.closeWithReason(
1088
- meshName,
1089
- activation.spotId,
1090
- signal,
1091
- ZLinkSpotCloseReason.HostShutdown,
1092
- 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
+ )
1093
1141
  )
1094
- )
1142
+ ),
1143
+ signal
1095
1144
  );
1096
1145
  const errors = results
1097
1146
  .filter((result): result is PromiseRejectedResult => result.status === 'rejected')
@@ -1129,7 +1178,10 @@ export class DefaultZLinkSpotManager {
1129
1178
  ): Promise<boolean> {
1130
1179
  const { meshName, spotId } = activation;
1131
1180
  const operation = this.closeOperations.get(`${meshName}\0${String(spotId)}`);
1132
- 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);
1133
1185
  if (current === undefined) {
1134
1186
  return Promise.resolve(false);
1135
1187
  }
@@ -1152,7 +1204,8 @@ export class DefaultZLinkSpotManager {
1152
1204
  signal,
1153
1205
  ZLinkSpotCloseReason.ExplicitClose,
1154
1206
  undefined,
1155
- beginUserAuthority
1207
+ beginUserAuthority,
1208
+ activation
1156
1209
  );
1157
1210
  }
1158
1211
 
@@ -1166,13 +1219,14 @@ export class DefaultZLinkSpotManager {
1166
1219
  onCommitted: () => void
1167
1220
  ) => Promise<
1168
1221
  import('../locations/spot-location-claims').ZLinkInstanceClosingAuthority | undefined
1169
- >
1222
+ >,
1223
+ contextActivation?: ZLinkSpotActivation
1170
1224
  ): Promise<boolean> {
1171
1225
  requireMeshName(meshName);
1172
1226
  const key = `${meshName}\0${String(spotId)}`;
1173
1227
  let operation = this.closeOperations.get(key);
1174
1228
  if (operation === undefined) {
1175
- const activation = this.activations.resolve(meshName, spotId);
1229
+ const activation = this.activations.resolve(meshName, spotId) ?? contextActivation;
1176
1230
  if (activation === undefined) return false;
1177
1231
  if (
1178
1232
  activation.domain.kind === 'user' &&
@@ -1245,10 +1299,11 @@ export class DefaultZLinkSpotManager {
1245
1299
  signal?: AbortSignal,
1246
1300
  deadline?: Date
1247
1301
  ): Promise<boolean> {
1302
+ if (this.activations.resolve(meshName, spotId) !== operation.activation) return false;
1248
1303
  const seal = await this.beginCloseAuthority(meshName, spotId, operation, signal);
1249
1304
  if (seal === undefined) return false;
1250
1305
  if (seal !== true) {
1251
- await this.activationLifecycle.sealForClose(operation.activation, seal);
1306
+ await this.activationLifecycle.sealForClose(operation.activation, seal, signal);
1252
1307
  } else {
1253
1308
  await operation.activation.executionBarrier.waitForStartedTurns(signal);
1254
1309
  }
@@ -1420,12 +1475,19 @@ export class DefaultZLinkSpotManager {
1420
1475
  this.activations.stage(meshName, spotId);
1421
1476
  }
1422
1477
 
1423
- publishUserSpot(meshName: string, spotId: RoutingId): void {
1424
- 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();
1425
1481
  }
1426
1482
 
1427
- abortUserSpotPublication(meshName: string, spotId: RoutingId): void {
1483
+ async abortUserSpotPublication(meshName: string, spotId: RoutingId): Promise<void> {
1428
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
+ }
1429
1491
  }
1430
1492
 
1431
1493
  resolveLocalSpotRoute(spotId: RoutingId): ZLinkSpotRouteTarget | undefined {
@@ -1511,14 +1573,6 @@ export class DefaultZLinkSpotManager {
1511
1573
  await this.actorMembership.commitActorLeaveAfterTransfer(spotId, actorId);
1512
1574
  }
1513
1575
 
1514
- async restoreActorAfterFailedTransfer(
1515
- spotId: RoutingId,
1516
- actor: ZLinkActor,
1517
- signal?: AbortSignal
1518
- ): Promise<void> {
1519
- await this.actorMembership.restoreActorAfterFailedTransfer(spotId, actor, signal);
1520
- }
1521
-
1522
1576
  async beginActorTransfer(spotId: RoutingId, actorId: string): Promise<void> {
1523
1577
  await this.actorMembership.beginActorTransfer(spotId, actorId);
1524
1578
  }
@@ -1597,6 +1651,24 @@ export class DefaultZLinkSpotManager {
1597
1651
  return this.activationLifecycle.admitActorPacketPrefix(activation, actorId, records);
1598
1652
  }
1599
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
+
1600
1672
  async dispatchRoutedSpotSend(
1601
1673
  spotId: RoutingId,
1602
1674
  packetName: string | undefined,
@@ -1631,14 +1703,15 @@ export class DefaultZLinkSpotManager {
1631
1703
  async dispatchMeshSpot(
1632
1704
  meshName: string,
1633
1705
  owner: ReadyRecord,
1634
- record: ReceiveRecord
1706
+ record: ReceiveRecord,
1707
+ admit?: ZLinkMeshDispatchAdmission
1635
1708
  ): Promise<void> {
1636
1709
  const spotId = owner.spotId as unknown as RoutingId | null;
1637
1710
  if (spotId === null) {
1638
1711
  throw new ZLinkConfigurationException('MeshNode Spot record is missing the owner Spot RID.');
1639
1712
  }
1640
1713
  if (record.kind === ReceiveKind.SpotMulticast) {
1641
- const activation = this.activations.resolve(meshName, spotId);
1714
+ const activation = this.activations.activationForClose(meshName, spotId);
1642
1715
  if (activation?.actorDispatch === undefined) {
1643
1716
  throw new ZLinkConfigurationException(
1644
1717
  `MeshNode Spot multicast target '${String(spotId)}' is not active.`
@@ -1649,11 +1722,13 @@ export class DefaultZLinkSpotManager {
1649
1722
  'MeshNode Spot multicast record is missing its topic.'
1650
1723
  );
1651
1724
  }
1652
- await activation.actorDispatch.dispatchSubscriptionRecord(
1653
- record.topic,
1654
- record.parts,
1655
- record.sourceNodeRid as unknown as RoutingId | null
1656
- );
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));
1657
1732
  return;
1658
1733
  }
1659
1734
  const envelope = decodeChannelEnvelope(
@@ -1675,28 +1750,32 @@ export class DefaultZLinkSpotManager {
1675
1750
  record.applicationMetadata?.byteLength ?? zlinkMetadataByteLength(envelope.header.metadata)
1676
1751
  )
1677
1752
  };
1678
- if (record.kind === ReceiveKind.SpotSend) {
1679
- await this.ensureInstanceApplicationActivation(meshName, spotId);
1680
- await this.routedSpotPackets.sendEncoded(spotId, packetName, decodePayload, context);
1681
- return;
1682
- }
1683
- if (record.kind !== ReceiveKind.SpotRequest) {
1684
- throw new ZLinkConfigurationException(
1685
- `Unsupported MeshNode Spot record kind '${record.kind}'.`
1686
- );
1687
- }
1688
1753
  try {
1689
- await this.ensureInstanceApplicationActivation(meshName, spotId);
1690
- const response = await this.routedSpotPackets.requestEncoded(
1691
- spotId,
1692
- packetName,
1693
- decodePayload,
1694
- context
1695
- );
1696
- requireMeshSpotReply(
1697
- record.reply(encodeChannelReplyParts(envelope.header, response, codecs))
1698
- );
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));
1699
1777
  } catch (error) {
1778
+ if (record.kind !== ReceiveKind.SpotRequest) throw error;
1700
1779
  requireMeshSpotReply(record.reply(encodeChannelErrorReplyParts(envelope.header, error)));
1701
1780
  }
1702
1781
  }
@@ -1731,7 +1810,8 @@ export class DefaultZLinkSpotManager {
1731
1810
  async dispatchMeshInstance(
1732
1811
  meshName: string,
1733
1812
  owner: ReadyRecord,
1734
- record: ReceiveRecord
1813
+ record: ReceiveRecord,
1814
+ admit?: ZLinkMeshDispatchAdmission
1735
1815
  ): Promise<void> {
1736
1816
  const spotId = owner.spotId as unknown as RoutingId | null;
1737
1817
  if (spotId === null) {
@@ -1761,75 +1841,111 @@ export class DefaultZLinkSpotManager {
1761
1841
  'activating'
1762
1842
  );
1763
1843
  try {
1764
- await this.ensureInstanceApplicationActivation(meshName, spotId);
1765
- const activation = this.resolveApplicationActivation(spotId, meshName);
1766
- if (activation === undefined || activation.domain.kind !== 'instance') {
1767
- throw new ZLinkConfigurationException(
1768
- `MeshNode Instance Spot target '${String(spotId)}' is not active.`
1769
- );
1770
- }
1771
- const target = this.options.instanceSpotApplicationTargetProvider?.(meshName, spotId);
1772
- if (
1773
- target !== undefined &&
1774
- activation.domain.objectGeneration !== target.objectGeneration
1775
- ) {
1776
- throw createInternalFrameworkException(
1777
- ZLinkFrameworkInternalErrorKind.SpotGenerationStale,
1778
- `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
1779
1921
  );
1780
- }
1781
- const codecs =
1782
- this.options.messageSerializers === undefined
1783
- ? undefined
1784
- : { serializers: this.options.messageSerializers };
1785
- const decodePayload = () => decodeChannelPayload(envelope, codecs);
1786
- const context = {
1787
- channelName: envelope.header.channelName,
1788
- contentType: envelope.header.contentType,
1789
- awaitFirstHandlerTurn: record.kind === ReceiveKind.InstanceSpotActivation,
1790
- activationRecord: record,
1791
- onOneWayError:
1792
- this.options.dispatchErrors?.captureEnabled() === true
1793
- ? (error: unknown) =>
1794
- this.reportInstanceDispatchFailure(
1795
- meshName,
1796
- spotId,
1797
- record,
1798
- envelope,
1799
- false,
1800
- error
1801
- )
1802
- : undefined,
1803
- workOptions: zlinkSerialWorkOptions(
1804
- envelope.payload.byteLength,
1805
- record.applicationMetadata?.byteLength ??
1806
- zlinkMetadataByteLength(envelope.header.metadata)
1807
- )
1808
- };
1809
- // Spot messaging §7 step 3: an Instance intent request that reaches an
1810
- // incarnation whose Close ended admission is refused before admission
1811
- // with the owner fence terminal, so its caller re-reads authority.
1812
- const instanceIntent =
1813
- record.activationRecord?.activation === 'missing' ||
1814
- (record.activationRecord?.activation === 'ready' &&
1815
- record.activationRecord.instanceIntent);
1816
- const refusal = activation.serial.applicationAdmissionRefusal(instanceIntent === true);
1817
- if (request && refusal !== undefined && record.replyFailure !== undefined) {
1818
- this.reportInstanceDispatchFailure(meshName, spotId, record, envelope, request, refusal);
1819
- const terminal = internalFrameworkWireReply(refusal);
1820
- requireMeshSpotReply(record.replyFailure(terminal.terminalResult, terminal.failureCode));
1821
- return;
1822
- }
1823
- this.traceInstanceMessage(
1824
- ZLinkMessageFlowOutcome.Admitted,
1825
- meshName,
1826
- spotId,
1827
- record,
1828
- envelope,
1829
- 'ready',
1830
- target?.stableType
1831
- );
1832
- 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
+ }
1833
1949
  this.traceInstanceMessage(
1834
1950
  ZLinkMessageFlowOutcome.Dispatched,
1835
1951
  meshName,
@@ -1839,14 +1955,17 @@ export class DefaultZLinkSpotManager {
1839
1955
  'ready',
1840
1956
  target?.stableType
1841
1957
  );
1842
- await this.routedSpotPackets.sendEncoded(
1958
+ const response = await this.routedSpotPackets.requestEncoded(
1843
1959
  spotId,
1844
1960
  envelope.packetName,
1845
1961
  decodePayload,
1846
1962
  context
1847
1963
  );
1964
+ requireMeshSpotReply(
1965
+ record.reply(encodeChannelReplyParts(envelope.header, response, codecs))
1966
+ );
1848
1967
  this.traceInstanceMessage(
1849
- ZLinkMessageFlowOutcome.Completed,
1968
+ ZLinkMessageFlowOutcome.Replied,
1850
1969
  meshName,
1851
1970
  spotId,
1852
1971
  record,
@@ -1854,35 +1973,8 @@ export class DefaultZLinkSpotManager {
1854
1973
  'ready',
1855
1974
  target?.stableType
1856
1975
  );
1857
- return;
1858
- }
1859
- this.traceInstanceMessage(
1860
- ZLinkMessageFlowOutcome.Dispatched,
1861
- meshName,
1862
- spotId,
1863
- record,
1864
- envelope,
1865
- 'ready',
1866
- target?.stableType
1867
- );
1868
- const response = await this.routedSpotPackets.requestEncoded(
1869
- spotId,
1870
- envelope.packetName,
1871
- decodePayload,
1872
- context
1873
- );
1874
- requireMeshSpotReply(
1875
- record.reply(encodeChannelReplyParts(envelope.header, response, codecs))
1876
- );
1877
- this.traceInstanceMessage(
1878
- ZLinkMessageFlowOutcome.Replied,
1879
- meshName,
1880
- spotId,
1881
- record,
1882
- envelope,
1883
- 'ready',
1884
- target?.stableType
1885
- );
1976
+ };
1977
+ await (admit === undefined ? dispatch() : admit(dispatch));
1886
1978
  } catch (error) {
1887
1979
  this.reportInstanceDispatchFailure(meshName, spotId, record, envelope, request, error);
1888
1980
  const reason = dispatchReasonFromError(error);
@@ -1977,7 +2069,8 @@ export class DefaultZLinkSpotManager {
1977
2069
  origin: ApplicationJobOrigin,
1978
2070
  meshName: string,
1979
2071
  owner: ReadyRecord,
1980
- record: ReceiveRecord
2072
+ record: ReceiveRecord,
2073
+ admit?: ZLinkMeshDispatchAdmission
1981
2074
  ): Promise<void> {
1982
2075
  const spotId = owner.spotId as unknown as RoutingId | null;
1983
2076
  const entrySpotId = this.options.entryNodeRidProvider?.() ?? this.options.entryNodeRid;
@@ -1988,12 +2081,15 @@ export class DefaultZLinkSpotManager {
1988
2081
  throw new ZLinkConfigurationException('MeshNode Actor record is missing its Actor owner.');
1989
2082
  }
1990
2083
  const request = record.kind === ReceiveKind.ActorRequest;
1991
- const resolvedOwner = this.options.actorDispatchOwnerResolver?.(actor.actorId);
1992
- const resolvedActorRef = resolvedOwner?.actorRef ?? {
1993
- actorId: actor.actorId,
1994
- 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,
1995
2091
  meshName,
1996
- nodeRid: String(actor.nodeRid)
2092
+ nodeRid: ingressActor.nodeRid
1997
2093
  };
1998
2094
  const responseActorRef =
1999
2095
  record.sourceBindingGeneration > 0n
@@ -2032,43 +2128,49 @@ export class DefaultZLinkSpotManager {
2032
2128
  )
2033
2129
  : undefined;
2034
2130
  try {
2035
- if (this.formalRemoteTransfers.has(actor.actorId)) {
2036
- throw new Error(`Actor '${actor.actorId}' target transfer reconciliation is not complete.`);
2037
- }
2038
- const response = targetsEntrySpot
2039
- ? await this.options.dispatchEntryActorPacket?.(
2040
- origin,
2041
- actor.actorId,
2042
- record.parts,
2043
- request,
2044
- undefined,
2045
- ownerActorRef,
2046
- requestTerminal,
2047
- record.messageFollowOrigin
2048
- )
2049
- : await this.dispatchMeshActorPacket(
2050
- origin,
2051
- meshName,
2052
- spotId,
2053
- actor.actorId,
2054
- record.parts,
2055
- request,
2056
- ownerActorRef,
2057
- requestTerminal,
2058
- 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.`
2059
2135
  );
2060
- if (targetsEntrySpot && this.options.dispatchEntryActorPacket === undefined) {
2061
- throw new ZLinkConfigurationException(
2062
- 'MeshNode Entry Spot Actor dispatch is not configured.'
2063
- );
2064
- }
2065
- if (request && !requestTerminalState.submitted) {
2066
- requireMeshSpotReply(
2067
- record.reply(
2068
- this.encodeMeshActorReply(record.parts[0], ZLinkStreamMessageKind.Response, response)
2069
- )
2070
- );
2071
- }
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));
2072
2174
  } catch (error) {
2073
2175
  if (!request) {
2074
2176
  throw error;
@@ -2078,10 +2180,11 @@ export class DefaultZLinkSpotManager {
2078
2180
  }
2079
2181
  requireMeshSpotReply(
2080
2182
  record.reply(
2081
- this.encodeMeshActorReply(record.parts[0], ZLinkStreamMessageKind.Error, {
2082
- message: error instanceof Error ? error.message : String(error),
2083
- kind: spotActorFailureKind(error)
2084
- })
2183
+ this.encodeMeshActorReply(
2184
+ record.parts[0],
2185
+ ZLinkStreamMessageKind.Error,
2186
+ boundSessionErrorPayload(error)
2187
+ )
2085
2188
  )
2086
2189
  );
2087
2190
  }
@@ -2869,11 +2972,7 @@ export class DefaultZLinkSpotManager {
2869
2972
  control.previousMembershipEpoch
2870
2973
  );
2871
2974
  };
2872
- if (this.options.actorTransferRuntime === undefined) {
2873
- await callback();
2874
- } else {
2875
- await this.options.actorTransferRuntime.notifyCoreSourceLeave(actor, callback);
2876
- }
2975
+ await callback();
2877
2976
  return;
2878
2977
  }
2879
2978
  if (spotId === null) {
@@ -2964,7 +3063,7 @@ export class DefaultZLinkSpotManager {
2964
3063
  // ingress hold) migrate into the real Actor queue next, in the
2965
3064
  // order they parked — after the relayed backlog above, before
2966
3065
  // regular ingress opens.
2967
- await this.migrateActorJoinPrewarm(activation, actor, pendingTransfer.transferId);
3066
+ this.migrateActorJoinPrewarm(activation, actor, pendingTransfer.transferId);
2968
3067
  // This registry owns target lifecycle and saved backlog
2969
3068
  // reconciliation only. Session route readiness is enforced by
2970
3069
  // the Session binding aggregate after this boundary.
@@ -3037,9 +3136,7 @@ export class DefaultZLinkSpotManager {
3037
3136
  if (sourceJoinedActor === undefined && pendingTransfer === undefined) {
3038
3137
  return;
3039
3138
  }
3040
- await this.options.actorTransferRuntime.notifyCoreSourceLeave(actor, () =>
3041
- activation.spot.onLeaveActor(actor)
3042
- );
3139
+ await activation.spot.onLeaveActor(actor);
3043
3140
  }
3044
3141
  activation.commitActorDeparture(actor.context.actorId);
3045
3142
  return;
@@ -3099,6 +3196,19 @@ export class DefaultZLinkSpotManager {
3099
3196
  }
3100
3197
  } catch (error) {
3101
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
+ }
3102
3212
  }
3103
3213
  if (lifecycleFailure === undefined) {
3104
3214
  const sourceLeave = submitSourceLeave(admission.admission.actorRef.nodeRid);
@@ -3117,7 +3227,7 @@ export class DefaultZLinkSpotManager {
3117
3227
  if (activation === undefined) {
3118
3228
  throw new Error(`Actor Join relocation '${relocationId}' target mailbox is missing.`);
3119
3229
  }
3120
- return activation.executeActor(actor.context.actorId, operation);
3230
+ return activation.executeActor(actor.context.actorId, operation, { lane: 'lifecycle' });
3121
3231
  };
3122
3232
  await this.options.actorTransferRuntime.deliverDeferredJoinCompletion(
3123
3233
  lifecycleFailure === undefined
@@ -3143,6 +3253,16 @@ export class DefaultZLinkSpotManager {
3143
3253
  return () => this.formalRemoteActorAdmissions.finishRestore(relocationId);
3144
3254
  }
3145
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
+
3146
3266
  async restoreCanonicalActorJoinRecovery(
3147
3267
  recovery: CanonicalActorJoinRecovery,
3148
3268
  signal?: AbortSignal
@@ -3237,35 +3357,13 @@ export class DefaultZLinkSpotManager {
3237
3357
  kind: ZLinkStreamMessageKind.Response | ZLinkStreamMessageKind.Error,
3238
3358
  payload: unknown
3239
3359
  ): readonly Buffer[] {
3240
- // Spec 27 §4/§7: the decode gate strips the observation-only flow pair at
3241
- // Off (and skips its validation); when tracing is on the reply preserves
3242
- // the request's flow pair alongside its correlation.
3243
- const requestHeader = decodeStreamHeader(
3360
+ return encodeActorReply(
3244
3361
  requestHeaderPart.data(),
3362
+ kind,
3363
+ payload,
3364
+ this.options.messageSerializers,
3245
3365
  this.options.dispatchErrors?.flow.flowCreationEnabled() ?? true
3246
3366
  );
3247
- const encoded = encodeFrameworkPayload(payload, this.options.messageSerializers);
3248
- try {
3249
- // encodeStreamHeader returns a fresh, unaliased array; view it without
3250
- // re-copying. The payload copy stays: encoded.message closes below.
3251
- const replyHeader = encodeStreamHeader({
3252
- kind,
3253
- codec: streamCodecForContentType(encoded.contentType),
3254
- flags: ZLinkStreamHeaderFlags.None,
3255
- requestSeq: requestHeader.requestSeq,
3256
- name: '',
3257
- metadata: new Map(),
3258
- correlationId: requestHeader.correlationId,
3259
- flowId: requestHeader.flowId,
3260
- flowOrigin: requestHeader.flowOrigin
3261
- });
3262
- return [
3263
- Buffer.from(replyHeader.buffer, replyHeader.byteOffset, replyHeader.byteLength),
3264
- Buffer.from(encoded.message.data())
3265
- ];
3266
- } finally {
3267
- encoded.message.close();
3268
- }
3269
3367
  }
3270
3368
 
3271
3369
  private async createActivation<TSpot extends ZLinkSpot>(
@@ -3327,13 +3425,14 @@ export class DefaultZLinkSpotManager {
3327
3425
  * either lands in the snapshot or resolves the Actor directly through
3328
3426
  * ordinary ingress — never both, never neither.
3329
3427
  */
3330
- private async migrateActorJoinPrewarm(
3428
+ private migrateActorJoinPrewarm(
3331
3429
  activation: ZLinkSpotActivation,
3332
3430
  actor: ZLinkActor,
3333
3431
  transferId: string
3334
- ): Promise<void> {
3432
+ ): void {
3335
3433
  const drained = this.formalRemoteActorAdmissions.completeMigration(transferId);
3336
- for (const arrival of drained) {
3434
+ if (drained.length === 0) return;
3435
+ const terminals = drained.map(async (arrival) => {
3337
3436
  try {
3338
3437
  const response = await this.dispatchActorPacket(
3339
3438
  arrival.origin,
@@ -3349,7 +3448,16 @@ export class DefaultZLinkSpotManager {
3349
3448
  } catch (error) {
3350
3449
  arrival.reject(error);
3351
3450
  }
3352
- }
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
+ );
3353
3461
  }
3354
3462
 
3355
3463
  private async dispatchMeshActorPacket(
@@ -3567,7 +3675,7 @@ function validateRemoteAdmissionCommit(
3567
3675
  expected.targetSpotGeneration !== (control.currentSpotGeneration ?? 0n) ||
3568
3676
  actorRef === undefined ||
3569
3677
  actorRef.actorId !== expected.actorRef.actorId ||
3570
- String(actorRef.nodeRid) !== String(expected.actorRef.nodeRid) ||
3678
+ !routingIdsEqual(actorRef.nodeRid, expected.actorRef.nodeRid) ||
3571
3679
  actorRef.objectGeneration !== expected.actorRef.objectGeneration
3572
3680
  ) {
3573
3681
  throw new ZLinkConfigurationException(
@@ -3615,17 +3723,3 @@ function isAbortSignal(value: unknown): value is AbortSignal {
3615
3723
  typeof (value as { addEventListener?: unknown }).addEventListener === 'function'
3616
3724
  );
3617
3725
  }
3618
-
3619
- function instanceActivationOutcome(error: unknown): string {
3620
- if (isAbortError(error)) return 'shutdown';
3621
- if (error instanceof ZLinkFrameworkException) {
3622
- if (error.kind === ZLinkFrameworkErrorKind.DeadlineExceeded) return 'timed_out';
3623
- if (error.kind === ZLinkFrameworkErrorKind.AlreadyExists) return 'conflict';
3624
- if (
3625
- error.kind === ZLinkFrameworkErrorKind.InvalidOperation ||
3626
- error.kind === ZLinkFrameworkErrorKind.Unavailable
3627
- )
3628
- return 'fenced';
3629
- }
3630
- return 'failed';
3631
- }