@zlink-systems/framework 0.25.0 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (557) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/contracts/Channels/IZLinkFanoutClient.d.ts +0 -6
  3. package/dist/contracts/Common/CoreTypes.d.ts +6 -0
  4. package/dist/contracts/Common/CoreTypes.js +7 -0
  5. package/dist/contracts/Common/index.d.ts +1 -1
  6. package/dist/contracts/Common/index.js +0 -1
  7. package/dist/contracts/Configuration/InternalDefaults.d.ts +8 -0
  8. package/dist/contracts/Configuration/InternalDefaults.js +9 -1
  9. package/dist/contracts/Configuration/Registration.d.ts +13 -2
  10. package/dist/contracts/Configuration/Registration.js +58 -36
  11. package/dist/contracts/Configuration/RegistrationBuilderPolicy.d.ts +13 -1
  12. package/dist/contracts/Configuration/RegistrationBuilderPolicy.js +38 -1
  13. package/dist/contracts/Configuration/RegistrationBuilders.d.ts +2 -3
  14. package/dist/contracts/Configuration/RegistrationBuilders.js +27 -32
  15. package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -0
  16. package/dist/contracts/Configuration/RegistrationValidators.js +15 -12
  17. package/dist/contracts/Configuration/TimerRegistrationValidator.js +3 -2
  18. package/dist/contracts/Dispatch/ZLinkDispatchOptions.d.ts +1 -1
  19. package/dist/contracts/Handlers/JsonContract.js +10 -4
  20. package/dist/contracts/Locations/Authority.d.ts +1 -1
  21. package/dist/contracts/Locations/Authority.js +3 -2
  22. package/dist/contracts/Locations/Options.js +1 -1
  23. package/dist/contracts/Locations/Stores.d.ts +12 -0
  24. package/dist/contracts/Locations/Stores.js +9 -0
  25. package/dist/contracts/RouteMesh/RuntimeTopology.d.ts +8 -0
  26. package/dist/contracts/Spots/Contracts.d.ts +1 -1
  27. package/dist/internal.d.ts +5 -0
  28. package/dist/internal.js +16 -1
  29. package/dist/nest-integration.d.ts +4 -2
  30. package/dist/nest-integration.js +14 -4
  31. package/dist/runtime/abort.d.ts +1 -0
  32. package/dist/runtime/abort.js +8 -5
  33. package/dist/runtime/activation-admission.d.ts +28 -0
  34. package/dist/runtime/activation-admission.js +57 -0
  35. package/dist/runtime/actors/actor-authority-payload-codec.d.ts +1 -2
  36. package/dist/runtime/actors/actor-authority-payload-codec.js +34 -18
  37. package/dist/runtime/actors/actor-client.d.ts +2 -2
  38. package/dist/runtime/actors/actor-client.js +42 -143
  39. package/dist/runtime/actors/actor-context.d.ts +3 -5
  40. package/dist/runtime/actors/actor-context.js +19 -17
  41. package/dist/runtime/actors/actor-handoff.d.ts +13 -7
  42. package/dist/runtime/actors/actor-handoff.js +36 -25
  43. package/dist/runtime/actors/actor-lifecycle-snapshot.js +2 -1
  44. package/dist/runtime/actors/actor-local-native-join.d.ts +11 -6
  45. package/dist/runtime/actors/actor-local-native-join.js +85 -123
  46. package/dist/runtime/actors/actor-native-lookup.js +2 -8
  47. package/dist/runtime/actors/actor-packet-relay-wire.d.ts +3 -3
  48. package/dist/runtime/actors/actor-packet-relay-wire.js +5 -3
  49. package/dist/runtime/actors/actor-remote-joiner.d.ts +3 -3
  50. package/dist/runtime/actors/actor-remote-joiner.js +11 -17
  51. package/dist/runtime/actors/actor-remote-wire.js +5 -3
  52. package/dist/runtime/actors/actor-request-deadline.d.ts +3 -0
  53. package/dist/runtime/actors/actor-request-deadline.js +31 -0
  54. package/dist/runtime/actors/actor-retry-delay.js +2 -1
  55. package/dist/runtime/actors/actor-runtime-contracts.d.ts +4 -2
  56. package/dist/runtime/actors/actor-runtime-state.d.ts +9 -21
  57. package/dist/runtime/actors/actor-runtime-state.js +70 -187
  58. package/dist/runtime/actors/actor-source-transfer.d.ts +5 -5
  59. package/dist/runtime/actors/bound-session-wire.js +2 -7
  60. package/dist/runtime/actors/deferred-join-completion.d.ts +19 -0
  61. package/dist/runtime/actors/deferred-join-completion.js +21 -0
  62. package/dist/runtime/actors/index.d.ts +10 -8
  63. package/dist/runtime/actors/index.js +101 -73
  64. package/dist/runtime/actors/spot-actor-dispatch.d.ts +3 -3
  65. package/dist/runtime/actors/spot-actor-dispatch.js +25 -10
  66. package/dist/runtime/actors/transferred-actor-rollback.d.ts +3 -5
  67. package/dist/runtime/actors/transferred-actor-rollback.js +9 -42
  68. package/dist/runtime/admission.d.ts +7 -1
  69. package/dist/runtime/admission.js +11 -1
  70. package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +1 -1
  71. package/dist/runtime/application-jobs/application-job-queue-scope.js +1 -1
  72. package/dist/runtime/backend/contracts/index.d.ts +8 -33
  73. package/dist/runtime/backend/mesh-actor-session-node-adapter.js +3 -26
  74. package/dist/runtime/backend/mesh-dispatch-pump.d.ts +1 -2
  75. package/dist/runtime/backend/mesh-dispatch-pump.js +95 -107
  76. package/dist/runtime/backend/node/node-backend-adapter-factory.d.ts +1 -2
  77. package/dist/runtime/backend/node/node-backend-adapter-factory.js +4 -18
  78. package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +7 -4
  79. package/dist/runtime/backend/node/node-backend-adapter-support.js +28 -34
  80. package/dist/runtime/backend/node/node-event-loop-poller.d.ts +2 -2
  81. package/dist/runtime/backend/node/node-event-loop-poller.js +11 -6
  82. package/dist/runtime/backend/node/node-monitor-backend-adapter.js +1 -0
  83. package/dist/runtime/backend/node/node-raw-binding-port.d.ts +1 -1
  84. package/dist/runtime/backend/node/node-raw-binding-port.js +51 -19
  85. package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +21 -19
  86. package/dist/runtime/backend/node/node-raw-mesh-backend.js +171 -111
  87. package/dist/runtime/backend/node/node-socket-backend-adapter.js +4 -3
  88. package/dist/runtime/backend/raw-binding-port.d.ts +13 -1
  89. package/dist/runtime/backend/runtime-values.d.ts +4 -1
  90. package/dist/runtime/backend/runtime-values.js +2 -0
  91. package/dist/runtime/channels/channel-clients.d.ts +20 -9
  92. package/dist/runtime/channels/channel-clients.js +68 -60
  93. package/dist/runtime/channels/channel-envelope-inspection.js +2 -1
  94. package/dist/runtime/channels/channel-envelope.js +47 -29
  95. package/dist/runtime/channels/channel-outbound-operations.d.ts +3 -0
  96. package/dist/runtime/channels/channel-outbound-operations.js +9 -18
  97. package/dist/runtime/channels/channel-receive-loops.d.ts +8 -3
  98. package/dist/runtime/channels/channel-receive-loops.js +27 -6
  99. package/dist/runtime/channels/channel-runtime-lifecycle.d.ts +12 -1
  100. package/dist/runtime/channels/channel-runtime-lifecycle.js +48 -28
  101. package/dist/runtime/channels/channel-runtime-manager.d.ts +2 -5
  102. package/dist/runtime/channels/channel-runtime-manager.js +4 -12
  103. package/dist/runtime/channels/channel-socket-options.js +3 -2
  104. package/dist/runtime/channels/channel-socket-registry.d.ts +30 -32
  105. package/dist/runtime/channels/channel-socket-registry.js +296 -235
  106. package/dist/runtime/channels/channel-transports.d.ts +11 -20
  107. package/dist/runtime/channels/channel-transports.js +68 -47
  108. package/dist/runtime/channels/client-server-location-runtime.d.ts +1 -1
  109. package/dist/runtime/channels/client-server-location-runtime.js +10 -11
  110. package/dist/runtime/channels/client-server-service-wire.d.ts +7 -2
  111. package/dist/runtime/channels/client-server-service-wire.js +32 -11
  112. package/dist/runtime/channels/dispatch-error-reporter.d.ts +1 -2
  113. package/dist/runtime/channels/dispatch-error-reporter.js +2 -1
  114. package/dist/runtime/channels/fanout-location-runtime.d.ts +16 -3
  115. package/dist/runtime/channels/fanout-location-runtime.js +133 -81
  116. package/dist/runtime/channels/spot-direct-envelope.d.ts +1 -0
  117. package/dist/runtime/channels/spot-direct-envelope.js +4 -3
  118. package/dist/runtime/channels/spot-node-route-transport.js +3 -2
  119. package/dist/runtime/diagnostics/diagnostic-text.d.ts +2 -0
  120. package/dist/runtime/diagnostics/diagnostic-text.js +7 -0
  121. package/dist/runtime/diagnostics/dispatch-error-details.d.ts +3 -0
  122. package/dist/runtime/diagnostics/dispatch-error-details.js +30 -2
  123. package/dist/runtime/diagnostics/flow-context.d.ts +6 -0
  124. package/dist/runtime/diagnostics/flow-context.js +16 -2
  125. package/dist/runtime/diagnostics/index.d.ts +4 -2
  126. package/dist/runtime/diagnostics/index.js +14 -4
  127. package/dist/runtime/diagnostics/message-flow.d.ts +1 -1
  128. package/dist/runtime/diagnostics/message-flow.js +10 -19
  129. package/dist/runtime/diagnostics/runtime-metrics.d.ts +94 -31
  130. package/dist/runtime/diagnostics/runtime-metrics.js +168 -105
  131. package/dist/runtime/diagnostics/runtime-observation-queue.js +3 -2
  132. package/dist/runtime/diagnostics/topology-runtime-projections.d.ts +2 -4
  133. package/dist/runtime/diagnostics/topology-runtime-projections.js +135 -154
  134. package/dist/runtime/disposal.d.ts +5 -0
  135. package/dist/runtime/disposal.js +22 -0
  136. package/dist/runtime/execution/index.d.ts +22 -9
  137. package/dist/runtime/execution/index.js +107 -37
  138. package/dist/runtime/execution/serial-execution-queue.d.ts +12 -7
  139. package/dist/runtime/execution/serial-execution-queue.js +99 -26
  140. package/dist/runtime/execution/state-lane.d.ts +8 -1
  141. package/dist/runtime/execution/state-lane.js +118 -3
  142. package/dist/runtime/foundation/actor-join-recovery-codec.d.ts +3 -0
  143. package/dist/runtime/foundation/actor-join-recovery-codec.js +15 -11
  144. package/dist/runtime/foundation/event-loop-resources.d.ts +2 -24
  145. package/dist/runtime/foundation/event-loop-resources.js +6 -119
  146. package/dist/runtime/foundation/listener-records.d.ts +11 -0
  147. package/dist/runtime/foundation/listener-records.js +20 -0
  148. package/dist/runtime/foundation/operation-identity.d.ts +2 -0
  149. package/dist/runtime/foundation/operation-identity.js +9 -5
  150. package/dist/runtime/foundation/operation-registry.d.ts +5 -7
  151. package/dist/runtime/foundation/operation-registry.js +34 -44
  152. package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +18 -26
  153. package/dist/runtime/foundation/raw-service-mesh-runtime.js +122 -469
  154. package/dist/runtime/foundation/runtime-state-projections.d.ts +3 -1
  155. package/dist/runtime/foundation/runtime-state-projections.js +8 -0
  156. package/dist/runtime/foundation/service-authority-payload-codec.d.ts +1 -0
  157. package/dist/runtime/foundation/service-authority-payload-codec.js +30 -12
  158. package/dist/runtime/foundation/service-discovery-registry.d.ts +4 -0
  159. package/dist/runtime/foundation/service-discovery-registry.js +22 -3
  160. package/dist/runtime/foundation/service-instance-activation-recovery-codec.js +8 -4
  161. package/dist/runtime/foundation/service-liveness-registry.js +2 -1
  162. package/dist/runtime/foundation/service-maintenance-runtime.d.ts +0 -1
  163. package/dist/runtime/foundation/service-maintenance-runtime.js +23 -8
  164. package/dist/runtime/foundation/service-metadata-codec.js +3 -3
  165. package/dist/runtime/foundation/service-relocation-aggregate-committer.d.ts +2 -5
  166. package/dist/runtime/foundation/service-relocation-aggregate-committer.js +1 -48
  167. package/dist/runtime/foundation/service-relocation-coordinator.d.ts +9 -0
  168. package/dist/runtime/foundation/service-relocation-coordinator.js +14 -1
  169. package/dist/runtime/foundation/service-relocation-object-owner.d.ts +8 -0
  170. package/dist/runtime/foundation/service-relocation-object-owner.js +19 -6
  171. package/dist/runtime/foundation/service-relocation-runtime.js +43 -32
  172. package/dist/runtime/foundation/service-runtime-contracts.d.ts +40 -8
  173. package/dist/runtime/foundation/service-runtime-contracts.js +25 -1
  174. package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +0 -19
  175. package/dist/runtime/foundation/service-stateful-registry.d.ts +2 -0
  176. package/dist/runtime/foundation/service-stateful-registry.js +10 -2
  177. package/dist/runtime/foundation/service-stateful-runtime.d.ts +28 -24
  178. package/dist/runtime/foundation/service-stateful-runtime.js +297 -244
  179. package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +12 -7
  180. package/dist/runtime/foundation/service-stateful-wire-codec.js +240 -143
  181. package/dist/runtime/foundation/service-topology-registry.d.ts +1 -3
  182. package/dist/runtime/foundation/service-topology-registry.js +22 -61
  183. package/dist/runtime/foundation/service-wire-binary-primitives.d.ts +5 -0
  184. package/dist/runtime/foundation/service-wire-binary-primitives.js +6 -0
  185. package/dist/runtime/foundation/service-wire-codec.js +10 -8
  186. package/dist/runtime/foundation/service-wire-constants.generated.d.ts +1 -0
  187. package/dist/runtime/foundation/service-wire-constants.generated.js +2 -1
  188. package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +2 -0
  189. package/dist/runtime/foundation/service-wire-m6a-codec.js +23 -13
  190. package/dist/runtime/framework-errors-internal.d.ts +2 -1
  191. package/dist/runtime/framework-errors-internal.js +343 -122
  192. package/dist/runtime/handlers/handler-instance-scope.d.ts +3 -1
  193. package/dist/runtime/handlers/handler-instance-scope.js +61 -74
  194. package/dist/runtime/host/actor-packet-relay.d.ts +9 -6
  195. package/dist/runtime/host/actor-packet-relay.js +48 -91
  196. package/dist/runtime/host/actor-placement-coordinator.js +7 -5
  197. package/dist/runtime/host/actor-runtime-options-factory.d.ts +2 -0
  198. package/dist/runtime/host/actor-runtime-options-factory.js +17 -4
  199. package/dist/runtime/host/actor-transfer-runtime.d.ts +28 -28
  200. package/dist/runtime/host/actor-transfer-runtime.js +210 -256
  201. package/dist/runtime/host/application-job-queue.js +16 -33
  202. package/dist/runtime/host/bound-session-relay.js +1 -1
  203. package/dist/runtime/host/channel-runtime-options-factory.js +1 -1
  204. package/dist/runtime/host/index.d.ts +19 -14
  205. package/dist/runtime/host/index.js +234 -175
  206. package/dist/runtime/host/instance-activation-authority.d.ts +2 -3
  207. package/dist/runtime/host/instance-activation-authority.js +17 -45
  208. package/dist/runtime/host/location-runtime-owner.d.ts +1 -1
  209. package/dist/runtime/host/location-runtime-owner.js +2 -2
  210. package/dist/runtime/host/remote-actor-join-receiver.d.ts +2 -2
  211. package/dist/runtime/host/remote-actor-join-receiver.js +1 -14
  212. package/dist/runtime/host/remote-actor-packet-target-store.d.ts +3 -2
  213. package/dist/runtime/host/remote-actor-packet-target-store.js +8 -47
  214. package/dist/runtime/host/remote-bound-session-relay.d.ts +2 -3
  215. package/dist/runtime/host/remote-bound-session-relay.js +11 -23
  216. package/dist/runtime/host/route-mesh-runtime.d.ts +14 -10
  217. package/dist/runtime/host/route-mesh-runtime.js +178 -257
  218. package/dist/runtime/host/runtime-shutdown.d.ts +2 -0
  219. package/dist/runtime/host/runtime-shutdown.js +18 -21
  220. package/dist/runtime/host/service-relocation-control.js +6 -1
  221. package/dist/runtime/host/service-relocation-host-runtime.d.ts +71 -38
  222. package/dist/runtime/host/service-relocation-host-runtime.js +816 -651
  223. package/dist/runtime/host/spot-address-transport.d.ts +2 -3
  224. package/dist/runtime/host/spot-address-transport.js +34 -136
  225. package/dist/runtime/host/spot-node-runtime-options-factory.d.ts +1 -1
  226. package/dist/runtime/host/spot-node-runtime-options-factory.js +3 -2
  227. package/dist/runtime/host/spot-runtime-options-factory.d.ts +4 -7
  228. package/dist/runtime/host/spot-runtime-options-factory.js +53 -21
  229. package/dist/runtime/host/stateful-authority-route-runtime.js +6 -2
  230. package/dist/runtime/host/user-spot-creation-coordinator.d.ts +14 -6
  231. package/dist/runtime/host/user-spot-creation-coordinator.js +96 -95
  232. package/dist/runtime/locations/aggregate-inventory-store.js +13 -10
  233. package/dist/runtime/locations/authority-key-codec.js +4 -3
  234. package/dist/runtime/locations/auto-connect-reconciler.d.ts +4 -0
  235. package/dist/runtime/locations/auto-connect-reconciler.js +37 -25
  236. package/dist/runtime/locations/creation-operation-id.js +6 -4
  237. package/dist/runtime/locations/domain-store-contract.d.ts +3 -3
  238. package/dist/runtime/locations/in-memory-authority-store.js +31 -15
  239. package/dist/runtime/locations/in-memory-location-store.d.ts +2 -2
  240. package/dist/runtime/locations/in-memory-location-store.js +17 -14
  241. package/dist/runtime/locations/in-memory-provider-location-store.d.ts +1 -0
  242. package/dist/runtime/locations/in-memory-provider-location-store.js +79 -27
  243. package/dist/runtime/locations/key-codec.js +3 -2
  244. package/dist/runtime/locations/lease-tracker.d.ts +3 -5
  245. package/dist/runtime/locations/lease-tracker.js +7 -11
  246. package/dist/runtime/locations/lifecycle.d.ts +5 -10
  247. package/dist/runtime/locations/lifecycle.js +4 -33
  248. package/dist/runtime/locations/location-store-failure.d.ts +2 -0
  249. package/dist/runtime/locations/location-store-failure.js +7 -0
  250. package/dist/runtime/locations/location-store-pages.d.ts +3 -0
  251. package/dist/runtime/locations/location-store-pages.js +13 -0
  252. package/dist/runtime/locations/location-store-repository.d.ts +5 -7
  253. package/dist/runtime/locations/location-store-repository.js +303 -332
  254. package/dist/runtime/locations/relocation-blob.js +18 -5
  255. package/dist/runtime/locations/resolvers.d.ts +5 -5
  256. package/dist/runtime/locations/resolvers.js +44 -30
  257. package/dist/runtime/locations/runtime.d.ts +5 -4
  258. package/dist/runtime/locations/runtime.js +123 -92
  259. package/dist/runtime/locations/spot-location-claims.d.ts +8 -2
  260. package/dist/runtime/locations/spot-location-claims.js +40 -23
  261. package/dist/runtime/messaging/payload-codec.js +26 -20
  262. package/dist/runtime/messaging/submission-result.d.ts +3 -0
  263. package/dist/runtime/messaging/submission-result.js +48 -0
  264. package/dist/runtime/protocol/service_wire_codec.generated.d.ts +2 -0
  265. package/dist/runtime/protocol/service_wire_codec.generated.js +17 -8
  266. package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +1 -0
  267. package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +3 -2
  268. package/dist/runtime/spots/formal-remote-actor-admission-registry.d.ts +3 -3
  269. package/dist/runtime/spots/formal-remote-actor-admission-registry.js +4 -4
  270. package/dist/runtime/spots/formal-remote-actor-transfer-registry.d.ts +6 -3
  271. package/dist/runtime/spots/index.d.ts +29 -29
  272. package/dist/runtime/spots/index.js +441 -313
  273. package/dist/runtime/spots/spot-activation-registry.d.ts +4 -4
  274. package/dist/runtime/spots/spot-activation-registry.js +27 -60
  275. package/dist/runtime/spots/spot-activation-state.d.ts +2 -11
  276. package/dist/runtime/spots/spot-activation-state.js +4 -17
  277. package/dist/runtime/spots/spot-activation.d.ts +10 -9
  278. package/dist/runtime/spots/spot-activation.js +103 -81
  279. package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +1 -2
  280. package/dist/runtime/spots/spot-actor-admission-coordinator.js +3 -40
  281. package/dist/runtime/spots/spot-actor-join-dispatch.d.ts +10 -18
  282. package/dist/runtime/spots/spot-actor-join-dispatch.js +5 -55
  283. package/dist/runtime/spots/spot-actor-lifecycle-drain.js +2 -2
  284. package/dist/runtime/spots/spot-actor-membership.d.ts +7 -5
  285. package/dist/runtime/spots/spot-actor-membership.js +44 -53
  286. package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +0 -1
  287. package/dist/runtime/spots/spot-actor-packet-dispatch.js +0 -9
  288. package/dist/runtime/spots/spot-actor-packet-relay-dispatch.d.ts +2 -2
  289. package/dist/runtime/spots/spot-actor-packet-relay-dispatch.js +1 -7
  290. package/dist/runtime/spots/spot-context.d.ts +2 -2
  291. package/dist/runtime/spots/spot-entry-activation.d.ts +3 -4
  292. package/dist/runtime/spots/spot-entry-activation.js +9 -21
  293. package/dist/runtime/spots/spot-lifecycle-metrics.js +3 -2
  294. package/dist/runtime/spots/spot-manager-public.d.ts +5 -6
  295. package/dist/runtime/spots/spot-manager-public.js +6 -5
  296. package/dist/runtime/spots/spot-node-autoconnect.js +22 -31
  297. package/dist/runtime/spots/spot-node-runtime-manager.d.ts +22 -21
  298. package/dist/runtime/spots/spot-node-runtime-manager.js +73 -82
  299. package/dist/runtime/spots/spot-outbound.d.ts +4 -3
  300. package/dist/runtime/spots/spot-outbound.js +10 -37
  301. package/dist/runtime/spots/spot-remote-codec.js +5 -3
  302. package/dist/runtime/spots/spot-route-packet-dispatch.d.ts +2 -2
  303. package/dist/runtime/spots/spot-route-packet-dispatch.js +8 -8
  304. package/dist/runtime/spots/spot-route-replies.d.ts +2 -2
  305. package/dist/runtime/spots/spot-route-replies.js +3 -1
  306. package/dist/runtime/spots/spot-routed-actor-admission.d.ts +3 -2
  307. package/dist/runtime/spots/spot-routed-actor-admission.js +3 -2
  308. package/dist/runtime/spots/spot-routed-frame-dispatch.d.ts +2 -7
  309. package/dist/runtime/spots/spot-routed-frame-dispatch.js +1 -70
  310. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.d.ts +4 -0
  311. package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +65 -15
  312. package/dist/runtime/spots/spot-runtime-ports.d.ts +4 -20
  313. package/dist/runtime/spots/spot-serial-executor.d.ts +5 -0
  314. package/dist/runtime/spots/spot-serial-executor.js +9 -2
  315. package/dist/runtime/spots/spot-serial-turn-executor.d.ts +29 -6
  316. package/dist/runtime/spots/spot-serial-turn-executor.js +89 -13
  317. package/dist/runtime/spots/spot-timer.d.ts +3 -2
  318. package/dist/runtime/streams/actor-session-binding-registry.d.ts +17 -32
  319. package/dist/runtime/streams/actor-session-binding-registry.js +145 -367
  320. package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +2 -6
  321. package/dist/runtime/streams/bound-actor-relay-sender.d.ts +6 -2
  322. package/dist/runtime/streams/bound-actor-relay-sender.js +57 -33
  323. package/dist/runtime/streams/bound-session-service.d.ts +7 -0
  324. package/dist/runtime/streams/bound-session-service.js +12 -19
  325. package/dist/runtime/streams/index.d.ts +15 -14
  326. package/dist/runtime/streams/index.js +38 -39
  327. package/dist/runtime/streams/managed-stream.d.ts +3 -0
  328. package/dist/runtime/streams/managed-stream.js +17 -8
  329. package/dist/runtime/streams/native-fallback-bound-session.js +1 -3
  330. package/dist/runtime/streams/protocol.d.ts +6 -33
  331. package/dist/runtime/streams/protocol.js +38 -110
  332. package/dist/runtime/streams/session-actor-coordinator.d.ts +2 -3
  333. package/dist/runtime/streams/session-actor-coordinator.js +12 -4
  334. package/dist/runtime/streams/session-calls.d.ts +1 -1
  335. package/dist/runtime/streams/session-calls.js +5 -4
  336. package/dist/runtime/streams/session-context.d.ts +6 -6
  337. package/dist/runtime/streams/session-context.js +22 -4
  338. package/dist/runtime/streams/session-requests.js +2 -1
  339. package/dist/runtime/streams/session-serial-executor.js +2 -2
  340. package/dist/runtime/streams/stream-binding-runtime-ports.d.ts +16 -1
  341. package/dist/runtime/streams/stream-frame-factory.js +2 -2
  342. package/dist/runtime/streams/stream-session-runtime.d.ts +10 -11
  343. package/dist/runtime/streams/stream-session-runtime.js +25 -33
  344. package/dist/runtime/workers/index.d.ts +2 -2
  345. package/dist/runtime/workers/index.js +5 -4
  346. package/package.json +3 -3
  347. package/src/contracts/Channels/IZLinkFanoutClient.ts +0 -7
  348. package/src/contracts/Common/CoreTypes.ts +7 -0
  349. package/src/contracts/Common/index.ts +1 -1
  350. package/src/contracts/Configuration/InternalDefaults.ts +12 -0
  351. package/src/contracts/Configuration/Registration.ts +92 -48
  352. package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +44 -2
  353. package/src/contracts/Configuration/RegistrationBuilders.ts +77 -68
  354. package/src/contracts/Configuration/RegistrationTypes.ts +1 -0
  355. package/src/contracts/Configuration/RegistrationValidators.ts +19 -13
  356. package/src/contracts/Configuration/TimerRegistrationValidator.ts +4 -2
  357. package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +1 -0
  358. package/src/contracts/Handlers/JsonContract.ts +14 -4
  359. package/src/contracts/Locations/Authority.ts +7 -3
  360. package/src/contracts/Locations/Options.ts +1 -1
  361. package/src/contracts/Locations/Stores.ts +14 -0
  362. package/src/contracts/RouteMesh/RuntimeTopology.ts +10 -0
  363. package/src/contracts/Spots/Contracts.ts +1 -1
  364. package/src/internal.ts +15 -0
  365. package/src/nest-integration.ts +28 -10
  366. package/src/runtime/abort.ts +6 -5
  367. package/src/runtime/activation-admission.ts +72 -0
  368. package/src/runtime/actors/actor-authority-payload-codec.ts +58 -20
  369. package/src/runtime/actors/actor-client.ts +77 -204
  370. package/src/runtime/actors/actor-context.ts +45 -39
  371. package/src/runtime/actors/actor-handoff.ts +55 -45
  372. package/src/runtime/actors/actor-lifecycle-snapshot.ts +2 -1
  373. package/src/runtime/actors/actor-local-native-join.ts +174 -215
  374. package/src/runtime/actors/actor-native-lookup.ts +2 -9
  375. package/src/runtime/actors/actor-packet-relay-wire.ts +18 -12
  376. package/src/runtime/actors/actor-remote-joiner.ts +15 -36
  377. package/src/runtime/actors/actor-remote-wire.ts +5 -3
  378. package/src/runtime/actors/actor-request-deadline.ts +49 -0
  379. package/src/runtime/actors/actor-retry-delay.ts +2 -1
  380. package/src/runtime/actors/actor-runtime-contracts.ts +4 -10
  381. package/src/runtime/actors/actor-runtime-state.ts +85 -247
  382. package/src/runtime/actors/actor-source-transfer.ts +5 -18
  383. package/src/runtime/actors/bound-session-wire.ts +2 -8
  384. package/src/runtime/actors/deferred-join-completion.ts +44 -0
  385. package/src/runtime/actors/index.ts +122 -88
  386. package/src/runtime/actors/spot-actor-dispatch.ts +60 -29
  387. package/src/runtime/actors/transferred-actor-rollback.ts +11 -62
  388. package/src/runtime/admission.ts +13 -2
  389. package/src/runtime/application-jobs/application-job-queue-scope.ts +4 -4
  390. package/src/runtime/backend/contracts/index.ts +15 -42
  391. package/src/runtime/backend/mesh-actor-session-node-adapter.ts +4 -28
  392. package/src/runtime/backend/mesh-dispatch-pump.ts +111 -117
  393. package/src/runtime/backend/node/node-backend-adapter-factory.ts +5 -25
  394. package/src/runtime/backend/node/node-backend-adapter-support.ts +32 -35
  395. package/src/runtime/backend/node/node-event-loop-poller.ts +16 -8
  396. package/src/runtime/backend/node/node-monitor-backend-adapter.ts +1 -0
  397. package/src/runtime/backend/node/node-raw-binding-port.ts +58 -23
  398. package/src/runtime/backend/node/node-raw-mesh-backend.ts +252 -162
  399. package/src/runtime/backend/node/node-socket-backend-adapter.ts +5 -4
  400. package/src/runtime/backend/raw-binding-port.ts +14 -1
  401. package/src/runtime/backend/runtime-values.ts +4 -1
  402. package/src/runtime/channels/channel-clients.ts +132 -96
  403. package/src/runtime/channels/channel-envelope-inspection.ts +2 -1
  404. package/src/runtime/channels/channel-envelope.ts +58 -29
  405. package/src/runtime/channels/channel-outbound-operations.ts +10 -31
  406. package/src/runtime/channels/channel-receive-loops.ts +39 -7
  407. package/src/runtime/channels/channel-runtime-lifecycle.ts +60 -27
  408. package/src/runtime/channels/channel-runtime-manager.ts +8 -15
  409. package/src/runtime/channels/channel-socket-options.ts +8 -2
  410. package/src/runtime/channels/channel-socket-registry.ts +369 -262
  411. package/src/runtime/channels/channel-transports.ts +161 -115
  412. package/src/runtime/channels/client-server-location-runtime.ts +17 -17
  413. package/src/runtime/channels/client-server-service-wire.ts +40 -12
  414. package/src/runtime/channels/dispatch-error-reporter.ts +7 -5
  415. package/src/runtime/channels/fanout-location-runtime.ts +175 -106
  416. package/src/runtime/channels/spot-direct-envelope.ts +1 -1
  417. package/src/runtime/channels/spot-node-route-transport.ts +5 -2
  418. package/src/runtime/diagnostics/diagnostic-text.ts +4 -0
  419. package/src/runtime/diagnostics/dispatch-error-details.ts +36 -1
  420. package/src/runtime/diagnostics/flow-context.ts +16 -2
  421. package/src/runtime/diagnostics/index.ts +27 -17
  422. package/src/runtime/diagnostics/message-flow.ts +15 -25
  423. package/src/runtime/diagnostics/runtime-metrics.ts +181 -113
  424. package/src/runtime/diagnostics/runtime-observation-queue.ts +3 -2
  425. package/src/runtime/diagnostics/topology-runtime-projections.ts +194 -162
  426. package/src/runtime/disposal.ts +19 -0
  427. package/src/runtime/execution/index.ts +116 -38
  428. package/src/runtime/execution/serial-execution-queue.ts +179 -34
  429. package/src/runtime/execution/state-lane.ts +142 -4
  430. package/src/runtime/foundation/actor-join-recovery-codec.ts +13 -8
  431. package/src/runtime/foundation/event-loop-resources.ts +5 -122
  432. package/src/runtime/foundation/listener-records.ts +21 -0
  433. package/src/runtime/foundation/operation-identity.ts +11 -5
  434. package/src/runtime/foundation/operation-registry.ts +33 -50
  435. package/src/runtime/foundation/raw-service-mesh-runtime.ts +170 -571
  436. package/src/runtime/foundation/runtime-state-projections.ts +9 -1
  437. package/src/runtime/foundation/service-authority-payload-codec.ts +41 -13
  438. package/src/runtime/foundation/service-discovery-registry.ts +32 -3
  439. package/src/runtime/foundation/service-instance-activation-recovery-codec.ts +12 -4
  440. package/src/runtime/foundation/service-liveness-registry.ts +2 -1
  441. package/src/runtime/foundation/service-maintenance-runtime.ts +30 -19
  442. package/src/runtime/foundation/service-metadata-codec.ts +2 -2
  443. package/src/runtime/foundation/service-relocation-aggregate-committer.ts +3 -66
  444. package/src/runtime/foundation/service-relocation-coordinator.ts +13 -0
  445. package/src/runtime/foundation/service-relocation-object-owner.ts +23 -7
  446. package/src/runtime/foundation/service-relocation-runtime.ts +57 -35
  447. package/src/runtime/foundation/service-runtime-contracts.ts +46 -10
  448. package/src/runtime/foundation/service-session-binding-ingress-port.ts +0 -25
  449. package/src/runtime/foundation/service-stateful-registry.ts +14 -2
  450. package/src/runtime/foundation/service-stateful-runtime.ts +435 -327
  451. package/src/runtime/foundation/service-stateful-wire-codec.ts +329 -199
  452. package/src/runtime/foundation/service-topology-registry.ts +30 -79
  453. package/src/runtime/foundation/service-wire-binary-primitives.ts +6 -0
  454. package/src/runtime/foundation/service-wire-codec.ts +15 -8
  455. package/src/runtime/foundation/service-wire-constants.generated.ts +1 -0
  456. package/src/runtime/foundation/service-wire-m6a-codec.ts +29 -15
  457. package/src/runtime/framework-errors-internal.ts +380 -134
  458. package/src/runtime/handlers/handler-instance-scope.ts +68 -95
  459. package/src/runtime/host/actor-packet-relay.ts +57 -147
  460. package/src/runtime/host/actor-placement-coordinator.ts +8 -5
  461. package/src/runtime/host/actor-runtime-options-factory.ts +27 -8
  462. package/src/runtime/host/actor-transfer-runtime.ts +266 -418
  463. package/src/runtime/host/application-job-queue.ts +28 -34
  464. package/src/runtime/host/bound-session-relay.ts +1 -2
  465. package/src/runtime/host/channel-runtime-options-factory.ts +1 -2
  466. package/src/runtime/host/index.ts +408 -312
  467. package/src/runtime/host/instance-activation-authority.ts +89 -109
  468. package/src/runtime/host/location-runtime-owner.ts +4 -2
  469. package/src/runtime/host/remote-actor-join-receiver.ts +3 -31
  470. package/src/runtime/host/remote-actor-packet-target-store.ts +17 -58
  471. package/src/runtime/host/remote-bound-session-relay.ts +12 -44
  472. package/src/runtime/host/route-mesh-runtime.ts +236 -275
  473. package/src/runtime/host/runtime-shutdown.ts +17 -21
  474. package/src/runtime/host/service-relocation-control.ts +14 -1
  475. package/src/runtime/host/service-relocation-host-runtime.ts +1161 -904
  476. package/src/runtime/host/spot-address-transport.ts +73 -195
  477. package/src/runtime/host/spot-node-runtime-options-factory.ts +6 -3
  478. package/src/runtime/host/spot-runtime-options-factory.ts +92 -30
  479. package/src/runtime/host/stateful-authority-route-runtime.ts +8 -4
  480. package/src/runtime/host/user-spot-creation-coordinator.ts +182 -163
  481. package/src/runtime/locations/aggregate-inventory-store.ts +16 -13
  482. package/src/runtime/locations/authority-key-codec.ts +7 -3
  483. package/src/runtime/locations/auto-connect-reconciler.ts +39 -26
  484. package/src/runtime/locations/creation-operation-id.ts +6 -3
  485. package/src/runtime/locations/domain-store-contract.ts +12 -3
  486. package/src/runtime/locations/in-memory-authority-store.ts +44 -15
  487. package/src/runtime/locations/in-memory-location-store.ts +50 -39
  488. package/src/runtime/locations/in-memory-provider-location-store.ts +110 -31
  489. package/src/runtime/locations/key-codec.ts +3 -2
  490. package/src/runtime/locations/lease-tracker.ts +8 -14
  491. package/src/runtime/locations/lifecycle.ts +16 -45
  492. package/src/runtime/locations/location-store-failure.ts +4 -0
  493. package/src/runtime/locations/location-store-pages.ts +18 -0
  494. package/src/runtime/locations/location-store-repository.ts +450 -478
  495. package/src/runtime/locations/relocation-blob.ts +17 -6
  496. package/src/runtime/locations/resolvers.ts +90 -58
  497. package/src/runtime/locations/runtime.ts +220 -110
  498. package/src/runtime/locations/spot-location-claims.ts +54 -26
  499. package/src/runtime/messaging/payload-codec.ts +35 -24
  500. package/src/runtime/messaging/submission-result.ts +57 -1
  501. package/src/runtime/protocol/service_wire_codec.generated.ts +27 -10
  502. package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +4 -4
  503. package/src/runtime/spots/formal-remote-actor-admission-registry.ts +6 -6
  504. package/src/runtime/spots/formal-remote-actor-transfer-registry.ts +6 -3
  505. package/src/runtime/spots/index.ts +687 -437
  506. package/src/runtime/spots/spot-activation-registry.ts +42 -71
  507. package/src/runtime/spots/spot-activation-state.ts +4 -16
  508. package/src/runtime/spots/spot-activation.ts +167 -115
  509. package/src/runtime/spots/spot-actor-admission-coordinator.ts +5 -57
  510. package/src/runtime/spots/spot-actor-join-dispatch.ts +25 -79
  511. package/src/runtime/spots/spot-actor-lifecycle-drain.ts +20 -18
  512. package/src/runtime/spots/spot-actor-membership.ts +107 -75
  513. package/src/runtime/spots/spot-actor-packet-dispatch.ts +0 -16
  514. package/src/runtime/spots/spot-actor-packet-relay-dispatch.ts +3 -15
  515. package/src/runtime/spots/spot-context.ts +3 -3
  516. package/src/runtime/spots/spot-entry-activation.ts +13 -33
  517. package/src/runtime/spots/spot-lifecycle-metrics.ts +3 -2
  518. package/src/runtime/spots/spot-manager-public.ts +29 -21
  519. package/src/runtime/spots/spot-node-autoconnect.ts +20 -26
  520. package/src/runtime/spots/spot-node-runtime-manager.ts +145 -140
  521. package/src/runtime/spots/spot-outbound.ts +47 -68
  522. package/src/runtime/spots/spot-remote-codec.ts +7 -3
  523. package/src/runtime/spots/spot-route-packet-dispatch.ts +25 -24
  524. package/src/runtime/spots/spot-route-replies.ts +6 -4
  525. package/src/runtime/spots/spot-routed-actor-admission.ts +13 -6
  526. package/src/runtime/spots/spot-routed-frame-dispatch.ts +6 -77
  527. package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +95 -22
  528. package/src/runtime/spots/spot-runtime-ports.ts +10 -43
  529. package/src/runtime/spots/spot-serial-executor.ts +10 -2
  530. package/src/runtime/spots/spot-serial-turn-executor.ts +120 -13
  531. package/src/runtime/spots/spot-timer.ts +3 -2
  532. package/src/runtime/streams/actor-session-binding-registry.ts +182 -560
  533. package/src/runtime/streams/actor-session-binding-runtime-owner.ts +1 -19
  534. package/src/runtime/streams/bound-actor-relay-sender.ts +89 -43
  535. package/src/runtime/streams/bound-session-service.ts +23 -37
  536. package/src/runtime/streams/index.ts +102 -88
  537. package/src/runtime/streams/managed-stream.ts +29 -10
  538. package/src/runtime/streams/native-fallback-bound-session.ts +1 -3
  539. package/src/runtime/streams/protocol.ts +34 -88
  540. package/src/runtime/streams/session-actor-coordinator.ts +17 -5
  541. package/src/runtime/streams/session-calls.ts +6 -5
  542. package/src/runtime/streams/session-context.ts +54 -10
  543. package/src/runtime/streams/session-requests.ts +2 -1
  544. package/src/runtime/streams/session-serial-executor.ts +2 -2
  545. package/src/runtime/streams/stream-binding-runtime-ports.ts +22 -1
  546. package/src/runtime/streams/stream-frame-factory.ts +2 -3
  547. package/src/runtime/streams/stream-session-runtime.ts +57 -59
  548. package/src/runtime/workers/index.ts +13 -12
  549. package/dist/runtime/actors/deferred-join-accepted-journal.d.ts +0 -47
  550. package/dist/runtime/actors/deferred-join-accepted-journal.js +0 -992
  551. package/dist/runtime/actors/post-commit-actor-location.d.ts +0 -19
  552. package/dist/runtime/actors/post-commit-actor-location.js +0 -72
  553. package/dist/runtime/spots/spot-native-actor-join-admission.d.ts +0 -26
  554. package/dist/runtime/spots/spot-native-actor-join-admission.js +0 -106
  555. package/src/runtime/actors/deferred-join-accepted-journal.ts +0 -1346
  556. package/src/runtime/actors/post-commit-actor-location.ts +0 -121
  557. package/src/runtime/spots/spot-native-actor-join-admission.ts +0 -155
@@ -1,5 +1,20 @@
1
+ import { ZlinkStreamContentType } from '@zlink-systems/stream-wire';
1
2
  import { AsyncLocalStorage } from 'node:async_hooks';
3
+ import { ZLinkFrameworkException } from '../../contracts';
4
+ import type { ZLinkAuthoritySnapshot } from '../locations/internal-location-contracts';
5
+ import { decodeServiceClosingSpotAuthority } from './service-authority-payload-codec';
6
+ import {
7
+ ZLinkRuntimeDispatchErrorAction as ZLinkDispatchErrorAction,
8
+ ZLinkRuntimeDispatchErrorReason as ZLinkDispatchErrorReason,
9
+ ZLinkDispatchErrorSurface,
10
+ ZLinkDispatchMessageKind,
11
+ ZLinkRuntimeMessageFlowOutcome as ZLinkMessageFlowOutcome
12
+ } from '../../contracts/Dispatch/ZLinkDispatchOptions';
2
13
  import { awaitWithAbort } from '../abort';
14
+ import { shouldCompactBackingArray } from '../admission';
15
+ import { RequestResult, SubmitResult, isZLinkBackendResultError } from '../backend/runtime-values';
16
+ import type { ZLinkDispatchErrorReporter } from '../channels/dispatch-error-reporter';
17
+ import { flowIfEnabled } from '../diagnostics/message-flow';
3
18
  import { captureZLinkExecutionTurn } from '../execution';
4
19
  import {
5
20
  ZLinkFrameworkInternalErrorKind,
@@ -8,18 +23,26 @@ import {
8
23
  internalFrameworkWireReply,
9
24
  translateWireReplyDecodeError
10
25
  } from '../framework-errors-internal';
11
- import { RequestResult, SubmitResult, isZLinkBackendResultError } from '../backend/runtime-values';
12
- import type { ZLinkDispatchErrorReporter } from '../channels/dispatch-error-reporter';
13
26
  import {
14
- ZLinkRuntimeDispatchErrorAction as ZLinkDispatchErrorAction,
15
- ZLinkDispatchErrorSurface,
16
- ZLinkDispatchMessageKind
17
- } from '../../contracts/Dispatch/ZLinkDispatchOptions';
27
+ decodeActorJoin28,
28
+ encodeActorJoin28,
29
+ type ActorJoin28
30
+ } from '../protocol/service_wire_pilot_codec.generated';
31
+ import { canonicalActorJoinHandoffId, routingIdBytes } from './actor-join-recovery-codec';
32
+ import { OperationRegistry } from './operation-registry';
33
+ import {
34
+ MessageFollowSuppressionRegistry,
35
+ type MessageFollowSuppressionFence
36
+ } from './message-follow-suppression-registry';
37
+ import { ZLINK_NATIVE_CORRELATION_OPERATION_NAMESPACE } from './operation-identity';
18
38
  import type {
19
39
  RawServiceIngressRecord,
20
40
  RawServiceMeshRuntime,
21
41
  RawServicePumpResult
22
42
  } from './raw-service-mesh-runtime';
43
+ import type { ServiceInstanceActivationRecoveryEnvelope } from './service-instance-activation-recovery-codec';
44
+ import type { ServiceMailboxRecord } from './service-mailbox';
45
+ import { validateServiceMetadataFrame } from './service-metadata-codec';
23
46
  import {
24
47
  ActorLifecycleKind,
25
48
  OperationKind,
@@ -28,13 +51,9 @@ import {
28
51
  type ActorJoinCompletionPayload,
29
52
  type ActorLocation,
30
53
  type ReceiveKindData,
54
+ type ServiceStreamSessionBinding,
31
55
  type StreamSessionActorAuthorityFence
32
56
  } from './service-runtime-contracts';
33
- import type { ServiceMailboxRecord } from './service-mailbox';
34
- import {
35
- MessageFollowSuppressionRegistry,
36
- type MessageFollowSuppressionFence
37
- } from './message-follow-suppression-registry';
38
57
  import {
39
58
  ServiceStaleGenerationError,
40
59
  ServiceStatefulRegistry,
@@ -46,6 +65,8 @@ import {
46
65
  type ServiceSpotState
47
66
  } from './service-stateful-registry';
48
67
  import {
68
+ M6bServiceWireCommand,
69
+ M6bServiceWireFlag,
49
70
  decodeStatefulHeader,
50
71
  decodeStatefulReply,
51
72
  encodeActorCreateHeader,
@@ -63,43 +84,37 @@ import {
63
84
  encodeStatefulReply,
64
85
  encodeUserSpotCloseHeader,
65
86
  encodeUserSpotCreateHeader,
66
- M6bServiceWireCommand,
67
- M6bServiceWireFlag,
68
87
  sessionBindingFromWire,
88
+ type ServiceActorCreateRecord,
69
89
  type ServiceActorRouteFence,
70
90
  type ServiceBoundSessionActorAuthority,
71
- type ServiceRetiredBoundSessionRouteFence,
72
- type ServiceActorCreateRecord,
91
+ type ServiceDirectSpotRouteFence,
73
92
  type ServiceInstanceActivationTarget,
74
93
  type ServiceInstanceRouteFence,
75
94
  type ServiceMessageFollowRoute,
76
- type ServiceDirectSpotRouteFence,
95
+ type ServiceRetiredBoundSessionRouteFence,
77
96
  type ServiceSpotRouteFence,
78
97
  type ServiceStatefulReplyTail,
79
98
  type ServiceStatefulWireRecord,
80
99
  type ServiceUserSpotCloseRecord,
81
100
  type ServiceUserSpotCreateRecord
82
101
  } from './service-stateful-wire-codec';
83
- import { routingIdsEqual } from '../routing-id';
84
102
  import {
85
- decodeActorJoin28,
86
- encodeActorJoin28,
87
- type ActorJoin28
88
- } from '../protocol/service_wire_pilot_codec.generated';
89
- import { canonicalActorJoinHandoffId, routingIdBytes } from './actor-join-recovery-codec';
90
-
103
+ SERVICE_WIRE_COMMAND_OFFSET,
104
+ SERVICE_WIRE_FLAGS_OFFSET
105
+ } from './service-wire-binary-primitives';
106
+ import { SERVICE_WIRE_MAGIC, SERVICE_WIRE_MAJOR } from './service-wire-constants.generated';
91
107
  import {
108
+ ServiceWireProtocolError,
92
109
  decodeApplicationPayload,
110
+ decodeApplicationPayloadView,
93
111
  encodeApplicationPayload,
94
- type ServiceApplicationPayload,
95
- ServiceWireProtocolError
112
+ type ServiceApplicationPayload
96
113
  } from './service-wire-m6a-codec';
97
- import type { ServiceInstanceActivationRecoveryEnvelope } from './service-instance-activation-recovery-codec';
98
- import { validateServiceMetadataFrame } from './service-metadata-codec';
99
- import type { ServiceSessionBindingIngressPort } from './service-session-binding-ingress-port';
100
- import { ZLinkFrameworkException } from '../../contracts';
114
+ const STATEFUL_OPERATION_RETRY_TICK_MS = 20;
115
+
116
+ const MAX_NODE_TIMER_DELAY_MS = 2_147_483_647;
101
117
 
102
- const ACTOR_ROUTE_STALE = 21;
103
118
  const SPOT_MOVING = 34;
104
119
  const USER_SPOT_OPERATION_CAPACITY = 65_536;
105
120
  const USER_SPOT_OPERATION_REPLAY_RETENTION_MS = 5 * 60_000;
@@ -110,12 +125,6 @@ export interface ServiceSpotMessageFollowSeal {
110
125
  readonly serial: bigint;
111
126
  }
112
127
 
113
- export interface ServiceBoundSessionSendFence {
114
- readonly targetNodeGeneration: bigint;
115
- readonly authorityOwnerGeneration: bigint;
116
- readonly ownerLeaseGeneration: bigint;
117
- }
118
-
119
128
  interface ServiceSpotMessageFollowRecord {
120
129
  readonly ingress: RawServiceIngressRecord;
121
130
  readonly wire: Extract<ServiceStatefulWireRecord, { readonly kind: 'spotSend' | 'spotRequest' }>;
@@ -172,7 +181,9 @@ export interface ServiceStatefulMailboxData {
172
181
  readonly isPending?: () => boolean;
173
182
  /** Carries the local operation deadline into the lifecycle dispatch lane. */
174
183
  readonly deadlineUnixMs?: bigint;
184
+ readonly activationRecord?: Extract<ServiceStatefulWireRecord, { readonly kind: 'instanceSpot' }>;
175
185
  readonly onTerminalCompletion?: () => void | Promise<void>;
186
+ readonly onHandlerTurnStarted?: () => void;
176
187
  /** Decoded only by the canonical command-28 generator path. */
177
188
  readonly canonicalApplicationPayload?: ServiceApplicationPayload;
178
189
  readonly reply?: (
@@ -196,9 +207,8 @@ export interface ServiceCanonicalActorJoinCandidate {
196
207
 
197
208
  export interface ServiceSessionDelivery {
198
209
  readonly binding: ServiceSessionBinding;
199
- readonly bindingIngress?: ServiceSessionBindingIngressPort;
200
210
  /**
201
- * Delivers the retained M6A application frame after the binding fence has
211
+ * Delivers the M6A application frame after the binding fence has
202
212
  * been validated. The stream adapter owns multipart decoding at that point.
203
213
  */
204
214
  readonly deliver: (sessionRid: string, payloadFrame: Uint8Array) => Promise<boolean>;
@@ -233,7 +243,6 @@ export type ServiceInstanceApplicationTarget = ServiceInstanceApplicationIdentit
233
243
  export interface ServiceInstanceApplicationLifecycle {
234
244
  isMaterialized(target: ServiceInstanceApplicationIdentity): boolean;
235
245
  isMaterializing?(target: ServiceInstanceApplicationIdentity): boolean;
236
- isClosing?(target: ServiceInstanceApplicationIdentity): boolean;
237
246
  isIdleEvicting?(target: ServiceInstanceApplicationIdentity): boolean;
238
247
  beginIdleEviction?(target: ServiceInstanceApplicationIdentity): boolean;
239
248
  materialize(target: ServiceInstanceApplicationIdentity, objectGeneration: bigint): Promise<void>;
@@ -263,8 +272,13 @@ export type ServiceInstanceAuthorityRead =
263
272
  readonly kind: 'creating';
264
273
  readonly objectGeneration: bigint;
265
274
  readonly authorityOwnerGeneration: bigint;
275
+ readonly authority?: ZLinkAuthoritySnapshot;
266
276
  }
267
- | { readonly kind: 'ready'; readonly route: ServiceInstanceRouteFence };
277
+ | {
278
+ readonly kind: 'ready';
279
+ readonly route: ServiceInstanceRouteFence;
280
+ readonly authority?: ZLinkAuthoritySnapshot;
281
+ };
268
282
 
269
283
  export type ServiceInstanceAuthorityReserve =
270
284
  | { readonly kind: 'reserved'; readonly reservation: ServiceInstanceActivationReservation }
@@ -300,7 +314,8 @@ export interface ServiceInstanceActivationAuthority {
300
314
  export interface ServiceAsyncInstanceActivationAuthority {
301
315
  read(target: ServiceInstanceActivationTarget): Promise<ServiceInstanceAuthorityRead>;
302
316
  reserve(
303
- activation: Omit<ServiceInstanceActivationRecoveryEnvelope, 'targetMeshName'>
317
+ activation: Omit<ServiceInstanceActivationRecoveryEnvelope, 'targetMeshName'>,
318
+ signal?: AbortSignal
304
319
  ): Promise<ServiceInstanceAuthorityReserve>;
305
320
  resume(
306
321
  target: ServiceInstanceActivationTarget,
@@ -309,7 +324,8 @@ export interface ServiceAsyncInstanceActivationAuthority {
309
324
  commit(
310
325
  target: ServiceInstanceActivationTarget,
311
326
  reservation: ServiceInstanceActivationReservation,
312
- spot: ServiceSpotState
327
+ spot: ServiceSpotState,
328
+ deadlineUnixMs?: bigint
313
329
  ): Promise<{ readonly kind: 'committed' | 'lost'; readonly route: ServiceInstanceRouteFence }>;
314
330
  complete(
315
331
  target: ServiceInstanceActivationTarget,
@@ -366,7 +382,7 @@ export class ServiceStatefulRuntime {
366
382
 
367
383
  readonly registry: ServiceStatefulRegistry;
368
384
 
369
- private readonly operations = new ServiceTerminalOperationRegistry<ServiceStatefulResult>();
385
+ private readonly operations: ServiceTerminalOperationRegistry<ServiceStatefulResult>;
370
386
  private readonly sessionDeliveries = new Map<string, ServiceSessionDelivery>();
371
387
  /**
372
388
  * A local Actor owner can replace its own session binding before the
@@ -378,7 +394,6 @@ export class ServiceStatefulRuntime {
378
394
  private readonly subscriptions = new Map<string, Set<string>>();
379
395
  private readonly instanceIntents = new Map<string, ServiceInstanceIntent>();
380
396
  private readonly admittedInstanceOperations = new Map<string, bigint>();
381
- private readonly pendingInstanceTerminals = new Map<string, number>();
382
397
  private readonly pendingInstanceAuthorityTerminals = new Map<string, number>();
383
398
  private readonly instanceApplicationWaiters = new Map<string, Set<() => void>>();
384
399
  private readonly canonicalActorJoinHandoffs = new Map<bigint, string>();
@@ -421,7 +436,7 @@ export class ServiceStatefulRuntime {
421
436
  private readonly pendingInstanceActivations = new Map<
422
437
  string,
423
438
  Promise<{
424
- readonly spot: ServiceSpotState;
439
+ readonly spot: Pick<ServiceSpotState, 'ref'>;
425
440
  readonly route: ServiceInstanceRouteFence;
426
441
  }>
427
442
  >();
@@ -430,8 +445,12 @@ export class ServiceStatefulRuntime {
430
445
  constructor(
431
446
  private readonly raw: RawServiceMeshRuntime,
432
447
  readonly nodeRid: string,
433
- readonly nodeGeneration: bigint
448
+ readonly nodeGeneration: bigint,
449
+ onPendingOperationsChanged?: () => void
434
450
  ) {
451
+ this.operations = new ServiceTerminalOperationRegistry(
452
+ new OperationRegistry(undefined, onPendingOperationsChanged)
453
+ );
435
454
  this.registry = new ServiceStatefulRegistry(nodeRid, nodeGeneration);
436
455
  this.registry.createEntrySpot(nodeRid);
437
456
  raw.setServiceIngress((record) => this.ingress(record));
@@ -879,6 +898,7 @@ export class ServiceStatefulRuntime {
879
898
  ...(envelope.replyRouteId === undefined ? {} : { replyRouteId: envelope.replyRouteId })
880
899
  };
881
900
  const applicationJobOwner = await this.raw.reserveLocalIngress();
901
+ const terminal = this.activationTerminalCompletion(target, route);
882
902
  try {
883
903
  const admitted = this.enqueueActivatedInstanceSpot(
884
904
  {
@@ -904,11 +924,11 @@ export class ServiceStatefulRuntime {
904
924
  Buffer.from(envelope.applicationPayloadFrame),
905
925
  spot,
906
926
  undefined,
907
- this.activationTerminalCompletion(target, route),
927
+ terminal.onTerminalCompletion,
908
928
  envelope.metadataFrame === undefined
909
929
  ? undefined
910
930
  : validateServiceMetadataFrame(envelope.metadataFrame),
911
- true,
931
+ terminal.onHandlerTurnStarted,
912
932
  this.instanceApplicationTarget(record, route.objectGeneration)
913
933
  );
914
934
  if (admitted !== 'application') {
@@ -1003,12 +1023,10 @@ export class ServiceStatefulRuntime {
1003
1023
  return released;
1004
1024
  }
1005
1025
 
1026
+ /** Resolves once every first terminal record of an activated Instance message is durable. */
1006
1027
  waitForInstanceApplicationQuiescence(spotId: string, signal?: AbortSignal): Promise<void> {
1007
1028
  const key = String(spotId);
1008
- if (
1009
- (this.pendingInstanceTerminals.get(key) ?? 0) === 0 &&
1010
- (this.pendingInstanceAuthorityTerminals.get(key) ?? 0) === 0
1011
- ) {
1029
+ if ((this.pendingInstanceAuthorityTerminals.get(key) ?? 0) === 0) {
1012
1030
  return Promise.resolve();
1013
1031
  }
1014
1032
  if (signal?.aborted === true) {
@@ -1271,11 +1289,11 @@ export class ServiceStatefulRuntime {
1271
1289
  reporter.report({
1272
1290
  surface: ZLinkDispatchErrorSurface.SpotRoute,
1273
1291
  messageKind: ZLinkDispatchMessageKind.Send,
1274
- reason: serviceSpotPublishFailureReason(
1275
- undefined,
1276
- this.raw.isPeerRouteReady(target.descriptor.nodeRoutingId),
1277
- this.closed
1278
- ),
1292
+ reason: this.closed
1293
+ ? ZLinkDispatchErrorReason.Shutdown
1294
+ : this.raw.isPeerRouteReady(target.descriptor.nodeRoutingId)
1295
+ ? ZLinkDispatchErrorReason.Backpressure
1296
+ : ZLinkDispatchErrorReason.StaleTarget,
1279
1297
  action: ZLinkDispatchErrorAction.Drop,
1280
1298
  meshName: this.dispatchErrorMeshName,
1281
1299
  channelName,
@@ -1296,7 +1314,10 @@ export class ServiceStatefulRuntime {
1296
1314
  if (target === undefined) {
1297
1315
  return SubmitResult.NotFound;
1298
1316
  }
1299
- const header = encodeSpotHeader('spotSend', sourceSpotId, target);
1317
+ const header = encodeSpotHeader('spotSend', sourceSpotId, target, undefined, {
1318
+ high: this.nodeGeneration,
1319
+ low: this.nextMessageFollowOperation++
1320
+ });
1300
1321
  return this.submitOneWay(target.targetNodeRid, [header, encodeApplicationPayload(payload)]);
1301
1322
  }
1302
1323
 
@@ -1309,13 +1330,16 @@ export class ServiceStatefulRuntime {
1309
1330
  const pending = this.operations.register(timeoutMs);
1310
1331
  const target = this.acceptSpotAuthority(requested);
1311
1332
  if (target === undefined) {
1312
- this.operations.reply(pending.id, {
1313
- terminalResult: RequestResult.NotFound,
1314
- failureCode: ACTOR_ROUTE_STALE
1315
- });
1333
+ this.operations.reply(
1334
+ pending.id,
1335
+ internalFrameworkWireReply(ZLinkFrameworkInternalErrorKind.ActorLocationStale)
1336
+ );
1316
1337
  return pending;
1317
1338
  }
1318
- const header = encodeSpotHeader('spotRequest', sourceSpotId, target, pending.id);
1339
+ const header = encodeSpotHeader('spotRequest', sourceSpotId, target, pending.id, {
1340
+ high: this.nodeGeneration,
1341
+ low: this.nextMessageFollowOperation++
1342
+ });
1319
1343
  this.submitRequest(
1320
1344
  pending,
1321
1345
  target.targetNodeRid,
@@ -1346,7 +1370,8 @@ export class ServiceStatefulRuntime {
1346
1370
  : {
1347
1371
  ...boundSession,
1348
1372
  sequence: this.nextSessionSequence++
1349
- }
1373
+ },
1374
+ { high: this.nodeGeneration, low: this.nextMessageFollowOperation++ }
1350
1375
  );
1351
1376
  return this.submitOneWay(target.nodeRid, [header, encodeApplicationPayload(payload)]);
1352
1377
  }
@@ -1363,10 +1388,10 @@ export class ServiceStatefulRuntime {
1363
1388
  const pending = this.operations.register(timeoutMs);
1364
1389
  const route = this.tryActorFence(target);
1365
1390
  if (route === undefined) {
1366
- this.operations.reply(pending.id, {
1367
- terminalResult: RequestResult.NotFound,
1368
- failureCode: ACTOR_ROUTE_STALE
1369
- });
1391
+ this.operations.reply(
1392
+ pending.id,
1393
+ internalFrameworkWireReply(ZLinkFrameworkInternalErrorKind.ActorLocationStale)
1394
+ );
1370
1395
  return pending;
1371
1396
  }
1372
1397
  const header = encodeActorHeader(
@@ -1379,7 +1404,8 @@ export class ServiceStatefulRuntime {
1379
1404
  : {
1380
1405
  ...boundSession,
1381
1406
  sequence: this.nextSessionSequence++
1382
- }
1407
+ },
1408
+ { high: this.nodeGeneration, low: this.nextMessageFollowOperation++ }
1383
1409
  );
1384
1410
  this.submitRequest(
1385
1411
  pending,
@@ -1395,7 +1421,8 @@ export class ServiceStatefulRuntime {
1395
1421
  route: ServiceInstanceRouteFence,
1396
1422
  payload: ServiceApplicationPayload,
1397
1423
  sourceSpotId?: string,
1398
- metadataFrame?: Uint8Array
1424
+ metadataFrame?: Uint8Array,
1425
+ instanceIntent = false
1399
1426
  ): Promise<number> {
1400
1427
  return this.submitOneWay(
1401
1428
  route.targetNodeRid,
@@ -1409,7 +1436,8 @@ export class ServiceStatefulRuntime {
1409
1436
  'send',
1410
1437
  { high: 0n, low: 0n },
1411
1438
  undefined,
1412
- metadataFrame !== undefined
1439
+ metadataFrame !== undefined,
1440
+ instanceIntent
1413
1441
  ),
1414
1442
  encodeApplicationPayload(payload)
1415
1443
  ],
@@ -1469,7 +1497,8 @@ export class ServiceStatefulRuntime {
1469
1497
  payload: ServiceApplicationPayload,
1470
1498
  timeoutMs: number,
1471
1499
  sourceSpotId?: string,
1472
- metadataFrame?: Uint8Array
1500
+ metadataFrame?: Uint8Array,
1501
+ instanceIntent = false
1473
1502
  ): ServiceStatefulPendingOperation {
1474
1503
  const pending = this.operations.register(timeoutMs);
1475
1504
  this.submitRequest(
@@ -1483,9 +1512,10 @@ export class ServiceStatefulRuntime {
1483
1512
  this.nodeRid,
1484
1513
  sourceSpotId,
1485
1514
  'request',
1486
- { high: 2n, low: pending.id },
1515
+ { high: ZLINK_NATIVE_CORRELATION_OPERATION_NAMESPACE, low: pending.id },
1487
1516
  pending.id,
1488
- metadataFrame !== undefined
1517
+ metadataFrame !== undefined,
1518
+ instanceIntent
1489
1519
  ),
1490
1520
  encodeApplicationPayload(payload)
1491
1521
  ],
@@ -1716,7 +1746,6 @@ export class ServiceStatefulRuntime {
1716
1746
  timeoutMs: number,
1717
1747
  deliver: ServiceSessionDelivery['deliver'],
1718
1748
  onBindingReplaced?: ServiceSessionDelivery['onBindingReplaced'],
1719
- bindingIngress?: ServiceSessionBindingIngressPort,
1720
1749
  actorAuthority?: StreamSessionActorAuthorityFence
1721
1750
  ): ServiceStatefulPendingOperation {
1722
1751
  const deadlineMs = performance.now() + timeoutMs;
@@ -1735,7 +1764,6 @@ export class ServiceStatefulRuntime {
1735
1764
  const delivery: ServiceSessionDelivery = {
1736
1765
  binding: localBinding,
1737
1766
  deliver,
1738
- ...(bindingIngress === undefined ? {} : { bindingIngress }),
1739
1767
  ...(onBindingReplaced === undefined ? {} : { onBindingReplaced })
1740
1768
  };
1741
1769
  const deliveryKey = actorKey(actor);
@@ -1876,10 +1904,10 @@ export class ServiceStatefulRuntime {
1876
1904
  delivery.binding.sessionRid !== sessionRid ||
1877
1905
  delivery.binding.bindingGeneration !== expectedBindingGeneration
1878
1906
  ) {
1879
- this.operations.reply(pending.id, {
1880
- terminalResult: RequestResult.NotFound,
1881
- failureCode: ACTOR_ROUTE_STALE
1882
- });
1907
+ this.operations.reply(
1908
+ pending.id,
1909
+ internalFrameworkWireReply(ZLinkFrameworkInternalErrorKind.ActorLocationStale)
1910
+ );
1883
1911
  return pending;
1884
1912
  }
1885
1913
  this.sessionDeliveries.delete(actorKey(actor));
@@ -1900,10 +1928,19 @@ export class ServiceStatefulRuntime {
1900
1928
  return pending;
1901
1929
  }
1902
1930
 
1903
- sessionBindings(sessionRid: string): readonly ServiceSessionBinding[] {
1931
+ sessionBindings(sessionRid: string): readonly ServiceStreamSessionBinding[] {
1904
1932
  return [...this.sessionDeliveries.values()]
1905
1933
  .map((value) => value.binding)
1906
- .filter((binding) => binding.sessionRid === sessionRid);
1934
+ .filter((binding) => binding.sessionRid === sessionRid)
1935
+ .map((binding) => {
1936
+ const owner = requireSessionOwnerIdentity(binding);
1937
+ return {
1938
+ ...binding,
1939
+ sessionOwnerNodeGeneration: owner.nodeGeneration,
1940
+ sessionOwnerId: owner.ownerId,
1941
+ sessionOwnerLeaseGeneration: owner.leaseGeneration
1942
+ };
1943
+ });
1907
1944
  }
1908
1945
 
1909
1946
  allSessionBindings(): readonly ServiceSessionBinding[] {
@@ -1935,16 +1972,20 @@ export class ServiceStatefulRuntime {
1935
1972
  async sendBoundSession(
1936
1973
  actor: ServiceActorRef,
1937
1974
  expectedBindingGeneration: bigint,
1938
- payload: ServiceApplicationPayload,
1939
- senderFence?: ServiceBoundSessionSendFence
1975
+ payload: ServiceApplicationPayload
1940
1976
  ): Promise<number> {
1977
+ // Session–Actor binding §3 item 3: the source sends by binding identity to
1978
+ // the registered route. The header's owner lifecycle fields are this node's
1979
+ // current route values, not send conditions; the Session owner alone
1980
+ // decides whether the binding is current.
1941
1981
  let binding: ServiceSessionBinding;
1942
1982
  try {
1943
1983
  binding = this.registry.validateBoundSession(actor, expectedBindingGeneration);
1944
- } catch {
1945
- return SubmitResult.InvalidState;
1984
+ } catch (error) {
1985
+ if (error instanceof ServiceStaleGenerationError) return SubmitResult.NotFound;
1986
+ throw error;
1946
1987
  }
1947
- const actorFence = this.tryBoundSessionSendFence(actor, senderFence);
1988
+ const actorFence = this.tryActorFence(actor);
1948
1989
  if (actorFence === undefined) return SubmitResult.InvalidState;
1949
1990
  const header = encodeBoundSessionSendHeader(actorFence, expectedBindingGeneration);
1950
1991
  return this.submitOneWay(binding.sessionOwnerNodeRid, [
@@ -1953,27 +1994,22 @@ export class ServiceStatefulRuntime {
1953
1994
  ]);
1954
1995
  }
1955
1996
 
1997
+ expireOperations(nowMs: number, turnDeadlineMs: number): number {
1998
+ return this.operations.expire(nowMs, turnDeadlineMs);
1999
+ }
2000
+
2001
+ get pendingOperationCount(): number {
2002
+ return this.operations.size;
2003
+ }
2004
+
1956
2005
  close(): void {
1957
2006
  if (this.closed) return;
1958
2007
  this.closed = true;
1959
2008
  this.operations.close();
1960
- const clearedActors = new Set<string>();
1961
- for (const deliveries of [this.sessionDeliveries, this.retiredSessionDeliveries]) {
1962
- for (const delivery of deliveries.values()) {
1963
- const actorId = delivery.binding.actor.actorId;
1964
- if (clearedActors.has(actorId)) continue;
1965
- clearedActors.add(actorId);
1966
- delivery.bindingIngress?.clearOutbound(
1967
- actorId,
1968
- new Error(`Actor '${actorId}' Session service closed with retained outbound delivery.`)
1969
- );
1970
- }
1971
- }
1972
2009
  this.sessionDeliveries.clear();
1973
2010
  this.retiredSessionDeliveries.clear();
1974
2011
  this.appliedReplacementNotices.clear();
1975
2012
  this.instanceIntents.clear();
1976
- this.pendingInstanceTerminals.clear();
1977
2013
  this.pendingInstanceAuthorityTerminals.clear();
1978
2014
  for (const waiters of this.instanceApplicationWaiters.values()) {
1979
2015
  for (const waiter of waiters) waiter();
@@ -2026,7 +2062,12 @@ export class ServiceStatefulRuntime {
2026
2062
  }
2027
2063
  decoded = statefulActorJoinFromCanonical(canonicalActorJoin);
2028
2064
  } else {
2029
- decoded = decodeStatefulHeader(record.parts[0]!);
2065
+ const metadata = (record.flags & M6bServiceWireFlag.metadata) !== 0;
2066
+ decoded = decodeStatefulHeader(
2067
+ record.parts[0]!,
2068
+ record.parts[metadata ? 2 : 1],
2069
+ metadata ? record.parts[1] : undefined
2070
+ );
2030
2071
  }
2031
2072
  const hasPayload = [
2032
2073
  'spotSend',
@@ -2039,6 +2080,12 @@ export class ServiceStatefulRuntime {
2039
2080
  ].includes(decoded.kind);
2040
2081
  const instanceMetadata =
2041
2082
  decoded.kind === 'instanceSpot' && (record.flags & M6bServiceWireFlag.metadata) !== 0;
2083
+ const statefulMetadata =
2084
+ (decoded.kind === 'spotSend' ||
2085
+ decoded.kind === 'spotRequest' ||
2086
+ decoded.kind === 'actorSend' ||
2087
+ decoded.kind === 'actorRequest') &&
2088
+ (record.flags & M6bServiceWireFlag.metadata) !== 0;
2042
2089
  const userSpotInfrastructure =
2043
2090
  decoded.kind === 'userSpotCreate' ||
2044
2091
  decoded.kind === 'userSpotClose' ||
@@ -2047,16 +2094,19 @@ export class ServiceStatefulRuntime {
2047
2094
  decoded.kind === 'boundSessionReplaced';
2048
2095
  if (
2049
2096
  record.parts.length < 1 ||
2050
- record.parts.length > (instanceMetadata ? 3 : 2) ||
2051
- (hasPayload && decoded.kind !== 'actorJoin' && record.parts.length !== 2) ||
2097
+ record.parts.length > (instanceMetadata || statefulMetadata ? 3 : 2) ||
2098
+ (hasPayload &&
2099
+ decoded.kind !== 'actorJoin' &&
2100
+ record.parts.length !== ((record.flags & M6bServiceWireFlag.metadata) !== 0 ? 3 : 2)) ||
2052
2101
  (decoded.kind === 'instanceSpot' && record.parts.length !== (instanceMetadata ? 3 : 2)) ||
2053
2102
  (userSpotInfrastructure && record.parts.length !== 1)
2054
2103
  ) {
2055
2104
  return 'protocolError';
2056
2105
  }
2057
- const metadataFrame = instanceMetadata
2058
- ? validateServiceMetadataFrame(record.parts[1]!)
2059
- : undefined;
2106
+ const metadataFrame =
2107
+ instanceMetadata || statefulMetadata
2108
+ ? validateServiceMetadataFrame(record.parts[1]!)
2109
+ : undefined;
2060
2110
  const canonicalPayload =
2061
2111
  canonicalActorJoin?.payload === undefined
2062
2112
  ? undefined
@@ -2095,6 +2145,22 @@ export class ServiceStatefulRuntime {
2095
2145
  kind === ZLinkFrameworkInternalErrorKind.SpotMoving ||
2096
2146
  kind === ZLinkFrameworkInternalErrorKind.SpotGenerationStale
2097
2147
  ) {
2148
+ const reporter = this.dispatchErrors;
2149
+ if (decoded.kind === 'instanceSpot' && reporter?.captureEnabled() === true) {
2150
+ reporter.report({
2151
+ surface: ZLinkDispatchErrorSurface.InstanceSpot,
2152
+ messageKind: ZLinkDispatchMessageKind.Send,
2153
+ reason: ZLinkDispatchErrorReason.StaleTarget,
2154
+ action: ZLinkDispatchErrorAction.Drop,
2155
+ meshName: this.dispatchErrorMeshName,
2156
+ sourceRid: decoded.sourceNodeRid,
2157
+ spotId:
2158
+ decoded.activation === 'ready'
2159
+ ? decoded.route.targetSpotId
2160
+ : decoded.target.targetSpotId,
2161
+ error
2162
+ });
2163
+ }
2098
2164
  return 'protocolError';
2099
2165
  }
2100
2166
  }
@@ -2349,11 +2415,6 @@ export class ServiceStatefulRuntime {
2349
2415
  targetSpotId: record.route.targetSpotId,
2350
2416
  stableType: intent.instanceType
2351
2417
  };
2352
- // A close seals execution only after the current application count reaches
2353
- // zero. A new Instance message must wait for that close even while the old
2354
- // activation is still materialized; otherwise it can be admitted after
2355
- // the close quiescence check and be removed with the old activation.
2356
- if (lifecycle.isClosing?.(applicationTarget) === true) return true;
2357
2418
  return !lifecycle.isMaterialized(applicationTarget);
2358
2419
  }
2359
2420
 
@@ -2361,11 +2422,11 @@ export class ServiceStatefulRuntime {
2361
2422
  ingress: RawServiceIngressRecord,
2362
2423
  record: Extract<ServiceStatefulWireRecord, { readonly kind: 'instanceSpot' }>,
2363
2424
  payloadFrame: Buffer,
2364
- spot: ServiceSpotState,
2425
+ spot: Pick<ServiceSpotState, 'ref'>,
2365
2426
  localReply?: NonNullable<ServiceStatefulMailboxData['reply']>,
2366
2427
  onTerminalCompletion?: NonNullable<ServiceStatefulMailboxData['onTerminalCompletion']>,
2367
2428
  metadataFrame?: Buffer,
2368
- activationTerminal = false,
2429
+ onHandlerTurnStarted?: () => void,
2369
2430
  applicationTargetOverride?: ServiceInstanceApplicationTarget
2370
2431
  ): RawServicePumpResult {
2371
2432
  let operationKey: string | undefined;
@@ -2395,10 +2456,6 @@ export class ServiceStatefulRuntime {
2395
2456
  onTerminalCompletion === undefined
2396
2457
  ? undefined
2397
2458
  : async () => {
2398
- // The application turn has returned before authority cleanup starts.
2399
- // Mark it quiescent first so a close requested by that turn can finish
2400
- // its local cleanup and release the exact authority fence below.
2401
- this.completeInstanceApplicationOperation(applicationTarget.targetSpotId);
2402
2459
  try {
2403
2460
  await onTerminalCompletion();
2404
2461
  } finally {
@@ -2413,8 +2470,11 @@ export class ServiceStatefulRuntime {
2413
2470
  ...(record.operationKind === 'request' ? { correlation: record.replyRouteId } : {}),
2414
2471
  ...(record.sourceSpotId === undefined ? {} : { sourceSpotId: record.sourceSpotId }),
2415
2472
  targetSpot: spot.ref,
2473
+ activationRecord: record,
2474
+ ...(record.activation === 'missing' ? { deadlineUnixMs: record.deadlineUnixMs } : {}),
2416
2475
  ...(metadataFrame === undefined ? {} : { applicationMetadata: metadataFrame }),
2417
2476
  ...(terminalCompletion === undefined ? {} : { onTerminalCompletion: terminalCompletion }),
2477
+ ...(onHandlerTurnStarted === undefined ? {} : { onHandlerTurnStarted }),
2418
2478
  ...(record.operationKind === 'request'
2419
2479
  ? {
2420
2480
  reply:
@@ -2431,10 +2491,6 @@ export class ServiceStatefulRuntime {
2431
2491
  this.admittedInstanceOperations.set(operationKey, record.deadlineUnixMs);
2432
2492
  }
2433
2493
  if (onTerminalCompletion !== undefined && result === 'application') {
2434
- this.beginInstanceApplicationOperation(applicationTarget.targetSpotId);
2435
- if (activationTerminal) {
2436
- this.beginInstanceAuthorityOperation(applicationTarget.targetSpotId);
2437
- }
2438
2494
  this.instanceApplicationLifecycle?.beginTerminal(applicationTarget);
2439
2495
  }
2440
2496
  return result;
@@ -2458,15 +2514,16 @@ export class ServiceStatefulRuntime {
2458
2514
  metadataFrame
2459
2515
  );
2460
2516
  if (this.closed) return;
2517
+ const terminal = this.activationTerminalCompletion(record.target, activation.route);
2461
2518
  const admitted = this.enqueueActivatedInstanceSpot(
2462
2519
  ingress,
2463
2520
  record,
2464
2521
  payloadFrame,
2465
2522
  activation.spot,
2466
2523
  localReply,
2467
- this.activationTerminalCompletion(record.target, activation.route),
2524
+ terminal.onTerminalCompletion,
2468
2525
  metadataFrame,
2469
- true,
2526
+ terminal.onHandlerTurnStarted,
2470
2527
  this.instanceApplicationTarget(record, activation.route.objectGeneration)
2471
2528
  );
2472
2529
  if (admitted !== 'application') {
@@ -2534,12 +2591,14 @@ export class ServiceStatefulRuntime {
2534
2591
  const spot = this.requireInstanceActivation(ingress, refreshedRecord);
2535
2592
  const admitted = this.enqueueActivatedInstanceSpot(
2536
2593
  ingress,
2537
- refreshedRecord,
2594
+ record,
2538
2595
  payloadFrame,
2539
2596
  spot,
2540
2597
  undefined,
2541
2598
  this.instanceApplicationTerminalCompletion(this.instanceApplicationTarget(refreshedRecord)),
2542
- metadataFrame
2599
+ metadataFrame,
2600
+ undefined,
2601
+ this.instanceApplicationTarget(refreshedRecord)
2543
2602
  );
2544
2603
  if (admitted !== 'application') {
2545
2604
  throw new Error('Rematerialized Instance message was not admitted to the local queue.');
@@ -2551,23 +2610,39 @@ export class ServiceStatefulRuntime {
2551
2610
  }
2552
2611
  }
2553
2612
 
2613
+ /**
2614
+ * Spot messaging §4 step 12 with §7 step 1: a Close waits for the first terminal
2615
+ * record only of a message whose handler turn started before it; a message queued
2616
+ * behind that Close is not counted, so it cannot hold the Close it follows.
2617
+ */
2554
2618
  private activationTerminalCompletion(
2555
2619
  target: ServiceInstanceActivationTarget,
2556
2620
  route: ServiceInstanceRouteFence
2557
- ): () => Promise<void> {
2621
+ ): {
2622
+ readonly onTerminalCompletion: () => Promise<void>;
2623
+ readonly onHandlerTurnStarted: () => void;
2624
+ } {
2558
2625
  let completion: Promise<void> | undefined;
2626
+ let started = false;
2559
2627
  const applicationTarget: ServiceInstanceApplicationTarget = {
2560
2628
  targetSpotId: target.targetSpotId,
2561
2629
  stableType: target.stableType,
2562
2630
  objectGeneration: route.objectGeneration
2563
2631
  };
2564
- return () =>
2632
+ const onHandlerTurnStarted = (): void => {
2633
+ if (started || completion !== undefined) return;
2634
+ started = true;
2635
+ this.beginInstanceAuthorityOperation(target.targetSpotId);
2636
+ };
2637
+ const onTerminalCompletion = (): Promise<void> =>
2565
2638
  (completion ??= (async () => {
2566
- let authorityCompletionSignaled = false;
2639
+ let authorityCompletionSignaled = !started;
2567
2640
  try {
2568
2641
  const released = await this.asyncInstanceAuthority?.complete(target, route);
2569
- this.completeInstanceAuthorityOperation(target.targetSpotId);
2570
- authorityCompletionSignaled = true;
2642
+ if (!authorityCompletionSignaled) {
2643
+ this.completeInstanceAuthorityOperation(target.targetSpotId);
2644
+ authorityCompletionSignaled = true;
2645
+ }
2571
2646
  if (released !== undefined) {
2572
2647
  const authorityReleased =
2573
2648
  (await this.instanceApplicationLifecycle?.completeTerminal(applicationTarget)) ??
@@ -2584,6 +2659,7 @@ export class ServiceStatefulRuntime {
2584
2659
  }
2585
2660
  }
2586
2661
  })());
2662
+ return { onTerminalCompletion, onHandlerTurnStarted };
2587
2663
  }
2588
2664
 
2589
2665
  private instanceApplicationTerminalCompletion(
@@ -2628,11 +2704,6 @@ export class ServiceStatefulRuntime {
2628
2704
  };
2629
2705
  }
2630
2706
 
2631
- private beginInstanceApplicationOperation(spotId: string): void {
2632
- const key = String(spotId);
2633
- this.pendingInstanceTerminals.set(key, (this.pendingInstanceTerminals.get(key) ?? 0) + 1);
2634
- }
2635
-
2636
2707
  private beginInstanceAuthorityOperation(spotId: string): void {
2637
2708
  const key = String(spotId);
2638
2709
  this.pendingInstanceAuthorityTerminals.set(
@@ -2641,17 +2712,6 @@ export class ServiceStatefulRuntime {
2641
2712
  );
2642
2713
  }
2643
2714
 
2644
- private completeInstanceApplicationOperation(spotId: string): void {
2645
- const key = String(spotId);
2646
- const pending = this.pendingInstanceTerminals.get(key);
2647
- if (pending === undefined || pending <= 1) {
2648
- this.pendingInstanceTerminals.delete(key);
2649
- this.completeInstanceApplicationWaitersIfQuiescent(key);
2650
- return;
2651
- }
2652
- this.pendingInstanceTerminals.set(key, pending - 1);
2653
- }
2654
-
2655
2715
  private completeInstanceAuthorityOperation(spotId: string): void {
2656
2716
  const key = String(spotId);
2657
2717
  const pending = this.pendingInstanceAuthorityTerminals.get(key);
@@ -2664,11 +2724,7 @@ export class ServiceStatefulRuntime {
2664
2724
  }
2665
2725
 
2666
2726
  private completeInstanceApplicationWaitersIfQuiescent(key: string): void {
2667
- if (
2668
- (this.pendingInstanceTerminals.get(key) ?? 0) !== 0 ||
2669
- (this.pendingInstanceAuthorityTerminals.get(key) ?? 0) !== 0
2670
- )
2671
- return;
2727
+ if ((this.pendingInstanceAuthorityTerminals.get(key) ?? 0) !== 0) return;
2672
2728
  const waiters = this.instanceApplicationWaiters.get(key);
2673
2729
  if (waiters === undefined) return;
2674
2730
  this.instanceApplicationWaiters.delete(key);
@@ -2817,8 +2873,8 @@ export class ServiceStatefulRuntime {
2817
2873
  // activation continuation can publish its in-memory intent. If the
2818
2874
  // local ready projection already carries the exact object and owner
2819
2875
  // fence from the received route, publish that validated projection
2820
- // instead of exposing a transient NotFound result to a following
2821
- // request. A mismatched or absent local projection remains NotFound.
2876
+ // instead of rejecting a following request while publication finishes.
2877
+ // An absent Ready projection cannot validate the received owner fence.
2822
2878
  const local = this.registry.spot(record.route.targetSpotId);
2823
2879
  if (
2824
2880
  local?.kind === 'instance' &&
@@ -2831,7 +2887,7 @@ export class ServiceStatefulRuntime {
2831
2887
  }
2832
2888
  if (intent === undefined) {
2833
2889
  throw createInternalFrameworkException(
2834
- ZLinkFrameworkInternalErrorKind.RequestTargetNotFound,
2890
+ ZLinkFrameworkInternalErrorKind.SpotMoving,
2835
2891
  `Instance Spot '${record.route.targetSpotId}' has no current Ready authority.`
2836
2892
  );
2837
2893
  }
@@ -2954,7 +3010,10 @@ export class ServiceStatefulRuntime {
2954
3010
  >,
2955
3011
  payloadFrame: Buffer,
2956
3012
  metadataFrame?: Buffer
2957
- ): Promise<{ readonly spot: ServiceSpotState; readonly route: ServiceInstanceRouteFence }> {
3013
+ ): Promise<{
3014
+ readonly spot: Pick<ServiceSpotState, 'ref'>;
3015
+ readonly route: ServiceInstanceRouteFence;
3016
+ }> {
2958
3017
  const key = instanceActivationKey(record);
2959
3018
  const pending = this.pendingInstanceActivations.get(key);
2960
3019
  if (pending !== undefined) return pending;
@@ -2976,7 +3035,10 @@ export class ServiceStatefulRuntime {
2976
3035
  >,
2977
3036
  payloadFrame: Buffer,
2978
3037
  metadataFrame?: Buffer
2979
- ): Promise<{ readonly spot: ServiceSpotState; readonly route: ServiceInstanceRouteFence }> {
3038
+ ): Promise<{
3039
+ readonly spot: Pick<ServiceSpotState, 'ref'>;
3040
+ readonly route: ServiceInstanceRouteFence;
3041
+ }> {
2980
3042
  const target = record.target;
2981
3043
  if (
2982
3044
  target.targetNodeRid !== this.nodeRid ||
@@ -2992,6 +3054,46 @@ export class ServiceStatefulRuntime {
2992
3054
 
2993
3055
  const local = this.registry.spot(target.targetSpotId);
2994
3056
  const current = await authority.read(target);
3057
+ if (
3058
+ current.kind === 'creating' &&
3059
+ current.authority?.allocation.state === 'active' &&
3060
+ this.instanceApplicationLifecycle?.isMaterializing?.(target) === true
3061
+ ) {
3062
+ return {
3063
+ spot: { ref: { spotId: target.targetSpotId, generation: current.objectGeneration } },
3064
+ route: {
3065
+ targetSpotId: target.targetSpotId,
3066
+ targetNodeRid: this.nodeRid,
3067
+ targetNodeGeneration: this.nodeGeneration,
3068
+ objectGeneration: current.objectGeneration,
3069
+ authorityOwnerGeneration: current.authorityOwnerGeneration,
3070
+ ownerId: current.authority.ownerId,
3071
+ leaseGeneration: current.authority.ownerLeaseGeneration,
3072
+ storeVersion: current.authority.storeVersion.value
3073
+ }
3074
+ };
3075
+ }
3076
+ if (
3077
+ current.kind === 'ready' &&
3078
+ current.authority !== undefined &&
3079
+ decodeServiceClosingSpotAuthority(current.authority.payload) !== undefined
3080
+ ) {
3081
+ if (current.route.targetNodeRid !== this.nodeRid) {
3082
+ throw new ServiceInstanceActivationRedirectError(current.route);
3083
+ }
3084
+ if (
3085
+ current.route.targetNodeGeneration !== this.nodeGeneration ||
3086
+ (local !== undefined &&
3087
+ !routeMatchesLocal(current.route, local, this.nodeRid, this.nodeGeneration)) ||
3088
+ (local === undefined && this.instanceApplicationLifecycle?.isMaterialized(target) !== true)
3089
+ ) {
3090
+ throw new ServiceStaleGenerationError('spot', target.targetSpotId);
3091
+ }
3092
+ return {
3093
+ spot: { ref: { spotId: target.targetSpotId, generation: current.route.objectGeneration } },
3094
+ route: current.route
3095
+ };
3096
+ }
2995
3097
  if (!this.acceptsLocalMissingInstancePlacement()) {
2996
3098
  if (current.kind === 'ready' && current.route.targetNodeRid !== this.nodeRid) {
2997
3099
  throw new ServiceInstanceActivationRedirectError(current.route);
@@ -3023,7 +3125,6 @@ export class ServiceStatefulRuntime {
3023
3125
  }
3024
3126
  if (local !== undefined) {
3025
3127
  const lifecycle = this.instanceApplicationLifecycle;
3026
- const closing = lifecycle?.isClosing?.(target) === true;
3027
3128
  let materialized = lifecycle === undefined ? undefined : lifecycle.isMaterialized(target);
3028
3129
  const materializing = lifecycle?.isMaterializing?.(target) === true;
3029
3130
  if (local.kind !== 'instance' || local.stableType !== target.stableType) {
@@ -3033,10 +3134,8 @@ export class ServiceStatefulRuntime {
3033
3134
  current.kind === 'creating' &&
3034
3135
  local.ref.generation === current.objectGeneration &&
3035
3136
  local.authorityOwnerGeneration === current.authorityOwnerGeneration;
3036
- const replacesClosingProjection = current.kind === 'creating' && closing;
3037
3137
  if (
3038
3138
  current.kind === 'missing' &&
3039
- !closing &&
3040
3139
  !materializing &&
3041
3140
  materialized === true &&
3042
3141
  lifecycle !== undefined
@@ -3060,24 +3159,33 @@ export class ServiceStatefulRuntime {
3060
3159
  // If disposal did not remove an orphaned materialization, keep fencing
3061
3160
  // it instead of admitting work into two application generations.
3062
3161
  if (
3063
- (!joinsCreating && !replacesClosingProjection && current.kind !== 'missing') ||
3064
- (!joinsCreating && !closing && materialized !== false && !materializing)
3162
+ (!joinsCreating && current.kind !== 'missing') ||
3163
+ (!joinsCreating && materialized !== false && !materializing)
3065
3164
  ) {
3066
3165
  throw new ServiceStaleGenerationError('spot', target.targetSpotId);
3067
3166
  }
3068
3167
  }
3069
- const reserved = await authority.reserve({
3070
- target,
3071
- sourceNodeRid: record.sourceNodeRid,
3072
- sourceNodeGeneration: record.sourceNodeGeneration,
3073
- ...(record.sourceSpotId === undefined ? {} : { sourceSpotId: record.sourceSpotId }),
3074
- operationKind: record.operationKind,
3075
- operation: record.operation,
3076
- ...(record.replyRouteId === undefined ? {} : { replyRouteId: record.replyRouteId }),
3077
- deadlineUnixMs: record.deadlineUnixMs,
3078
- ...(metadataFrame === undefined ? {} : { metadataFrame }),
3079
- applicationPayloadFrame: payloadFrame
3080
- });
3168
+ const deadline = operationDeadline(record.deadlineUnixMs);
3169
+ let reserved: ServiceInstanceAuthorityReserve;
3170
+ try {
3171
+ reserved = await authority.reserve(
3172
+ {
3173
+ target,
3174
+ sourceNodeRid: record.sourceNodeRid,
3175
+ sourceNodeGeneration: record.sourceNodeGeneration,
3176
+ ...(record.sourceSpotId === undefined ? {} : { sourceSpotId: record.sourceSpotId }),
3177
+ operationKind: record.operationKind,
3178
+ operation: record.operation,
3179
+ ...(record.replyRouteId === undefined ? {} : { replyRouteId: record.replyRouteId }),
3180
+ deadlineUnixMs: record.deadlineUnixMs,
3181
+ ...(metadataFrame === undefined ? {} : { metadataFrame }),
3182
+ applicationPayloadFrame: payloadFrame
3183
+ },
3184
+ deadline.signal
3185
+ );
3186
+ } finally {
3187
+ deadline.close();
3188
+ }
3081
3189
  if (reserved.kind === 'ready') {
3082
3190
  throw new ServiceInstanceActivationRedirectError(reserved.route);
3083
3191
  }
@@ -3102,7 +3210,12 @@ export class ServiceStatefulRuntime {
3102
3210
  }
3103
3211
  let committed: Awaited<ReturnType<ServiceAsyncInstanceActivationAuthority['commit']>>;
3104
3212
  try {
3105
- committed = await authority.commit(target, reserved.reservation, activation.spot);
3213
+ committed = await authority.commit(
3214
+ target,
3215
+ reserved.reservation,
3216
+ activation.spot,
3217
+ record.deadlineUnixMs
3218
+ );
3106
3219
  } catch (error) {
3107
3220
  if (activation.created) this.registry.closeSpot(activation.spot.ref);
3108
3221
  await this.instanceApplicationLifecycle?.discard(target);
@@ -3594,7 +3707,15 @@ export class ServiceStatefulRuntime {
3594
3707
  const accepted = this.raw.mailbox.tryEnqueue({
3595
3708
  owner: `actor:${actor.actorId}\0${actor.generation}`,
3596
3709
  domain: 'infrastructure',
3597
- parts: [Buffer.from([0x5a, 0x4d, 1, M6bServiceWireCommand.boundSessionBind, 0])],
3710
+ parts: [
3711
+ Buffer.from([
3712
+ SERVICE_WIRE_MAGIC[0],
3713
+ SERVICE_WIRE_MAGIC[1],
3714
+ SERVICE_WIRE_MAJOR,
3715
+ M6bServiceWireCommand.boundSessionBind,
3716
+ 0
3717
+ ])
3718
+ ],
3598
3719
  sourceRoutingId: binding.sessionOwnerNodeRid,
3599
3720
  stateful: {
3600
3721
  receiveKind: ReceiveKind.ActorBinding,
@@ -3627,62 +3748,25 @@ export class ServiceStatefulRuntime {
3627
3748
  record: Extract<ServiceStatefulWireRecord, { readonly kind: 'boundSessionSend' }>,
3628
3749
  payloadFrame: Uint8Array | undefined
3629
3750
  ): Promise<RawServicePumpResult> {
3751
+ // Session–Actor binding §3 item 3, §8.1: this Session owner's binding
3752
+ // record alone decides whether command 36 names the current binding
3753
+ // (ActorId, ObjectGeneration, binding generation; SessionRid is the
3754
+ // record's own). The transport boundary has already authenticated the
3755
+ // source peer, and the header's route fields are not compared here.
3756
+ if (payloadFrame === undefined) return 'protocolError';
3630
3757
  const delivery = this.sessionDeliveries.get(actorKey(record.actor.actor));
3631
3758
  if (
3632
3759
  delivery === undefined ||
3633
- delivery.binding.bindingGeneration !== record.expectedBindingGeneration ||
3634
- payloadFrame === undefined ||
3635
- ingress.sourceNodeGeneration === undefined ||
3636
- !routingIdsEqual(ingress.sourceRoutingId, record.actor.actor.nodeRid) ||
3637
- ingress.sourceNodeGeneration !== record.actor.targetNodeGeneration
3760
+ delivery.binding.bindingGeneration !== record.expectedBindingGeneration
3638
3761
  ) {
3762
+ this.traceRejectedBoundSessionSend(ingress, record, payloadFrame);
3639
3763
  return 'protocolError';
3640
3764
  }
3641
3765
  const sessionRid = delivery.binding.sessionRid;
3642
- let retainedPayload: Uint8Array | undefined = payloadFrame;
3643
- let settled = false;
3644
- const settle = () => {
3645
- if (settled) return false;
3646
- settled = true;
3647
- retainedPayload = undefined;
3648
- return true;
3649
- };
3650
- const operation = {
3651
- deliver: async () => {
3652
- if (settled || retainedPayload === undefined) return false;
3653
- const delivered = await delivery.deliver(sessionRid, retainedPayload);
3654
- if (delivered) settle();
3655
- return delivered;
3656
- },
3657
- fail: (_error: unknown) => {
3658
- settle();
3659
- }
3660
- };
3661
- const decision = await delivery.bindingIngress?.retainOutbound(
3662
- {
3663
- actorId: record.actor.actor.actorId,
3664
- objectGeneration: record.actor.actor.generation,
3665
- actorNodeRid: record.actor.actor.nodeRid,
3666
- actorNodeGeneration: record.actor.targetNodeGeneration,
3667
- authorityOwnerGeneration: record.actor.authorityOwnerGeneration,
3668
- ownerLeaseGeneration: record.actor.ownerLeaseGeneration,
3669
- producerNodeRid: ingress.sourceRoutingId,
3670
- producerNodeGeneration: ingress.sourceNodeGeneration,
3671
- sessionIdentity: sessionRid,
3672
- bindingGeneration: record.expectedBindingGeneration
3673
- },
3674
- operation
3675
- );
3676
- if (decision === 'retained') return 'application';
3677
- if (decision === 'rejected') {
3678
- return 'protocolError';
3679
- }
3680
3766
  try {
3681
- const delivered = await delivery.deliver(sessionRid, retainedPayload);
3682
- settle();
3767
+ const delivered = await delivery.deliver(sessionRid, payloadFrame);
3683
3768
  if (!delivered) return 'protocolError';
3684
3769
  } catch (error) {
3685
- operation.fail(error);
3686
3770
  // Remote command 36 is one-way: its source transport admission has
3687
3771
  // already completed, so a later client delivery terminal is local to
3688
3772
  // this session owner. Local fast paths still preserve the typed result.
@@ -3698,6 +3782,37 @@ export class ServiceStatefulRuntime {
3698
3782
  return 'application';
3699
3783
  }
3700
3784
 
3785
+ // Session–Actor binding §3 item 4: a push refused as not current is
3786
+ // recorded with the closed flow vocabulary (dropped, stream_session, send,
3787
+ // stale_target) instead of disappearing. Nothing is built while tracing is
3788
+ // off.
3789
+ private traceRejectedBoundSessionSend(
3790
+ ingress: RawServiceIngressRecord,
3791
+ record: Extract<ServiceStatefulWireRecord, { readonly kind: 'boundSessionSend' }>,
3792
+ payloadFrame: Uint8Array
3793
+ ): void {
3794
+ const tracePoint = flowIfEnabled(this.dispatchErrors?.flow, ZLinkMessageFlowOutcome.Dropped);
3795
+ if (tracePoint === undefined) return;
3796
+ let packetName: string | undefined;
3797
+ try {
3798
+ packetName = decodeApplicationPayloadView(payloadFrame).packetName;
3799
+ } catch (error) {
3800
+ // A malformed payload is still a refused push; it is traced without a
3801
+ // packet name.
3802
+ if (!(error instanceof ServiceWireProtocolError)) throw error;
3803
+ }
3804
+ tracePoint.trace({
3805
+ outcome: ZLinkMessageFlowOutcome.Dropped,
3806
+ surface: ZLinkDispatchErrorSurface.StreamSession,
3807
+ messageKind: ZLinkDispatchMessageKind.Send,
3808
+ ...(packetName === undefined ? {} : { packetName }),
3809
+ ...(this.dispatchErrorMeshName === undefined ? {} : { meshName: this.dispatchErrorMeshName }),
3810
+ sourceRid: ingress.sourceRoutingId,
3811
+ actorId: record.actor.actor.actorId,
3812
+ errorReason: ZLinkDispatchErrorReason.StaleTarget
3813
+ });
3814
+ }
3815
+
3701
3816
  private enqueueApplicationFrame(
3702
3817
  ingress: RawServiceIngressRecord,
3703
3818
  owner: string,
@@ -3826,7 +3941,13 @@ export class ServiceStatefulRuntime {
3826
3941
  control: ActorControlPayload,
3827
3942
  onTerminalCompletion?: () => void | Promise<void>
3828
3943
  ): void {
3829
- const header = Buffer.from([0x5a, 0x4d, 1, M6bServiceWireCommand.actorJoined, 0]);
3944
+ const header = Buffer.from([
3945
+ SERVICE_WIRE_MAGIC[0],
3946
+ SERVICE_WIRE_MAGIC[1],
3947
+ SERVICE_WIRE_MAJOR,
3948
+ M6bServiceWireCommand.actorJoined,
3949
+ 0
3950
+ ]);
3830
3951
  let terminalAttempted = false;
3831
3952
  void (async () => {
3832
3953
  const applicationJobOwner = await this.raw.reserveLocalIngress();
@@ -3872,7 +3993,13 @@ export class ServiceStatefulRuntime {
3872
3993
  ): boolean {
3873
3994
  const actor = binding.actor;
3874
3995
  const sessionOwner = requireSessionOwnerIdentity(binding);
3875
- const header = Buffer.from([0x5a, 0x4d, 1, M6bServiceWireCommand.boundSessionBind, 0]);
3996
+ const header = Buffer.from([
3997
+ SERVICE_WIRE_MAGIC[0],
3998
+ SERVICE_WIRE_MAGIC[1],
3999
+ SERVICE_WIRE_MAJOR,
4000
+ M6bServiceWireCommand.boundSessionBind,
4001
+ 0
4002
+ ]);
3876
4003
  const applicationJob = requireApplicationJobOwner(ingress).takeInitial('infrastructure');
3877
4004
  const accepted = this.raw.mailbox.tryEnqueue({
3878
4005
  owner: `actor:${actor.actorId}\0${actor.generation}`,
@@ -4046,7 +4173,7 @@ export class ServiceStatefulRuntime {
4046
4173
  handler: ServiceUserSpotOperationHandler,
4047
4174
  record: ServiceUserSpotCreateRecord | ServiceUserSpotCloseRecord | ServiceActorCreateRecord
4048
4175
  ): Promise<ServiceUserSpotOperationResult> {
4049
- const deadline = userSpotDeadline(record.deadlineUnixMs);
4176
+ const deadline = operationDeadline(record.deadlineUnixMs);
4050
4177
  try {
4051
4178
  const result =
4052
4179
  record.kind === 'userSpotCreate'
@@ -4150,7 +4277,10 @@ export class ServiceStatefulRuntime {
4150
4277
  stop.signal.throwIfAborted();
4151
4278
  if (!durableRequestCanReplay(error)) throw error;
4152
4279
  if (durableRequestWasAdmitted(error)) wasAdmitted = true;
4153
- const retryDelayMs = Math.min(20, deadlineMs - performance.now());
4280
+ const retryDelayMs = Math.min(
4281
+ STATEFUL_OPERATION_RETRY_TICK_MS,
4282
+ deadlineMs - performance.now()
4283
+ );
4154
4284
  if (retryDelayMs <= 0) {
4155
4285
  throw durableOperationExhausted(operationKind, wasAdmitted, error);
4156
4286
  }
@@ -4201,8 +4331,8 @@ export class ServiceStatefulRuntime {
4201
4331
  const applicationJobOwner = await this.raw.reserveLocalIngress();
4202
4332
  try {
4203
4333
  const result = await this.ingress({
4204
- command: header[3]!,
4205
- flags: header[4]!,
4334
+ command: header[SERVICE_WIRE_COMMAND_OFFSET]!,
4335
+ flags: header[SERVICE_WIRE_FLAGS_OFFSET]!,
4206
4336
  sourceRoutingId: this.nodeRid,
4207
4337
  requestSequence,
4208
4338
  reply: finish,
@@ -4239,8 +4369,8 @@ export class ServiceStatefulRuntime {
4239
4369
  void ServiceStatefulRuntime.detachedIngressScope(async () => {
4240
4370
  try {
4241
4371
  await this.ingress({
4242
- command: parts[0]![3]!,
4243
- flags: parts[0]![4]!,
4372
+ command: parts[0]![SERVICE_WIRE_COMMAND_OFFSET]!,
4373
+ flags: parts[0]![SERVICE_WIRE_FLAGS_OFFSET]!,
4244
4374
  sourceRoutingId: this.nodeRid,
4245
4375
  sourceNodeGeneration: this.nodeGeneration,
4246
4376
  parts,
@@ -4258,8 +4388,8 @@ export class ServiceStatefulRuntime {
4258
4388
  }
4259
4389
  try {
4260
4390
  const result = await this.ingress({
4261
- command: parts[0]![3]!,
4262
- flags: parts[0]![4]!,
4391
+ command: parts[0]![SERVICE_WIRE_COMMAND_OFFSET]!,
4392
+ flags: parts[0]![SERVICE_WIRE_FLAGS_OFFSET]!,
4263
4393
  sourceRoutingId: this.nodeRid,
4264
4394
  sourceNodeGeneration: this.nodeGeneration,
4265
4395
  parts,
@@ -4300,18 +4430,30 @@ export class ServiceStatefulRuntime {
4300
4430
  ): void {
4301
4431
  if (targetNodeRid === this.nodeRid) {
4302
4432
  const deadlineUnixMs = BigInt(Date.now() + Math.max(0, timeoutMs));
4433
+ const capacityStop = new AbortController();
4434
+ void pending.promise.then(
4435
+ () => capacityStop.abort(),
4436
+ () => capacityStop.abort()
4437
+ );
4303
4438
  void (async () => {
4304
- const applicationJobOwner = await this.raw.reserveLocalIngress();
4305
- const localIngress: RawServiceIngressRecord = {
4306
- command: parts[0]![3]!,
4307
- flags: parts[0]![4]!,
4308
- sourceRoutingId: this.nodeRid,
4309
- requestSequence: pending.id,
4310
- parts,
4311
- applicationJobOwner
4312
- };
4439
+ const applicationJobOwner = await this.raw.reserveLocalIngress(capacityStop.signal);
4313
4440
  try {
4314
- this.submitLocalRequest(localIngress, pending, operationKind, actor, deadlineUnixMs);
4441
+ if (!this.operations.isPending(pending.id)) return;
4442
+ const localIngress: RawServiceIngressRecord = {
4443
+ command: parts[0]![SERVICE_WIRE_COMMAND_OFFSET]!,
4444
+ flags: parts[0]![SERVICE_WIRE_FLAGS_OFFSET]!,
4445
+ sourceRoutingId: this.nodeRid,
4446
+ requestSequence: pending.id,
4447
+ parts,
4448
+ applicationJobOwner
4449
+ };
4450
+ await this.submitLocalRequest(
4451
+ localIngress,
4452
+ pending,
4453
+ operationKind,
4454
+ actor,
4455
+ deadlineUnixMs
4456
+ );
4315
4457
  } catch (error) {
4316
4458
  this.operations.reply(pending.id, failure(error));
4317
4459
  } finally {
@@ -4340,10 +4482,10 @@ export class ServiceStatefulRuntime {
4340
4482
  ? this.tryActorFence(actor)
4341
4483
  : this.acceptCanonicalActorFence(actor, canonical.actorFence);
4342
4484
  if (target === undefined || actorRoute === undefined) {
4343
- this.operations.reply(pending.id, {
4344
- terminalResult: RequestResult.NotFound,
4345
- failureCode: ACTOR_ROUTE_STALE
4346
- });
4485
+ this.operations.reply(
4486
+ pending.id,
4487
+ internalFrameworkWireReply(ZLinkFrameworkInternalErrorKind.ActorLocationStale)
4488
+ );
4347
4489
  return;
4348
4490
  }
4349
4491
  if (canonical !== undefined) {
@@ -4412,7 +4554,7 @@ export class ServiceStatefulRuntime {
4412
4554
  );
4413
4555
  }
4414
4556
 
4415
- private submitLocalRequest(
4557
+ private async submitLocalRequest(
4416
4558
  ingress: RawServiceIngressRecord,
4417
4559
  pending: ServiceStatefulPendingOperation,
4418
4560
  operationKind:
@@ -4426,7 +4568,7 @@ export class ServiceStatefulRuntime {
4426
4568
  | 'instanceSpotRequest',
4427
4569
  actor?: ServiceActorRef,
4428
4570
  deadlineUnixMs?: bigint
4429
- ): void {
4571
+ ): Promise<void> {
4430
4572
  const canonicalActorJoin =
4431
4573
  operationKind === 'actorJoin' ? decodeActorJoin28(ingress.parts) : undefined;
4432
4574
  const decoded =
@@ -4502,7 +4644,9 @@ export class ServiceStatefulRuntime {
4502
4644
  operationKind: OperationKind.ActorRequest,
4503
4645
  correlation: decoded.correlation,
4504
4646
  targetActor: current.ref,
4505
- ...(decoded.sourceActor === undefined ? {} : { sourceActor: decoded.sourceActor }),
4647
+ ...(decoded.sourceActor === undefined
4648
+ ? {}
4649
+ : { sourceActor: { ...decoded.sourceActor, nodeRid: ingress.sourceRoutingId } }),
4506
4650
  ...(decoded.boundSession === undefined
4507
4651
  ? {}
4508
4652
  : { sourceBindingGeneration: decoded.boundSession.bindingGeneration }),
@@ -4801,7 +4945,16 @@ export class ServiceStatefulRuntime {
4801
4945
  return spot;
4802
4946
  }
4803
4947
 
4804
- private validateDirectSpotFence(fence: ServiceDirectSpotRouteFence): ServiceSpotState {
4948
+ private validateDirectSpotFence(fence: ServiceSpotRouteFence): ServiceSpotState {
4949
+ if (
4950
+ fence.targetNodeRid !== this.nodeRid ||
4951
+ fence.targetNodeGeneration !== this.nodeGeneration
4952
+ ) {
4953
+ throw createInternalFrameworkException(
4954
+ ZLinkFrameworkInternalErrorKind.SpotMoving,
4955
+ `Spot '${fence.spot.spotId}' targets an unavailable owner route.`
4956
+ );
4957
+ }
4805
4958
  const spot = this.registry.spot(fence.spot.spotId);
4806
4959
  if (spot === undefined) {
4807
4960
  throw createInternalFrameworkException(
@@ -4815,15 +4968,6 @@ export class ServiceStatefulRuntime {
4815
4968
  `Spot '${fence.spot.spotId}' is not Ready.`
4816
4969
  );
4817
4970
  }
4818
- if (
4819
- fence.targetNodeRid !== this.nodeRid ||
4820
- fence.targetNodeGeneration !== this.nodeGeneration
4821
- ) {
4822
- throw createInternalFrameworkException(
4823
- ZLinkFrameworkInternalErrorKind.SpotMoving,
4824
- `Spot '${fence.spot.spotId}' targets an unavailable owner route.`
4825
- );
4826
- }
4827
4971
  if (spot.kind === 'entry') {
4828
4972
  if (!isEntrySpotFence(fence)) {
4829
4973
  throw createInternalFrameworkException(
@@ -4860,7 +5004,7 @@ export class ServiceStatefulRuntime {
4860
5004
  wire: Extract<ServiceStatefulWireRecord, { readonly kind: 'spotSend' | 'spotRequest' }>
4861
5005
  ): RawServicePumpResult | undefined {
4862
5006
  const state = this.spotMessageFollow.get(spotKey(wire.target.spot));
4863
- if (state === undefined || !sameDirectSpotRoute(state.source, wire.target)) {
5007
+ if (state === undefined || !sameDirectSpotRouteIdentity(state.source, wire.target)) {
4864
5008
  return undefined;
4865
5009
  }
4866
5010
  if (state.expiresAtMs !== undefined && state.expiresAtMs <= performance.now()) {
@@ -4912,14 +5056,22 @@ export class ServiceStatefulRuntime {
4912
5056
  }
4913
5057
  const current = this.peekSpotMessageFollow(state)!;
4914
5058
  try {
5059
+ const metadata =
5060
+ (current.ingress.parts[0]![SERVICE_WIRE_FLAGS_OFFSET]! &
5061
+ M6bServiceWireFlag.metadata) !==
5062
+ 0;
4915
5063
  const parts = [
4916
5064
  encodeSpotHeader(
4917
5065
  current.wire.kind,
4918
5066
  current.wire.sourceSpotId,
4919
5067
  state.target,
4920
- current.wire.correlation!
5068
+ current.wire.correlation,
5069
+ current.wire.operation,
5070
+ current.wire.messageFollowHopCount + 1,
5071
+ metadata ? current.ingress.parts[1] : undefined
4921
5072
  ),
4922
- current.ingress.parts[1]!
5073
+ ...(metadata ? [current.ingress.parts[1]!] : []),
5074
+ current.ingress.parts[metadata ? 2 : 1]!
4923
5075
  ];
4924
5076
  if (current.wire.kind === 'spotSend') {
4925
5077
  if (!(await this.raw.sendService(state.target.targetNodeRid, parts))) continue;
@@ -5046,7 +5198,7 @@ export class ServiceStatefulRuntime {
5046
5198
  if (state.queuedCount === 0) {
5047
5199
  state.queued.length = 0;
5048
5200
  state.queuedHead = 0;
5049
- } else if (state.queuedHead >= 1024 && state.queuedHead * 2 >= state.queued.length) {
5201
+ } else if (shouldCompactBackingArray(state.queuedHead, state.queued.length)) {
5050
5202
  state.queued.splice(0, state.queuedHead);
5051
5203
  state.queuedHead = 0;
5052
5204
  }
@@ -5058,34 +5210,6 @@ export class ServiceStatefulRuntime {
5058
5210
  return route;
5059
5211
  }
5060
5212
 
5061
- private tryBoundSessionSendFence(
5062
- actor: ServiceActorRef,
5063
- senderFence: ServiceBoundSessionSendFence | undefined
5064
- ): ServiceActorRouteFence | undefined {
5065
- if (
5066
- senderFence === undefined ||
5067
- senderFence.targetNodeGeneration !== this.nodeGeneration ||
5068
- senderFence.authorityOwnerGeneration <= 0n ||
5069
- senderFence.ownerLeaseGeneration <= 0n
5070
- ) {
5071
- return undefined;
5072
- }
5073
- const local = actor.nodeRid === this.nodeRid ? this.registry.actor(actor.actorId) : undefined;
5074
- if (
5075
- local === undefined ||
5076
- !sameActorRef(local.ref, actor) ||
5077
- local.authorityOwnerGeneration !== senderFence.authorityOwnerGeneration
5078
- ) {
5079
- return undefined;
5080
- }
5081
- return {
5082
- actor,
5083
- targetNodeGeneration: senderFence.targetNodeGeneration,
5084
- authorityOwnerGeneration: senderFence.authorityOwnerGeneration,
5085
- ownerLeaseGeneration: senderFence.ownerLeaseGeneration
5086
- };
5087
- }
5088
-
5089
5213
  private tryActorFence(actor: ServiceActorRef): ServiceActorRouteFence | undefined {
5090
5214
  const local = actor.nodeRid === this.nodeRid ? this.registry.actor(actor.actorId) : undefined;
5091
5215
  if (local !== undefined && sameActorRef(local.ref, actor)) {
@@ -5295,48 +5419,32 @@ export class ServiceStatefulRuntime {
5295
5419
  }
5296
5420
  }
5297
5421
 
5298
- function serviceSpotPublishFailureReason(
5299
- result: number | undefined,
5300
- routeReady: boolean,
5301
- closed: boolean
5302
- ): 'stale_target' | 'backpressure' | 'shutdown' {
5303
- if (closed || result === SubmitResult.Terminated) return 'shutdown';
5304
- switch (result) {
5305
- case SubmitResult.Backpressured:
5306
- return 'backpressure';
5307
- case SubmitResult.NotAdmitted:
5308
- case SubmitResult.NotConnected:
5309
- case SubmitResult.NotFound:
5310
- case SubmitResult.InvalidHandle:
5311
- return 'stale_target';
5312
- default:
5313
- // RawServiceMeshRuntime exposes failed Core submissions as false. A
5314
- // ready route therefore identifies queue admission failure; a route
5315
- // that became unready after selection is a stale target.
5316
- return routeReady ? 'backpressure' : 'stale_target';
5317
- }
5318
- }
5319
-
5320
- function isEntrySpotFence(fence: ServiceDirectSpotRouteFence): boolean {
5422
+ function isEntrySpotFence(fence: ServiceSpotRouteFence): boolean {
5321
5423
  return (
5322
5424
  fence.spot.spotId === fence.targetNodeRid &&
5323
5425
  fence.spot.generation === fence.targetNodeGeneration &&
5324
5426
  fence.authorityOwnerGeneration === fence.targetNodeGeneration &&
5325
- fence.ownerLeaseGeneration === fence.targetNodeGeneration &&
5326
- fence.storeVersion === `entry:${fence.targetNodeGeneration}`
5427
+ fence.ownerLeaseGeneration === fence.targetNodeGeneration
5327
5428
  );
5328
5429
  }
5329
5430
 
5330
- function userSpotDeadline(deadlineUnixMs: bigint): {
5431
+ function operationDeadline(deadlineUnixMs: bigint): {
5331
5432
  readonly signal: AbortSignal;
5332
5433
  close(): void;
5333
5434
  } {
5334
5435
  const controller = new AbortController();
5335
5436
  const delay = Number(deadlineUnixMs - BigInt(Date.now()));
5336
- const timeout = setTimeout(
5337
- () => controller.abort(new Error('User Spot operation deadline exceeded.')),
5338
- Math.max(0, Math.min(delay, 0x7fff_ffff))
5339
- );
5437
+ const expire = () =>
5438
+ controller.abort(
5439
+ createInternalFrameworkException(
5440
+ ZLinkFrameworkInternalErrorKind.DeadlineExceeded,
5441
+ 'Operation deadline exceeded.'
5442
+ )
5443
+ );
5444
+ const timeout =
5445
+ delay <= 0
5446
+ ? (expire(), undefined)
5447
+ : setTimeout(expire, Math.min(delay, MAX_NODE_TIMER_DELAY_MS));
5340
5448
  return {
5341
5449
  signal: controller.signal,
5342
5450
  close: () => clearTimeout(timeout)
@@ -5417,12 +5525,12 @@ function actorLocation(actor: ServiceActorState): ActorLocation {
5417
5525
 
5418
5526
  function failure(error: unknown): ServiceStatefulResult {
5419
5527
  if (error instanceof ServiceStaleGenerationError) {
5420
- return { terminalResult: RequestResult.NotFound, failureCode: ACTOR_ROUTE_STALE };
5528
+ return internalFrameworkWireReply(ZLinkFrameworkInternalErrorKind.ActorLocationStale);
5421
5529
  }
5422
5530
  if (error instanceof ZLinkFrameworkException) {
5423
5531
  return internalFrameworkWireReply(error);
5424
5532
  }
5425
- return { terminalResult: RequestResult.InternalError, failureCode: 17 };
5533
+ return internalFrameworkWireReply(ZLinkFrameworkInternalErrorKind.RequestFailed);
5426
5534
  }
5427
5535
 
5428
5536
  function actorKey(actor: ServiceActorRef): string {
@@ -5744,15 +5852,15 @@ function sameMessageFollowSpotSource(
5744
5852
  }
5745
5853
 
5746
5854
  function sameDirectSpotRouteIdentity(
5747
- left: ServiceDirectSpotRouteFence,
5748
- right: ServiceDirectSpotRouteFence
5855
+ left: ServiceSpotRouteFence,
5856
+ right: ServiceSpotRouteFence
5749
5857
  ): boolean {
5750
5858
  return sameDirectSpotOwnerIdentity(left, right) && left.spot.generation === right.spot.generation;
5751
5859
  }
5752
5860
 
5753
5861
  function sameDirectSpotOwnerIdentity(
5754
- left: ServiceDirectSpotRouteFence,
5755
- right: ServiceDirectSpotRouteFence
5862
+ left: ServiceSpotRouteFence,
5863
+ right: ServiceSpotRouteFence
5756
5864
  ): boolean {
5757
5865
  return (
5758
5866
  left.spot.spotId === right.spot.spotId &&
@@ -5815,7 +5923,7 @@ function topicMatches(filter: string, topic: string): boolean {
5815
5923
  function emptyPayload(): ServiceApplicationPayload {
5816
5924
  return {
5817
5925
  packetName: 'ZLinkFrameworkEmpty',
5818
- contentType: 'application/octet-stream',
5926
+ contentType: ZlinkStreamContentType.Raw,
5819
5927
  payload: Buffer.alloc(0)
5820
5928
  };
5821
5929
  }