@spine-event-engine/server 2.0.0-snapshot.24 → 2.0.0-snapshot.26

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 (374) hide show
  1. package/README.md +86 -19
  2. package/REFERENCE.md +538 -150
  3. package/dist/agent/agent-acceptance-receipts.d.ts +69 -0
  4. package/dist/agent/agent-acceptance-receipts.d.ts.map +1 -0
  5. package/dist/agent/agent-acceptance-receipts.js +198 -0
  6. package/dist/agent/agent-acceptance-receipts.js.map +1 -0
  7. package/dist/agent/agent-execution-capacity.d.ts +37 -9
  8. package/dist/agent/agent-execution-capacity.d.ts.map +1 -1
  9. package/dist/agent/agent-execution-capacity.js +73 -15
  10. package/dist/agent/agent-execution-capacity.js.map +1 -1
  11. package/dist/agent/agent-history.d.ts +33 -12
  12. package/dist/agent/agent-history.d.ts.map +1 -1
  13. package/dist/agent/agent-history.js +61 -18
  14. package/dist/agent/agent-history.js.map +1 -1
  15. package/dist/agent/agent-live-ai-audit.d.ts +95 -0
  16. package/dist/agent/agent-live-ai-audit.d.ts.map +1 -0
  17. package/dist/agent/agent-live-ai-audit.js +290 -0
  18. package/dist/agent/agent-live-ai-audit.js.map +1 -0
  19. package/dist/agent/agent-live-ai-runtime.d.ts +300 -0
  20. package/dist/agent/agent-live-ai-runtime.d.ts.map +1 -0
  21. package/dist/agent/agent-live-ai-runtime.js +611 -0
  22. package/dist/agent/agent-live-ai-runtime.js.map +1 -0
  23. package/dist/agent/agent-live-audit.d.ts +67 -0
  24. package/dist/agent/agent-live-audit.d.ts.map +1 -0
  25. package/dist/agent/agent-live-audit.js +121 -0
  26. package/dist/agent/agent-live-audit.js.map +1 -0
  27. package/dist/agent/agent-live-budget.d.ts +84 -0
  28. package/dist/agent/agent-live-budget.d.ts.map +1 -0
  29. package/dist/agent/agent-live-budget.js +161 -0
  30. package/dist/agent/agent-live-budget.js.map +1 -0
  31. package/dist/agent/agent-live-fault.d.ts +18 -0
  32. package/dist/agent/agent-live-fault.d.ts.map +1 -0
  33. package/dist/agent/{agent-execution-fault.js → agent-live-fault.js} +7 -7
  34. package/dist/agent/agent-live-fault.js.map +1 -0
  35. package/dist/agent/agent-live-inputs.d.ts +74 -0
  36. package/dist/agent/agent-live-inputs.d.ts.map +1 -0
  37. package/dist/agent/agent-live-inputs.js +15 -0
  38. package/dist/agent/agent-live-inputs.js.map +1 -0
  39. package/dist/agent/agent-live-interaction-events.d.ts +46 -0
  40. package/dist/agent/agent-live-interaction-events.d.ts.map +1 -0
  41. package/dist/agent/agent-live-interaction-events.js +104 -0
  42. package/dist/agent/agent-live-interaction-events.js.map +1 -0
  43. package/dist/agent/agent-live-mcp-controls.d.ts +129 -0
  44. package/dist/agent/agent-live-mcp-controls.d.ts.map +1 -0
  45. package/dist/agent/agent-live-mcp-controls.js +228 -0
  46. package/dist/agent/agent-live-mcp-controls.js.map +1 -0
  47. package/dist/agent/agent-live-mcp-host.d.ts +88 -0
  48. package/dist/agent/agent-live-mcp-host.d.ts.map +1 -0
  49. package/dist/agent/{agent-mcp-host.js → agent-live-mcp-host.js} +1 -1
  50. package/dist/agent/agent-live-mcp-host.js.map +1 -0
  51. package/dist/agent/{agent-mcp-runtime.d.ts → agent-live-mcp-runtime.d.ts} +6 -6
  52. package/dist/agent/agent-live-mcp-runtime.d.ts.map +1 -0
  53. package/dist/agent/{agent-mcp-runtime.js → agent-live-mcp-runtime.js} +13 -42
  54. package/dist/agent/agent-live-mcp-runtime.js.map +1 -0
  55. package/dist/agent/agent-live-read-runtime.d.ts +72 -0
  56. package/dist/agent/agent-live-read-runtime.d.ts.map +1 -0
  57. package/dist/agent/agent-live-read-runtime.js +122 -0
  58. package/dist/agent/agent-live-read-runtime.js.map +1 -0
  59. package/dist/agent/agent-model-selection.d.ts +21 -34
  60. package/dist/agent/agent-model-selection.d.ts.map +1 -1
  61. package/dist/agent/agent-model-selection.js +61 -78
  62. package/dist/agent/agent-model-selection.js.map +1 -1
  63. package/dist/browser/browser-server.d.ts +163 -0
  64. package/dist/browser/browser-server.d.ts.map +1 -1
  65. package/dist/browser/browser-server.js +579 -188
  66. package/dist/browser/browser-server.js.map +1 -1
  67. package/dist/browser/durable-subscription-bindings.d.ts +5 -0
  68. package/dist/browser/durable-subscription-bindings.d.ts.map +1 -1
  69. package/dist/browser/durable-subscription-bindings.js +226 -38
  70. package/dist/browser/durable-subscription-bindings.js.map +1 -1
  71. package/dist/browser/options.d.ts +5 -0
  72. package/dist/browser/options.d.ts.map +1 -1
  73. package/dist/bus/command-bus.d.ts +17 -18
  74. package/dist/bus/command-bus.d.ts.map +1 -1
  75. package/dist/bus/command-bus.js +97 -54
  76. package/dist/bus/command-bus.js.map +1 -1
  77. package/dist/bus/command-errors.d.ts +20 -4
  78. package/dist/bus/command-errors.d.ts.map +1 -1
  79. package/dist/bus/command-errors.js +47 -7
  80. package/dist/bus/command-errors.js.map +1 -1
  81. package/dist/bus/event-bus.d.ts +20 -4
  82. package/dist/bus/event-bus.d.ts.map +1 -1
  83. package/dist/bus/event-bus.js +166 -14
  84. package/dist/bus/event-bus.js.map +1 -1
  85. package/dist/context/bounded-context.d.ts +169 -98
  86. package/dist/context/bounded-context.d.ts.map +1 -1
  87. package/dist/context/bounded-context.js +837 -503
  88. package/dist/context/bounded-context.js.map +1 -1
  89. package/dist/context/entity-inbox.d.ts +7 -2
  90. package/dist/context/entity-inbox.d.ts.map +1 -1
  91. package/dist/context/entity-inbox.js +22 -13
  92. package/dist/context/entity-inbox.js.map +1 -1
  93. package/dist/context/local-inbox-handoff.d.ts +34 -34
  94. package/dist/context/local-inbox-handoff.d.ts.map +1 -1
  95. package/dist/context/local-inbox-handoff.js +108 -150
  96. package/dist/context/local-inbox-handoff.js.map +1 -1
  97. package/dist/context/projection-handoff.d.ts +2 -2
  98. package/dist/context/projection-handoff.d.ts.map +1 -1
  99. package/dist/context/projection-handoff.js +10 -8
  100. package/dist/context/projection-handoff.js.map +1 -1
  101. package/dist/context/tenant-index.d.ts +36 -31
  102. package/dist/context/tenant-index.d.ts.map +1 -1
  103. package/dist/context/tenant-index.js +123 -125
  104. package/dist/context/tenant-index.js.map +1 -1
  105. package/dist/context/tenant-unknown-error.d.ts +33 -0
  106. package/dist/context/tenant-unknown-error.d.ts.map +1 -0
  107. package/dist/context/tenant-unknown-error.js +75 -0
  108. package/dist/context/tenant-unknown-error.js.map +1 -0
  109. package/dist/delivery/agent-delivery-scope.d.ts +66 -0
  110. package/dist/delivery/agent-delivery-scope.d.ts.map +1 -0
  111. package/dist/delivery/agent-delivery-scope.js +44 -0
  112. package/dist/delivery/agent-delivery-scope.js.map +1 -0
  113. package/dist/delivery/delivery-builder.d.ts +25 -1
  114. package/dist/delivery/delivery-builder.d.ts.map +1 -1
  115. package/dist/delivery/delivery-builder.js +89 -0
  116. package/dist/delivery/delivery-builder.js.map +1 -1
  117. package/dist/delivery/delivery-monitor.d.ts +1 -1
  118. package/dist/delivery/delivery-monitor.js +1 -1
  119. package/dist/delivery/delivery-run-control.d.ts +6 -0
  120. package/dist/delivery/delivery-run-control.d.ts.map +1 -1
  121. package/dist/delivery/delivery-run-control.js +10 -0
  122. package/dist/delivery/delivery-run-control.js.map +1 -1
  123. package/dist/delivery/delivery-supervisor.d.ts.map +1 -1
  124. package/dist/delivery/delivery-supervisor.js +28 -4
  125. package/dist/delivery/delivery-supervisor.js.map +1 -1
  126. package/dist/delivery/delivery-tenant.d.ts +17 -0
  127. package/dist/delivery/delivery-tenant.d.ts.map +1 -0
  128. package/dist/delivery/delivery-tenant.js +50 -0
  129. package/dist/delivery/delivery-tenant.js.map +1 -0
  130. package/dist/delivery/delivery.d.ts +96 -2
  131. package/dist/delivery/delivery.d.ts.map +1 -1
  132. package/dist/delivery/delivery.js +693 -53
  133. package/dist/delivery/delivery.js.map +1 -1
  134. package/dist/delivery/inbox-records.d.ts.map +1 -1
  135. package/dist/delivery/inbox-records.js +9 -16
  136. package/dist/delivery/inbox-records.js.map +1 -1
  137. package/dist/delivery/inbox-storage.d.ts +6 -0
  138. package/dist/delivery/inbox-storage.d.ts.map +1 -1
  139. package/dist/delivery/inbox-storage.js +43 -6
  140. package/dist/delivery/inbox-storage.js.map +1 -1
  141. package/dist/delivery/inbox.d.ts.map +1 -1
  142. package/dist/delivery/inbox.js +3 -2
  143. package/dist/delivery/inbox.js.map +1 -1
  144. package/dist/delivery/reception-observation.d.ts +12 -4
  145. package/dist/delivery/reception-observation.d.ts.map +1 -1
  146. package/dist/delivery/reception-observation.js +14 -3
  147. package/dist/delivery/reception-observation.js.map +1 -1
  148. package/dist/delivery/sharded-work-registry.d.ts +6 -0
  149. package/dist/delivery/sharded-work-registry.d.ts.map +1 -1
  150. package/dist/delivery/sharded-work-registry.js +41 -4
  151. package/dist/delivery/sharded-work-registry.js.map +1 -1
  152. package/dist/entity/entity-storage-descriptor.d.ts.map +1 -1
  153. package/dist/entity/entity-storage-descriptor.js +7 -4
  154. package/dist/entity/entity-storage-descriptor.js.map +1 -1
  155. package/dist/entity/entity.d.ts +59 -0
  156. package/dist/entity/entity.d.ts.map +1 -1
  157. package/dist/entity/entity.js +60 -0
  158. package/dist/entity/entity.js.map +1 -1
  159. package/dist/handler/app-query-handler.d.ts +60 -0
  160. package/dist/handler/app-query-handler.d.ts.map +1 -0
  161. package/dist/{bus/saved-dispatcher-binding.js → handler/app-query-handler.js} +8 -12
  162. package/dist/handler/app-query-handler.js.map +1 -0
  163. package/dist/handler/generated-registry-discovery.d.ts +6 -0
  164. package/dist/handler/generated-registry-discovery.d.ts.map +1 -1
  165. package/dist/handler/generated-registry-discovery.js +71 -2
  166. package/dist/handler/generated-registry-discovery.js.map +1 -1
  167. package/dist/handler/handler-decorators.d.ts +8 -29
  168. package/dist/handler/handler-decorators.d.ts.map +1 -1
  169. package/dist/handler/handler-decorators.js +33 -210
  170. package/dist/handler/handler-decorators.js.map +1 -1
  171. package/dist/handler/spine-metadata-inventory.d.ts +99 -0
  172. package/dist/handler/spine-metadata-inventory.d.ts.map +1 -0
  173. package/dist/handler/spine-metadata-inventory.js +162 -0
  174. package/dist/handler/spine-metadata-inventory.js.map +1 -0
  175. package/dist/index.d.ts +9 -5
  176. package/dist/index.d.ts.map +1 -1
  177. package/dist/index.js +6 -3
  178. package/dist/index.js.map +1 -1
  179. package/dist/integration/external-messages.d.ts.map +1 -1
  180. package/dist/integration/external-messages.js +9 -15
  181. package/dist/integration/external-messages.js.map +1 -1
  182. package/dist/integration/integration-broker.d.ts.map +1 -1
  183. package/dist/integration/integration-broker.js +112 -6
  184. package/dist/integration/integration-broker.js.map +1 -1
  185. package/dist/integration/third-party-context.d.ts.map +1 -1
  186. package/dist/integration/third-party-context.js +7 -10
  187. package/dist/integration/third-party-context.js.map +1 -1
  188. package/dist/repository/primitive-id.js +26 -11
  189. package/dist/repository/primitive-id.js.map +1 -1
  190. package/dist/repository/repository.d.ts +75 -60
  191. package/dist/repository/repository.d.ts.map +1 -1
  192. package/dist/repository/repository.js +1757 -1818
  193. package/dist/repository/repository.js.map +1 -1
  194. package/dist/runtime/runtime.d.ts +13 -0
  195. package/dist/runtime/runtime.d.ts.map +1 -1
  196. package/dist/runtime/runtime.js +18 -0
  197. package/dist/runtime/runtime.js.map +1 -1
  198. package/dist/runtime/signal-metadata.d.ts.map +1 -1
  199. package/dist/runtime/signal-metadata.js +6 -6
  200. package/dist/runtime/signal-metadata.js.map +1 -1
  201. package/dist/runtime/signal-publisher.d.ts +0 -6
  202. package/dist/runtime/signal-publisher.d.ts.map +1 -1
  203. package/dist/runtime/signal-publisher.js +1 -9
  204. package/dist/runtime/signal-publisher.js.map +1 -1
  205. package/dist/runtime/standalone-handler-runtime.d.ts +0 -7
  206. package/dist/runtime/standalone-handler-runtime.d.ts.map +1 -1
  207. package/dist/runtime/standalone-handler-runtime.js +13 -99
  208. package/dist/runtime/standalone-handler-runtime.js.map +1 -1
  209. package/dist/server/managed-delivery-gate.d.ts +34 -0
  210. package/dist/server/managed-delivery-gate.d.ts.map +1 -0
  211. package/dist/server/managed-delivery-gate.js +70 -0
  212. package/dist/server/managed-delivery-gate.js.map +1 -0
  213. package/dist/server/managed-server-application.d.ts +12 -11
  214. package/dist/server/managed-server-application.d.ts.map +1 -1
  215. package/dist/server/managed-server-application.js +48 -29
  216. package/dist/server/managed-server-application.js.map +1 -1
  217. package/dist/server/node-coordinator.d.ts +18 -5
  218. package/dist/server/node-coordinator.d.ts.map +1 -1
  219. package/dist/server/node-coordinator.js +554 -84
  220. package/dist/server/node-coordinator.js.map +1 -1
  221. package/dist/server/reserved-spine-rpc-paths.json +1 -0
  222. package/dist/server/server-environment.d.ts +220 -25
  223. package/dist/server/server-environment.d.ts.map +1 -1
  224. package/dist/server/server-environment.js +734 -145
  225. package/dist/server/server-environment.js.map +1 -1
  226. package/dist/server/server-log.d.ts +7 -0
  227. package/dist/server/server-log.d.ts.map +1 -1
  228. package/dist/server/server-log.js +14 -1
  229. package/dist/server/server-log.js.map +1 -1
  230. package/dist/server/server.d.ts +60 -29
  231. package/dist/server/server.d.ts.map +1 -1
  232. package/dist/server/server.js +155 -201
  233. package/dist/server/server.js.map +1 -1
  234. package/dist/services/app-query-execution.d.ts +53 -0
  235. package/dist/services/app-query-execution.d.ts.map +1 -0
  236. package/dist/services/app-query-execution.js +408 -0
  237. package/dist/services/app-query-execution.js.map +1 -0
  238. package/dist/services/query-reader.d.ts +32 -7
  239. package/dist/services/query-reader.d.ts.map +1 -1
  240. package/dist/services/query-reader.js +22 -2
  241. package/dist/services/query-reader.js.map +1 -1
  242. package/dist/services/read-request-status.d.ts +65 -0
  243. package/dist/services/read-request-status.d.ts.map +1 -0
  244. package/dist/services/read-request-status.js +151 -0
  245. package/dist/services/read-request-status.js.map +1 -0
  246. package/dist/services/spine-services.d.ts +37 -8
  247. package/dist/services/spine-services.d.ts.map +1 -1
  248. package/dist/services/spine-services.js +1103 -470
  249. package/dist/services/spine-services.js.map +1 -1
  250. package/dist/services/trusted-reader-ingress.d.ts +92 -0
  251. package/dist/services/trusted-reader-ingress.d.ts.map +1 -0
  252. package/dist/services/trusted-reader-ingress.js +89 -0
  253. package/dist/services/trusted-reader-ingress.js.map +1 -0
  254. package/dist/spi/handler-registry.d.ts +2 -0
  255. package/dist/spi/handler-registry.d.ts.map +1 -1
  256. package/dist/spi/handler-registry.js +1 -1
  257. package/dist/spi/handler-registry.js.map +1 -1
  258. package/dist/stand/event-origin-filter.js +3 -3
  259. package/dist/stand/event-origin-filter.js.map +1 -1
  260. package/dist/stand/read-side-filter-engine.d.ts +46 -0
  261. package/dist/stand/read-side-filter-engine.d.ts.map +1 -0
  262. package/dist/stand/read-side-filter-engine.js +356 -0
  263. package/dist/stand/read-side-filter-engine.js.map +1 -0
  264. package/dist/stand/read-side-filter.d.ts +247 -0
  265. package/dist/stand/read-side-filter.d.ts.map +1 -0
  266. package/dist/stand/read-side-filter.js +39 -0
  267. package/dist/stand/read-side-filter.js.map +1 -0
  268. package/dist/stand/read-side-message.d.ts +66 -0
  269. package/dist/stand/read-side-message.d.ts.map +1 -0
  270. package/dist/stand/read-side-message.js +167 -0
  271. package/dist/stand/read-side-message.js.map +1 -0
  272. package/dist/stand/stand-direct-delivery.d.ts +161 -0
  273. package/dist/stand/stand-direct-delivery.d.ts.map +1 -0
  274. package/dist/stand/stand-direct-delivery.js +210 -0
  275. package/dist/stand/stand-direct-delivery.js.map +1 -0
  276. package/dist/stand/stand.d.ts +94 -42
  277. package/dist/stand/stand.d.ts.map +1 -1
  278. package/dist/stand/stand.js +460 -60
  279. package/dist/stand/stand.js.map +1 -1
  280. package/dist/stand/subscription-observer.d.ts.map +1 -1
  281. package/dist/stand/subscription-observer.js +157 -40
  282. package/dist/stand/subscription-observer.js.map +1 -1
  283. package/dist/stand/subscription-read-filters.d.ts +40 -0
  284. package/dist/stand/subscription-read-filters.d.ts.map +1 -0
  285. package/dist/stand/subscription-read-filters.js +91 -0
  286. package/dist/stand/subscription-read-filters.js.map +1 -0
  287. package/dist/stand/subscription-reader-binding.d.ts +20 -0
  288. package/dist/stand/subscription-reader-binding.d.ts.map +1 -0
  289. package/dist/stand/subscription-reader-binding.js +56 -0
  290. package/dist/stand/subscription-reader-binding.js.map +1 -0
  291. package/dist/stand/subscription-records.d.ts +30 -3
  292. package/dist/stand/subscription-records.d.ts.map +1 -1
  293. package/dist/stand/subscription-records.js +61 -16
  294. package/dist/stand/subscription-records.js.map +1 -1
  295. package/dist/stand/subscription-registry.d.ts +54 -15
  296. package/dist/stand/subscription-registry.d.ts.map +1 -1
  297. package/dist/stand/subscription-registry.js +164 -41
  298. package/dist/stand/subscription-registry.js.map +1 -1
  299. package/dist/stand/subscription-runtime.d.ts +12 -5
  300. package/dist/stand/subscription-runtime.d.ts.map +1 -1
  301. package/dist/stand/subscription-runtime.js +183 -34
  302. package/dist/stand/subscription-runtime.js.map +1 -1
  303. package/dist/testing/index.d.ts.map +1 -1
  304. package/dist/testing/index.js +4 -3
  305. package/dist/testing/index.js.map +1 -1
  306. package/dist/tsconfig.tsbuildinfo +1 -1
  307. package/package.json +14 -14
  308. package/dist/agent/agent-admission.d.ts +0 -80
  309. package/dist/agent/agent-admission.d.ts.map +0 -1
  310. package/dist/agent/agent-admission.js +0 -127
  311. package/dist/agent/agent-admission.js.map +0 -1
  312. package/dist/agent/agent-ai-runtime.d.ts +0 -76
  313. package/dist/agent/agent-ai-runtime.d.ts.map +0 -1
  314. package/dist/agent/agent-ai-runtime.js +0 -1269
  315. package/dist/agent/agent-ai-runtime.js.map +0 -1
  316. package/dist/agent/agent-execution-fault.d.ts +0 -18
  317. package/dist/agent/agent-execution-fault.d.ts.map +0 -1
  318. package/dist/agent/agent-execution-fault.js.map +0 -1
  319. package/dist/agent/agent-execution-session.d.ts +0 -103
  320. package/dist/agent/agent-execution-session.d.ts.map +0 -1
  321. package/dist/agent/agent-execution-session.js +0 -238
  322. package/dist/agent/agent-execution-session.js.map +0 -1
  323. package/dist/agent/agent-interaction-audit.d.ts +0 -58
  324. package/dist/agent/agent-interaction-audit.d.ts.map +0 -1
  325. package/dist/agent/agent-interaction-audit.js +0 -114
  326. package/dist/agent/agent-interaction-audit.js.map +0 -1
  327. package/dist/agent/agent-interaction-events.d.ts +0 -40
  328. package/dist/agent/agent-interaction-events.d.ts.map +0 -1
  329. package/dist/agent/agent-interaction-events.js +0 -129
  330. package/dist/agent/agent-interaction-events.js.map +0 -1
  331. package/dist/agent/agent-mcp-budget.d.ts +0 -125
  332. package/dist/agent/agent-mcp-budget.d.ts.map +0 -1
  333. package/dist/agent/agent-mcp-budget.js +0 -566
  334. package/dist/agent/agent-mcp-budget.js.map +0 -1
  335. package/dist/agent/agent-mcp-host.d.ts +0 -125
  336. package/dist/agent/agent-mcp-host.d.ts.map +0 -1
  337. package/dist/agent/agent-mcp-host.js.map +0 -1
  338. package/dist/agent/agent-mcp-runtime.d.ts.map +0 -1
  339. package/dist/agent/agent-mcp-runtime.js.map +0 -1
  340. package/dist/agent/agent-read-runtime.d.ts +0 -70
  341. package/dist/agent/agent-read-runtime.d.ts.map +0 -1
  342. package/dist/agent/agent-read-runtime.js +0 -320
  343. package/dist/agent/agent-read-runtime.js.map +0 -1
  344. package/dist/agent/agent-revisions.d.ts +0 -35
  345. package/dist/agent/agent-revisions.d.ts.map +0 -1
  346. package/dist/agent/agent-revisions.js +0 -133
  347. package/dist/agent/agent-revisions.js.map +0 -1
  348. package/dist/agent/agent-scheduler.d.ts +0 -99
  349. package/dist/agent/agent-scheduler.d.ts.map +0 -1
  350. package/dist/agent/agent-scheduler.js +0 -398
  351. package/dist/agent/agent-scheduler.js.map +0 -1
  352. package/dist/bus/saved-dispatcher-binding.d.ts +0 -53
  353. package/dist/bus/saved-dispatcher-binding.d.ts.map +0 -1
  354. package/dist/bus/saved-dispatcher-binding.js.map +0 -1
  355. package/dist/delivery/delivery-run-coordinator.d.ts +0 -218
  356. package/dist/delivery/delivery-run-coordinator.d.ts.map +0 -1
  357. package/dist/delivery/delivery-run-coordinator.js +0 -609
  358. package/dist/delivery/delivery-run-coordinator.js.map +0 -1
  359. package/dist/delivery/parked-delivery-obligations.d.ts +0 -182
  360. package/dist/delivery/parked-delivery-obligations.d.ts.map +0 -1
  361. package/dist/delivery/parked-delivery-obligations.js +0 -390
  362. package/dist/delivery/parked-delivery-obligations.js.map +0 -1
  363. package/dist/server/environment-attachment.d.ts +0 -356
  364. package/dist/server/environment-attachment.d.ts.map +0 -1
  365. package/dist/server/environment-attachment.js +0 -2062
  366. package/dist/server/environment-attachment.js.map +0 -1
  367. package/dist/server/environment-delivery-records.d.ts +0 -77
  368. package/dist/server/environment-delivery-records.d.ts.map +0 -1
  369. package/dist/server/environment-delivery-records.js +0 -282
  370. package/dist/server/environment-delivery-records.js.map +0 -1
  371. package/dist/server/environment-delivery-worker.d.ts +0 -161
  372. package/dist/server/environment-delivery-worker.d.ts.map +0 -1
  373. package/dist/server/environment-delivery-worker.js +0 -973
  374. package/dist/server/environment-delivery-worker.js.map +0 -1
package/REFERENCE.md CHANGED
@@ -33,7 +33,7 @@ versioned registries are rejected and must be regenerated.
33
33
  Generated standalone handlers extend `AbstractAssignee`, `AbstractCommander`,
34
34
  `AbstractEventReactor`, or `AbstractEventSubscriber`. Register instances with
35
35
  `addAssignee()`, `addCommandDispatcher()`, or `addEventDispatcher()` as their
36
- role requires, then use `buildAsync()` to load generated receiver metadata and
36
+ role requires, then use `build()` to load generated receiver metadata and
37
37
  match the exact constructor. Assignees consume Commands and produce Events;
38
38
  commanders consume Commands, Events, or rejections and produce Commands;
39
39
  reactors consume Events or rejections and may produce Events; subscribers
@@ -139,7 +139,8 @@ valid event with no interested external receptor is simply not delivered.
139
139
  ## Server environment facilities
140
140
 
141
141
  `ServerEnvironment.instance()` is a process-wide singleton. Production
142
- resolution requires storage and the complete application schema registry:
142
+ resolution requires the complete application schema registry; storage defaults to
143
+ in-memory when `storageFactory` is omitted:
143
144
 
144
145
  ```ts
145
146
  import { EnvironmentType, ServerEnvironment } from "@spine-event-engine/server";
@@ -153,9 +154,52 @@ ServerEnvironment.when(EnvironmentType.Production).use({
153
154
  storageFactory,
154
155
  typeRegistry,
155
156
  });
157
+ await ServerEnvironment.instance().completeSetup();
156
158
  ```
157
159
 
158
- `storageFactory` supplies records and events. `typeRegistry` is the complete
160
+ Call `completeSetup()` explicitly before building any Bounded Context. It
161
+ checks the storage connection, initializes integration transport, and opens the
162
+ shared Delivery. Concurrent callers join one setup attempt; a failed attempt
163
+ closes acquired facilities and prevents context assembly. Building a context
164
+ does not start setup. The environment logs an INFO message after each successful
165
+ phase without implying that every Entity model has been prepared.
166
+
167
+ `BoundedContextBuilder.build({ createStorageStructures, startSubscriptionMonitoring })`
168
+ awaits both model preparation and the first subscription reconciliation by
169
+ default. Each option can be set to `false` independently. A deferred phase runs
170
+ before the first valid Command, Event, query, subscription operation, or Inbox
171
+ replay for the receiving context; lazy multitenant preparation selects only that
172
+ input's currently registered tenant. A failed lazy attempt rejects its current
173
+ input and can be retried by a later input. Monitoring requires the shared
174
+ subscription registry, so `startSubscriptionMonitoring: true` prepares that
175
+ registry even when `createStorageStructures: false`; it does not prepare all
176
+ tenant Entity families. An eager required preparation or initial monitoring
177
+ failure stops accepting new input and triggers attempt-all cleanup.
178
+ After a successful first pass, a failed periodic reconciliation logs a WARN
179
+ with the context name and bounded error name or code, leaves unaffected observers active,
180
+ and retries on the existing ten-second schedule. Closing the context cancels
181
+ the timer and drains an admitted pass before detaching observers.
182
+
183
+ `context.runtime.createStorageStructures(...tenantIds)` and
184
+ `context.runtime.checkStructureCompatibility(...tenantIds)` prepare declared
185
+ Record, Entity, history, and Agent audit structures through the configured
186
+ provider. The check is read-only; a successful provider check also satisfies
187
+ later creation readiness. Explicit IDs must be registered in the context's
188
+ effective tenant index. With no IDs, a multitenant context traverses its current
189
+ index in finite pages; a single-tenant context prepares its neutral destination
190
+ without registering a synthetic tenant. `context.runtime.startSubscriptionMonitoring()`
191
+ performs the first registry pass independently of per-tenant Entity preparation.
192
+ The environment's no-argument structure methods include both kinds of completed,
193
+ open context. With explicit IDs, they select only matching multitenant contexts,
194
+ respect each `withTenantIndex` override, and reject an ID absent from all current
195
+ indexes before provider work. They validate every supplied ID before preparing
196
+ any structures. Database-backed providers require an existing database; these
197
+ calls do not provision one or register a tenant. Required explicit provider or initial-monitor
198
+ failure stops new input and triggers automatic cleanup. Unknown or malformed IDs,
199
+ directory lookup failure, and local API misuse reject only that operation;
200
+ lazy first-input provider failures remain request-local and retryable.
201
+
202
+ `storageFactory` supplies records and events to every context. `typeRegistry` is the complete
159
203
  application schema universe used by `ThirdPartyContext` to encode outgoing
160
204
  imported events. An optional `integrationChannelFactory` overrides the
161
205
  process-wide private
@@ -164,6 +208,26 @@ contexts share one in-memory factory, including in production. Local and test
164
208
  environments default storage in memory and use the core registry only as a
165
209
  fallback; those defaults are not production configuration.
166
210
 
211
+ `tenantIndex` selects a live application membership directory. When omitted,
212
+ the environment uses its storage factory's native catalog where available, or
213
+ a transient in-memory index for a custom factory without a catalog. The
214
+ transient index lasts only for this environment instance. `contains()` checks
215
+ membership without preparing storage; `keep()` makes a registration visible to
216
+ later reads and may reject for a read-only catalog. PostgreSQL and MySQL
217
+ catalogs expose only configured tenant entries: `keep()` is idempotent for
218
+ those entries and rejects unknown IDs. A dynamic SQL tenant resolver does not
219
+ register or enumerate tenants. Single-tenant contexts do not insert a synthetic
220
+ member into this directory.
221
+
222
+ Multitenant receiving contexts check current index membership before Command,
223
+ Event, query, direct repository/history, and subscription work. Inbox persistence
224
+ and later replay check separately, so removing a tenant prevents saved work from
225
+ restoring it. Input does not call `keep()` implicitly. A confirmed missing member
226
+ raises `TenantUnknownError` with the complete tenant ID and context name; native
227
+ services return `NotFound` with a structured `spine.base.Error` detail whose type
228
+ is `TENANT_UNKNOWN`. Lookup failures remain operational errors. Single-tenant
229
+ work does not consult the directory.
230
+
167
231
  To override the default channel factory, add
168
232
  `integrationChannelFactory: customFactory` to the same settings object.
169
233
 
@@ -265,8 +329,8 @@ callbacks receive that scope as their third argument while they run.
265
329
 
266
330
  For contexts registered with one `Server`, the target Entity's type URL selects
267
331
  its context. No context name or network request is required. The Server rejects
268
- duplicate Entity type registrations before starting delivery recovery or
269
- listening, identifying the type and both contexts. Contexts used without a
332
+ duplicate Entity type registrations before opening the listener, identifying
333
+ the type and both contexts. Contexts used without a
270
334
  Server retain local querying; separate Servers do not share query routes.
271
335
 
272
336
  Cross-context targets must declare `query` or `full` visibility. This applies
@@ -282,9 +346,11 @@ partition in a multitenant destination. The query never replaces the tenant to
282
346
  suit the target. A valid query with no matching record keeps its ordinary empty
283
347
  result (`undefined` from `findById()`). Reads remain eventually consistent.
284
348
 
285
- Routes are available before recovered handlers execute. Server shutdown drains
286
- accepted handlers across contexts before closing any target read-side; failed
287
- startup validation participates in context and resource cleanup.
349
+ Routes are available before ordinary Inbox work resumes. An accepted Agent
350
+ interaction never resumes after interruption; a fresh signal starts fresh work.
351
+ Server shutdown drains admitted handlers across contexts before closing any
352
+ target read-side; failed startup validation participates in context and
353
+ resource cleanup.
288
354
 
289
355
  ```ts
290
356
  import type { Message } from "@bufbuild/protobuf";
@@ -506,7 +572,7 @@ const repository = new Repository<typeof ApprovalCoordinator>({
506
572
  schema: CoordinationStateSchema,
507
573
  handlers: handlers as EntityHandlersMetadata<ApprovalCoordinator, typeof CoordinationStateSchema>,
508
574
  });
509
- const context = BoundedContext.singleTenant("Projects").add(repository).build();
575
+ const context = await BoundedContext.singleTenant("Projects").add(repository).build();
510
576
  await context.commandBus().post(
511
577
  SignalEnvelopes.command({
512
578
  context: create(CommandContextSchema),
@@ -519,9 +585,8 @@ await context.commandBus().post(
519
585
  The generated record declares `ApproveProjectSchema` as the input and
520
586
  `ScheduleProjectSchema` as the emitted Command schema; registry ingestion, not
521
587
  manual decorator materialization, constructs the output-bearing metadata.
522
- Application builds emit the record to
523
- `generated/handler/generated-handler-registry.js`; those applications use
524
- `buildAsync()` with their compiled package root.
588
+ Application builds emit the record to `generated/spine-metadata.js` and import
589
+ `generated/spine-bootstrap.js` before `build()` selects registered classes.
525
590
 
526
591
  One `@Where({ eventField, equals })` equality filter may narrow an event- or
527
592
  rejection-consuming `@Subscribe`, `@React`, or `@Command` handler after type
@@ -531,18 +596,24 @@ repeated declarations fail closed. It is not an alternative routing mechanism.
531
596
  Configure logging through `ServerEnvironment` when assembling the server. The
532
597
  server installs that logger into its runtime components, where warnings and
533
598
  failures carry operation context. Durable facts belong in events or storage.
534
- Entity Inbox replay sends persisted accepted work through the normal handler
535
- path, so handler effects must be replay-safe.
599
+ Ordinary Aggregate, Process Manager, and Projection Inbox replay sends persisted
600
+ accepted work through the normal handler path, so those handler effects must be
601
+ replay-safe. An accepted Agent interaction is recorded by its receipt and is
602
+ never re-executed after interruption.
536
603
 
537
604
  ## Context assembly and entities
538
605
 
539
606
  Create a context with `BoundedContext.singleTenant(name)` or
540
607
  `BoundedContext.multitenant(name)`. Names are immutable. Use
541
- `withStorageFactory(factory)` to supply record/event storage.
542
- `withGeneratedRegistryRoot(root)` enables framework discovery of the generated
543
- handler registry for classes registered with `add(EntityClass)`;
544
- `buildAsync()` performs that discovery and assembly. `build()` remains for
545
- explicit `Repository` registration. A built context contains `CommandBus`,
608
+ `ServerEnvironment.when(type).use({ storageFactory: factory })` before explicit
609
+ environment setup to supply record/event storage to all contexts.
610
+ `withTenantIndex(index)` selects a different live membership directory for one
611
+ context; `context.tenantIndex` and `ServerEnvironment.instance().tenantIndex`
612
+ return the configured objects. Closing a context does not close either index.
613
+ The application imports its generated `spine-bootstrap.js` before registering
614
+ classes with `add(EntityClass)`; `build()` then selects passive descriptions
615
+ by exact constructor and performs assembly, including
616
+ explicit `Repository` registration. Await it before using the context. A built context contains `CommandBus`,
546
617
  `EventBus`, `Stand`, repositories, and its storage lifecycle.
547
618
  Trusted server-side code can call `context.getRepository(EntityClass)` to obtain
548
619
  the already registered repository for that exact constructor. The lookup does
@@ -559,13 +630,12 @@ registry shapes with an instruction to regenerate.
559
630
  Each built context also has one `StandSubscriptionRegistry`. By default the
560
631
  builder creates a storage-backed registry from the resolved context
561
632
  `StorageFactory` (including the `ServerEnvironment` factory used for a builder
562
- added to a server). It stores one `spine.client.SubscriptionRecord` under each
633
+ added to a server). Its physical `StorageGroup` derives from the logical Bounded Context name, so two contexts using one factory keep distinct definitions. An injected `StorageSubscriptionRegistry` takes an explicit group as its third constructor argument and prepares its captured factory and context. It stores one `spine.client.SubscriptionRecord` under each
563
634
  explicit `SubscriptionId`. A complete custom implementation can instead be
564
635
  supplied with `withSubscriptionRegistry(registry)`; responsibility transfers to
565
636
  the builder on the first build attempt.
566
637
 
567
- `SubscriptionService` streams are live best-effort notifications, not replay,
568
- ordering, or completeness contracts. A standalone Server defaults to the
638
+ `SubscriptionService` streams are live notifications. Each subscriber receives its admitted filtered updates in order, but there is no replay, exactly-once, or cluster-wide completeness guarantee. A standalone Server defaults to the
569
639
  persistent registry. In a group of managed server replicas, the framework starts
570
640
  and closes each child Server and accepts only every context's actual
571
641
  `InMemorySubscriptionRegistry`; a persistent or custom registry is rejected
@@ -573,7 +643,12 @@ and the assembled child is closed before READY. Durable logical bindings remain
573
643
  Gateway-only. The Coordinator fans each logical definition to ready children,
574
644
  merges updates, propagates cancellation, and carries no subscription payload on
575
645
  parent/child IPC. A late or replacement child synchronizes retained definitions
576
- before it is eligible for normal requests. Active definitions attach their
646
+ before it is eligible for normal requests. The Coordinator resolves the same
647
+ `subscriptionQueueCapacity` before binding its HTTP/2 listener. Its activation
648
+ ACK is separate from the update queue, which reserves one active DATA update
649
+ plus the configured waiting count for each logical subscriber. Overflow closes
650
+ that subscriber's relay and aborts its child streams.
651
+ Active definitions attach their
577
652
  child streams before admission; subscribed but inactive definitions do not
578
653
  block readiness. Each child observes application-configured remote/shared
579
654
  Delivery directly. During DRAINING, new unary and shard admission stops while
@@ -606,12 +681,21 @@ completed cycle. This is best-effort per-node convergence, not a
606
681
  cluster-completeness, replay, ordering, gap-repair, or exactly-once guarantee.
607
682
 
608
683
  The registry accepts only a generated `SubscriptionId` for activate, get, and
609
- delete. `create(subscription)` returns `{ kind: "created", entry }` or
684
+ delete. `create(subscription, reader?)` returns `{ kind: "created", entry }` or
610
685
  `{ kind: "existing", entry }`; the latter requires byte-equivalent canonical
611
- content and a different definition with the same ID throws `StandConflictError`.
612
- `activate(id)` returns `activated`, `active`, `missing`, or `expired`.
613
- `delete(id)` returns `deleted` or `missing`. Blank IDs or topics and malformed
614
- durable records fail closed.
686
+ content and the same reader binding. A different definition or binding with the
687
+ same ID throws `StandConflictError`. `activate(id, reader?)` returns `activated`,
688
+ `active`, `missing`, `expired`, or `denied`. `delete(id, reader?)` returns `deleted`,
689
+ `missing`, or `denied`. Blank IDs or topics and malformed durable records fail closed.
690
+
691
+ Service requests always supply the admitted principal ID or an explicit anonymous
692
+ binding. When supplied, the registry checks the binding again after every failed
693
+ compare-and-set, before changing a reread record. The omitted argument is for
694
+ trusted internal lifecycle work; it is not a way to admit an unauthenticated RPC.
695
+ Reader identity is stored atomically with the subscription definition and phase.
696
+ Attributes, authority facts, and credentials are not part of the stored identity.
697
+ A missing legacy binding is not anonymous and cannot be claimed by a caller;
698
+ the client must create a new subscription.
615
699
 
616
700
  Entries and nested subscriptions returned by create, activate, get, and
617
701
  snapshot are clone-safe views. Protobuf byte arrays remain mutable runtime
@@ -654,24 +738,24 @@ start a new autonomous Entity loop.
654
738
  ### Configuration
655
739
 
656
740
  Register a factory-created `AiRegistry`, enable `persistSystemEvents()`, and
657
- configure `agentCodeRevision` plus `ai.models` for each Agent repository. Use
741
+ configure `ai.models` for each Agent repository. Use
658
742
  an empty `models` array when that Agent has no model calls. Readiness requires
659
- indexed Agent history and execution storage from the selected provider.
743
+ indexed Agent history and atomic live Agent commits from the selected provider.
660
744
  The [Support Bounded Context](../../examples/support/src/index.ts) uses generated
661
745
  registration with these options.
662
746
 
663
747
  Configuration has these scopes:
664
748
 
665
- | Scope | Setting | Effect |
666
- | --------------- | ---------------------------------------- | ------------------------------------------------------------------------ |
667
- | Server | `Server.withAi(registry)` | Default registry for Bounded Context builders assembled by that server. |
668
- | Bounded Context | `BoundedContextBuilder.withAi(registry)` | Explicit registry replacing the server default for that Bounded Context. |
669
- | Repository | `ai.defaultModels` | Generation and decision defaults before the registry's defaults. |
670
- | Repository | `ai.allowedModels` | Deployment references the Agent may use. |
671
- | Repository | `ai.resolveModel` | Optional accepted-source choice before the Agent handler. |
672
- | Repository | `ai.authorizeSelection` | Authorizes explicit choices and staged preference changes. |
673
- | Repository | `ai.invocationLimits` | Limits that can narrow the registry's whole-signal limits. |
674
- | Instance | `this.ai.select(kind, ref)` | A saved preference applied to later accepted signals. |
749
+ | Scope | Setting | Effect |
750
+ | --------------- | ------------------------------------------ | ---------------------------------------------------------------- |
751
+ | Environment | `ServerEnvironment.when(type).use({ ai })` | Default registry for Bounded Contexts. |
752
+ | Bounded Context | `BoundedContextBuilder.withAi(registry)` | Overrides environment AI for one Bounded Context. |
753
+ | Repository | `ai.defaultModels` | Generation and decision defaults before the registry's defaults. |
754
+ | Repository | `ai.allowedModels` | Deployment references the Agent may use. |
755
+ | Repository | `ai.resolveModel` | Optional accepted-source choice before the Agent handler. |
756
+ | Repository | `ai.authorizeSelection` | Authorizes explicit choices and staged preference changes. |
757
+ | Repository | `ai.invocationLimits` | Limits that can narrow the registry's whole-signal limits. |
758
+ | Instance | `this.ai.select(kind, ref)` | A saved preference applied to later accepted signals. |
675
759
 
676
760
  A prebuilt Bounded Context already has its registry; adding it to a server does not
677
761
  reconfigure it. An instance preference takes precedence over its repository
@@ -687,7 +771,7 @@ signal; `undefined` preserves it. This allows an Agent without a configured
687
771
  default to start after a deployment is appended to the bound registry. The
688
772
  runtime checks repository allowlists, capabilities and `authorizeSelection`
689
773
  before saving the selection and connection identity. A saved selection is reused
690
- on continuation. Resolver and authorization callbacks receive linked cancellation
774
+ for the current signal. Resolver and authorization callbacks receive linked cancellation
691
775
  and the smaller of the invocation deadline and registry hook timeout. An
692
776
  effective `this.ai.select()` change, including reset to inheritance, is
693
777
  authorized before the Entity transition and preference Events commit; a no-op
@@ -702,60 +786,30 @@ See [adapter configuration](../ai-vercel-ax/README.md).
702
786
 
703
787
  ### Acceptance and completion
704
788
 
705
- Before acknowledging Agent intake, the runtime saves the original signal,
706
- recipient, selected handlers and code/schema/policy revisions. The scheduler
707
- processes one accepted signal at a time per Agent instance, under a provider
708
- claim. Different instances can run concurrently within configured limits.
709
- Bounded Contexts using the same registry object share its capacity within the process.
710
- Signals beyond the bounded in-memory waiting queue remain durably pending.
711
- Waiting before a fresh execution starts precedes its deadline. Once execution
712
- starts, recovery continues with the saved deadline and counts. The same deadline
713
- bounds an awaited application handler. Expiry or Bounded Context shutdown ends that wait
714
- and prevents late handler results from changing Entity state or emitting signals;
715
- it cannot stop arbitrary application JavaScript or undo external effects.
716
-
717
- Newly accepted work supplies its repository and tenant to prompt discovery.
718
- Periodic discovery reads tenant pages and constructs repository scopes as they
719
- are needed. It retains at most one page of 16 tenants, four periodic scan scopes,
720
- and 64 scopes awaiting a prompt scan. A turn requests at most one tenant page
721
- and reads at most four pending-work pages. It does not load the complete tenant
722
- catalog or retain a scan position for every tenant.
723
-
724
- A sweep finishes before another begins. The next starts no earlier than five
725
- seconds after the preceding sweep started, measured by `Time`; longer sweeps
726
- restart after completion. This lets discovery reach tenants near the end of a
727
- large catalog and find later admissions on the next sweep. Periodic scans keep
728
- their turn during new arrivals, including while execution capacity is full.
729
- A pending catalog request does not block prompt scans of known scopes.
730
-
731
- Bounded Context shutdown stops waiting for discovery reads even if a provider ignores
732
- cancellation. Late results cannot submit work or restart scanning. Built-in
733
- adapters use their available cancellation and timeout controls; detaching the
734
- scheduler does not guarantee cancellation of an already issued native request.
789
+ An accepted signal and recipient are admitted through ordinary Delivery. A
790
+ typed receipt prevents a duplicate signal from starting the same Agent turn.
791
+ Within one process, live capacity serializes turns for one Agent instance and
792
+ permits different instances up to configured limits. The shared registry's
793
+ capacity applies across Bounded Contexts using that registry. A waiting signal
794
+ stays in the ordinary Inbox until capacity can admit it; capacity release wakes
795
+ the ordinary Delivery worker. There is no Agent-specific discovery scheduler.
735
796
 
736
797
  The signal's matching handlers share one Entity draft. Each handler can await
737
- `this.ai.invoke()` through the protected Spine facade. Calls in one handler must
738
- be sequential and finish before it returns. Requests, results and
739
- validation failures are saved as the operation progresses. The final accepted
740
- state, Version, history and outgoing Command obligations are committed under the
741
- same execution claim. Emitted domain Events enter immutable Agent history but are
742
- not stored as delivery obligations. A no-op still completes its execution record. Waiting for
743
- a provider does not hold a database transaction open.
744
-
745
- Recovery compares the registered handler, schema and policy with accepted work.
746
- A saved named call can reuse its result; changing that call's input or prepared
747
- request is a mismatch, not a new attempt. Domain code should derive its decisions
748
- from accepted signals and recorded reads. Arbitrary external effects performed
749
- by handler code are outside the model/tool journal.
750
-
751
- After completion, emitted domain Events are handed once to the Bounded Context's
752
- normal EventBus. The Agent does not track Event recipients, retry a failed handoff,
753
- or replay Event delivery after restart. Immutable Agent history remains readable
754
- independently of EventBus delivery. Saved outgoing Commands retain their original
755
- IDs and recipient bindings for recovery without rerunning the producing handler
756
- or model. Generated repository and standalone Command receivers provide the
757
- required binding metadata; matching raw custom Command dispatchers without it
758
- are rejected.
798
+ `this.ai.invoke()` through the protected Spine facade. Calls in one handler
799
+ must be sequential and finish before it returns. Requests, results, and
800
+ validation failures are saved as audited history while work progresses. The
801
+ final accepted state, Version, preference changes, and Agent history use an
802
+ atomic live Agent commit. Outgoing Commands enter ordinary command delivery;
803
+ there is no saved Agent-private list to finish after a restart. Emitted domain Events
804
+ enter immutable Agent history before normal EventBus publication. A no-op or
805
+ preference-only turn can commit without a state Version increase. Waiting for a
806
+ provider does not hold a database transaction open.
807
+
808
+ An admitted turn uses a current session and cancellation guard. Shutdown drains
809
+ tracked work and prevents late results from changing Entity state or emitting
810
+ signals. It cannot undo external effects already performed by application code.
811
+ A restarted process can read retained receipts and audit history, but it does
812
+ not replay a model response or re-enter an interrupted Agent handler.
759
813
 
760
814
  ### Retained history
761
815
 
@@ -775,7 +829,7 @@ persistent provider when records must survive process termination.
775
829
  All methods return newest entries first. A request supplies positive `pageSize`
776
830
  and an optional opaque cursor; `nextCursor` continues toward older entries.
777
831
  There is no fixed 100-item or page-byte ceiling. Reads made during a handler count
778
- toward any configured invocation limits for recorded reads and recovery data. Ordering
832
+ toward any configured invocation limits for recorded reads. Ordering
779
833
  uses the full Spine `Time` timestamp, category and existing record ID. There is
780
834
  no repository-managed history counter. Cursors cannot be transferred across
781
835
  Agents, tenants, categories or conversations.
@@ -795,28 +849,36 @@ For a trusted application bridge, `context.getRepository(AgentClass)` returns
795
849
  the registered Agent `Repository`, which exposes
796
850
  `agentHistory(id, scope)` with the same four history methods and page contracts.
797
851
  The scope is explicit: pass `{}` in a single-tenant Bounded Context or
798
- `{ tenantId }` in a multitenant Bounded Context. The repository also exposes
799
- `agentExecution(id, sourceCommandOrEventId, scope)` for the exact recorded phase:
800
- `accepted`, `active`, `completed-pending-commands`, `completed`, or `terminated`.
801
- An absent record returns `undefined`; it does not establish completion. These
802
- reads use indexed storage without restoring an Agent. The application bridge
803
- must authorize access before calling either method; actor metadata does not
804
- grant read permission.
805
-
806
- If a selected model's `authorizeUse` callback explicitly returns `false` at
807
- Agent claim time, the execution becomes `terminated` with one
808
- `AgentInvocationTerminated` System Event carrying `MODEL_USE_DENIED`. No Agent
809
- handler runs and no application-domain result Event is emitted. Callback
810
- exceptions and infrastructure failures remain distinct from this denial.
852
+ `{ tenantId }` in a multitenant Bounded Context. Reads use indexed storage
853
+ without restoring an Agent. The application bridge must authorize access;
854
+ actor metadata does not grant read permission.
855
+ For a trusted in-process caller, the scope can also include detached
856
+ `actorContext`, a verified `reader` with principal and authority facts, and a
857
+ `signal`. Read-side filters receive those facts for that history call; omitting
858
+ `reader` leaves principal and authority facts absent. The bridge supplies
859
+ verified facts explicitly and cannot derive them from `actorContext`.
860
+
861
+ If a selected model's `authorizeUse` callback explicitly returns `false`
862
+ before the handler, the turn records one `AgentInvocationTerminated` System
863
+ Event carrying `MODEL_USE_DENIED`. No handler runs, no application-domain
864
+ result Event is invented, and other failures remain distinct. Applications
865
+ may correlate this fact with the original source through paged Agent history.
811
866
 
812
867
  ## Signals, validation, and rejection behavior
813
868
 
814
- `CommandBus` validates every accepted command from Proto validation options
815
- before dispatcher or repository handler code runs. It raises the framework's
816
- command-validation failure, which `SpineServices` maps to
817
- `COMMAND_VALIDATION_ERROR` with a packed `spine.validation.ValidationError`.
818
- Entity transition validation failures map to
819
- `COMMAND_STATE_TRANSITION_VALIDATION_FAILED` with the same detail type.
869
+ `CommandBus` checks the nonempty Command ID, nondefault message and context,
870
+ and declared payload constraints before admission or dispatcher code runs.
871
+ Annotated packed messages use generated Proto modules registered in the process.
872
+ `SpineServices` reports invalid Commands in an error Ack with type
873
+ `spine.core.CommandValidationError`, numeric `INVALID_COMMAND` code, and a
874
+ packed `spine.validation.ValidationError`. Unsupported Commands use the same
875
+ enum type and numeric `UNSUPPORTED_COMMAND` code.
876
+ Technical validator failures use a sanitized `COMMAND_POST_ERROR` Ack without
877
+ constraint details; they are distinct from invalid Command input.
878
+ Entity transition validation failures that escape service processing map to
879
+ `COMMAND_STATE_TRANSITION_VALIDATION_FAILED` with the same detail type. Managed
880
+ reception of ordinary Entity work sends post-handler transition rejection to `DeliveryMonitor`;
881
+ its default action acknowledges the failed input without storing invalid state.
820
882
  Framework-created runtime command and event metadata uses fresh Node secure
821
883
  UUIDs; fixed IDs belong only to existing source envelopes retained through the
822
884
  normal origin chain.
@@ -831,6 +893,8 @@ an internal diagnostic, not a retry guarantee.
831
893
  Every domain context has an internal paired System Context. Domain events use
832
894
  the domain `EventBus` and domain `EventStore`. System events use only the
833
895
  System Context `EventBus`, so they never enter the domain EventStore.
896
+ Each EventBus validates the Event envelope and domain payload before admission,
897
+ storage, or delivery.
834
898
  `persistSystemEvents()` enables the paired System Context's separate storage.
835
899
  Bounded Contexts with Agents must enable it. For other Bounded Contexts it is optional; without
836
900
  it, the bus validates, dispatches and notifies without appending. Schemas may come from an external dispatcher or
@@ -847,6 +911,204 @@ work to stop using dependencies, then closes contexts. Caller-managed `start()`
847
911
  does not close global process facilities; close `ServerEnvironment.instance()`
848
912
  separately when used. The final run-managed `run()` close closes its environment.
849
913
 
914
+ `ServerOptions.appQueries` selects concrete generated `AppQueryHandler<Q, R>`
915
+ instances by exact constructor metadata before listening. Duplicate Q routes
916
+ or missing metadata fail startup. On direct app-node ingress,
917
+ `QueryService.Execute` validates a complete AppQuery envelope and Q, then
918
+ returns one packed paired R. Native and browser Gateways and managed Coordinators
919
+ forward Execute to an app node; `ClientRequest.query(generatedQ)` decodes its paired R.
920
+ The internal
921
+ `Server.query(generatedQ, executionContext)` accepts a generated Q and returns
922
+ its paired generated R, using a detached request and the effective actor,
923
+ verified reader facts, and cancellation signal supplied by the current
924
+ framework invocation. `ProcessManager.currentActorContext` and
925
+ `Agent.currentActorContext` expose only the current signal's detached actor and
926
+ tenant during a handler; neither establishes a verified principal. Constructor
927
+ injection can bind the query function to a Server. Scoped Entity reads require
928
+ query/full visibility and destination tenant membership. Direct calls do not
929
+ cross the Server's gRPC output-filter boundary.
930
+
931
+ `ReadSideFilter<typeof MessageSchema>` declares a typed policy for a registered
932
+ Proto message. Its protected constructor takes the generated schema and optional
933
+ `{ nested: true }`; `filter(message, context)` receives a detached mutable value
934
+ and may return the same type or `null` to remove that occurrence. The context
935
+ separates actor metadata from verified reader facts and identifies the current
936
+ operation, plus a detached containing message and field for nested calls.
937
+ Read-only packed bytes remain available to Buf decoding through a detached
938
+ `value.slice()` passed to `fromBinary`.
939
+ Call `addReadSideFilter(filter)` on a `BoundedContextBuilder` before `build()` to apply it to that
940
+ Bounded Context's outward Entity reads and retained histories. Pass `readSideFilters`
941
+ to `new Server(...)` to apply policies to Entity Query and App Query results
942
+ leaving that Server over gRPC. The same instance can be installed in both
943
+ places; each boundary invokes it once. Direct `Server.query()` runs BC source
944
+ policies but does not cross the Server output boundary. An Entity root returned
945
+ as `null` is omitted without another storage read; an App Query root returned
946
+ as `null` produces OK with zero outer `AppQueryResponse.message` entries. A
947
+ non-null response whose child field is absent remains one response entry.
948
+ History removals retain the
949
+ original continuation. Retained storage, hydration, and replay remain raw.
950
+ Direct Stand and retained-history callbacks identify the producing Bounded
951
+ Context. Protected history called from a handler carries its current signal
952
+ actor; an out-of-handler diagnostic read has no actor or authenticated reader.
953
+ Native SubscriptionService delivery filters already matched Entity states and
954
+ Event payloads through the producing Bounded Context policy and then the
955
+ Server policy. The `subscription` operation includes the original Topic and
956
+ admitted subscription; its context carries the current verified reader facts,
957
+ effective tenant, actor metadata, producing Bounded Context, and cancellation
958
+ signal. Removing a state emits `no_longer_matching` with its original Entity
959
+ ID; removing every Event payload suppresses that data batch. ACKs and existing
960
+ removal controls remain unchanged. Policy failures end only that reader stream
961
+ with a sanitized technical status.
962
+
963
+ The operation describes the call that produced the value. `query` includes the
964
+ actual Query and, during an App Query child read, the enclosing AppQuery. `app-query`
965
+ identifies the final application result. `direct` identifies either a typed
966
+ Stand state read by type URL and Entity ID, a caller-supplied RecordQuery, or a
967
+ normalized query plan. `history` distinguishes an Entity state-at timestamp,
968
+ Entity state/Event history depth, and an Agent view with its page request and
969
+ optional cursor. Direct callers supply actor metadata, verified reader facts,
970
+ and cancellation separately; they cannot override the operation.
971
+ Direct subscription delivery uses `kind: "direct"` with
972
+ `operation.subscription.typeUrl`, distinct from a one-off Stand read's
973
+ `operation.read`.
974
+
975
+ This filter uses the generated Project state and can be installed on the Bounded
976
+ Context builder that contains its Repository:
977
+
978
+ <!-- docs-snippet-path: packages/server/test/server/app-query-execution.test.ts -->
979
+
980
+ ```ts
981
+ import {
982
+ type BoundedContextBuilder,
983
+ ReadSideFilter,
984
+ type ReadSideContext,
985
+ } from "@spine-event-engine/server";
986
+ import {
987
+ type ProjectOverviewState,
988
+ ProjectOverviewStateSchema,
989
+ } from "../../test-fixtures/generated/repository-routing/project_states_pb.js";
990
+
991
+ /**
992
+ * Replaces a project name in all ordinary Entity Query results.
993
+ */
994
+ class PublicProjectName extends ReadSideFilter<typeof ProjectOverviewStateSchema> {
995
+ /**
996
+ * Registers the filter for project overview state.
997
+ */
998
+ constructor() {
999
+ super(ProjectOverviewStateSchema);
1000
+ }
1001
+
1002
+ /**
1003
+ * Replaces the name only for ordinary Entity Query responses.
1004
+ *
1005
+ * @param state Project overview returned by the read side.
1006
+ * @param context Describes the read operation and verified reader.
1007
+ * @returns The project overview with its name replaced for ordinary Entity Queries.
1008
+ */
1009
+ filter(state: ProjectOverviewState, context: ReadSideContext): ProjectOverviewState {
1010
+ if (context.operation.kind === "query") state.name = "Public project";
1011
+ return state;
1012
+ }
1013
+ }
1014
+
1015
+ const projectPolicy = new PublicProjectName();
1016
+
1017
+ /**
1018
+ * Registers the project name policy in its supplying Bounded Context.
1019
+ *
1020
+ * @param builder Configures the project Bounded Context.
1021
+ * @returns The builder with the read policy installed.
1022
+ */
1023
+ function installProjectPolicy(builder: BoundedContextBuilder): BoundedContextBuilder {
1024
+ return builder.addReadSideFilter(projectPolicy);
1025
+ }
1026
+ ```
1027
+
1028
+ The repository `onCreate` callback can inject `(q, context) => server.query(q, context)`
1029
+ into a Process Manager or Agent. Within an active handler, pass a generated Q
1030
+ with `{ actorContext: this.currentActorContext }`; the actor/tenant snapshot
1031
+ does not supply verified principal or provider facts. The
1032
+ [scoped integration test](https://github.com/SpineEventEngine/spine-ts/blob/master/packages/server/test/entity/process-manager-querying.test.ts) includes
1033
+ the full callback and handler invocation.
1034
+
1035
+ This example uses the generated Project query and the current Process Manager
1036
+ scope; pass `scopedOnCreate(server)` as the repository's `onCreate` callback.
1037
+ Ordinary generation and bootstrap register the decorated handler description:
1038
+
1039
+ <!-- docs-snippet-path: packages/server/test/entity/process-manager-querying.test.ts -->
1040
+
1041
+ ```ts
1042
+ import { create } from "@bufbuild/protobuf";
1043
+ import {
1044
+ Assign,
1045
+ ProcessManager,
1046
+ type EntityOptions,
1047
+ type Server,
1048
+ type ServerQueryExecutionContext,
1049
+ } from "@spine-event-engine/server";
1050
+ import { ProcessManagerStateSchema } from "../../test-fixtures/generated/entity-metadata/visibility_pb.js";
1051
+ import { ProjectIdSchema } from "../../test-fixtures/generated/repository-routing/project_identifiers_pb.js";
1052
+ import {
1053
+ type ProjectCreated as ProjectionEvent,
1054
+ ProjectCreatedSchema as ProjectionEventSchema,
1055
+ } from "../../test-fixtures/generated/repository-routing/project_events_pb.js";
1056
+ import { type CreateReviewProject } from "../../test-fixtures/generated/validation-refusal/project_commands_pb.js";
1057
+ import {
1058
+ type GetProjectOverview_Query,
1059
+ type GetProjectOverview_Response,
1060
+ } from "../../test-fixtures/generated/repository-routing/project_queries_pb.js";
1061
+ import { GetProjectOverview } from "../../test-fixtures/generated/repository-routing/project_queries_app_query.js";
1062
+
1063
+ /**
1064
+ * Runs a typed App Query from an active Process Manager handler.
1065
+ */
1066
+ class ScopedAppQueryManager extends ProcessManager<string, typeof ProcessManagerStateSchema> {
1067
+ /**
1068
+ * Captures the scoped query callback supplied during repository construction.
1069
+ *
1070
+ * @param options Configures this Process Manager instance.
1071
+ * @param ask Executes a generated App Query with trusted handler context.
1072
+ */
1073
+ constructor(
1074
+ options: EntityOptions<string, typeof ProcessManagerStateSchema>,
1075
+ private readonly ask: (
1076
+ query: GetProjectOverview_Query,
1077
+ context: ServerQueryExecutionContext,
1078
+ ) => Promise<GetProjectOverview_Response>,
1079
+ ) {
1080
+ super(options);
1081
+ }
1082
+
1083
+ /**
1084
+ * Reads the current project overview while handling the creation Command.
1085
+ *
1086
+ * @param command Project creation request being assigned.
1087
+ * @returns Event carrying the selected overview name.
1088
+ */
1089
+ @Assign
1090
+ async assign(command: CreateReviewProject): Promise<ProjectionEvent> {
1091
+ const result = await this.ask(
1092
+ create(GetProjectOverview.querySchema, {
1093
+ project: create(ProjectIdSchema, { value: command.id }),
1094
+ }),
1095
+ { actorContext: this.currentActorContext },
1096
+ );
1097
+ return create(ProjectionEventSchema, {
1098
+ id: command.id,
1099
+ name: result.project?.name ?? "",
1100
+ });
1101
+ }
1102
+ }
1103
+
1104
+ /**
1105
+ * Injects the Server's typed App Query route into new Process Manager instances.
1106
+ */
1107
+ export const scopedOnCreate =
1108
+ (server: Server) => (options: EntityOptions<string, typeof ProcessManagerStateSchema>) =>
1109
+ new ScopedAppQueryManager(options, (q, context) => server.query(q, context));
1110
+ ```
1111
+
850
1112
  `Stand` registers entity state for point/list reads, updates current state, and
851
1113
  offers in-process subscriptions. The legacy-named local reset/replay helper
852
1114
  `catchUpReadSide(options?)` clears every registered Projection state and replays
@@ -877,8 +1139,57 @@ authoritative queries from current state and Entity subscriptions observe
877
1139
  committed `EntityStateChanged` messages on the paired System Context EventBus,
878
1140
  so a direct Stand write alone does not produce a subscription update. Consumer
879
1141
  callback failures are isolated from post-commit observation and other
880
- consumers. The package does not guarantee cluster-complete observations,
881
- subscription replay, event-gap repair, or exactly-once effects.
1142
+ consumers. Native subscription updates enter the existing bounded delivery
1143
+ queue before asynchronous read policies run; a full queue closes that stream.
1144
+ For a surviving Event, policy replaces only its domain payload and retains the original envelope.
1145
+ Direct `Stand.subscribe(schema, { next, error }, options)` applies only its
1146
+ producing Bounded Context's read policies, independently for each local
1147
+ subscriber. `next` receives either `{ kind: "state", state, previousState? }`
1148
+ or `{ kind: "removal", noLongerMatching: true }`; both retain the original type
1149
+ URL, Entity ID, version, and tenant metadata. A removed prior state is omitted
1150
+ from a surviving current state. `error` receives one terminal local policy,
1151
+ callback, or capacity fault. There is no raw callback overload. Options accept
1152
+ trusted `reader` facts, `actorContext` metadata, tenant, and cancellation;
1153
+ `ServerEnvironmentSettings.subscriptionQueueCapacity` sets the waiting count
1154
+ for direct and server-served subscriptions. Configure it before constructing
1155
+ the Stand or Bounded Context. It defaults to 100 waiting updates in addition to
1156
+ one active update; zero allows the active update with no waiting updates. Filter calls
1157
+ and `next` completion are sequential per subscriber. Overflow closes only that
1158
+ subscriber, clears waiting updates, invalidates the active result, and reports
1159
+ `StandSubscriptionCapacityError`; committed writes and other subscribers
1160
+ continue. Unsubscribe, cancellation, and Stand close invalidate outstanding
1161
+ results without waiting for a nonsettling policy. A producer does not await
1162
+ asynchronous policy or observer completion, although CPU-heavy synchronous
1163
+ policy work still runs on the producer's Node event loop.
1164
+ Direct subscribers do not cross a Server output-filter boundary. The package
1165
+ does not guarantee cluster-complete observations, subscription replay,
1166
+ event-gap repair, or exactly-once effects.
1167
+
1168
+ This typed local observer handles visible states, removals, and terminal faults.
1169
+ Configure `subscriptionQueueCapacity: 250` through `ServerEnvironment.when(...).use(...)`
1170
+ before creating the Stand to allow 250 waiting updates beyond the active one:
1171
+
1172
+ <!-- docs-snippet-path: packages/server/test/stand/stand-direct-subscription.test.ts -->
1173
+
1174
+ ```ts
1175
+ import { type Stand, type StandSubscription } from "@spine-event-engine/server";
1176
+ import { ProjectOverviewStateSchema } from "../../test-fixtures/generated/repository-routing/project_states_pb.js";
1177
+
1178
+ export function observeProjects(
1179
+ stand: Stand,
1180
+ onState: (name: string) => void,
1181
+ onRemoval: (id: unknown) => void,
1182
+ onError: (error: Error) => void,
1183
+ ): StandSubscription {
1184
+ return stand.subscribe(ProjectOverviewStateSchema, {
1185
+ next(update) {
1186
+ if (update.kind === "state") onState(update.state.name);
1187
+ else onRemoval(update.id);
1188
+ },
1189
+ error: onError,
1190
+ });
1191
+ }
1192
+ ```
882
1193
 
883
1194
  ### Native and managed hosting
884
1195
 
@@ -948,6 +1259,48 @@ gRPC-Web transport message accepted by the public listener, so the effective
948
1259
  inbound limit is the stricter applicable limit. `writeMaxBytes` limits public
949
1260
  transport responses independently.
950
1261
 
1262
+ ### Native reader admission
1263
+
1264
+ Configure app-node admission at `ServerOptions.services.readerAdmission`:
1265
+
1266
+ - `direct.authenticate({ service, method, value, headers, peer })` authenticates
1267
+ a direct native request. It returns verified `{ principal, authorityFacts }`,
1268
+ an empty object for deliberate public access, or `undefined` to deny access.
1269
+ The request value contains canonical Proto bytes; `peer` is the Connect
1270
+ `HandlerContext` for that invocation.
1271
+ - `forwarded.verify(bytes, proof, peer)` verifies an assertion from a trusted
1272
+ forwarding peer. It must authenticate that peer and validate the supplied
1273
+ proof over the exact bytes. `BrowserServerOptions.forwardingProof.issue(bytes)`
1274
+ supplies the corresponding gateway adapter.
1275
+
1276
+ Admission completes before service validation, routing, or subscription mutation.
1277
+ Principal IDs and authority facts are copied per invocation. `principal.attributes`
1278
+ remains a string map; `authorityFacts` accepts finite JSON values, including
1279
+ arrays and nested objects. ActorContext remains separate from authentication.
1280
+ Neither the framework nor these ports promise live provider information.
1281
+
1282
+ With no admission adapters, native requests remain public. Internal identity
1283
+ headers are still rejected without a configured verifier. With a forwarding
1284
+ verifier but no direct adapter, a request without a forwarding assertion is
1285
+ rejected as unauthenticated. An application that also permits public direct
1286
+ requests can explicitly return an empty reader from its direct adapter.
1287
+ Malformed assertions and denied authentication return `UNAUTHENTICATED`;
1288
+ unexpected adapter faults return sanitized `INTERNAL`. Explicit cancellation,
1289
+ availability, and permission statuses retain their meaning.
1290
+
1291
+ `ManagedServerApplication` accepts `readerAdmission` for its Coordinator listener
1292
+ and `forwardingProof` for Coordinator-to-child requests. Configure the receiving
1293
+ child Servers with their verifier as well. Each hop verifies its incoming
1294
+ assertion and issues a new proof for the actual outgoing operation and payload.
1295
+ Loopback placement alone does not authenticate a forwarding peer.
1296
+
1297
+ Authenticated forwarding now requires an issuer; configure both gateway and
1298
+ receiving node when updating an existing authenticated deployment. The native
1299
+ Server root still does not load the optional auth package. The forwarding ports
1300
+ do not make a JVM endpoint understand the TS internal reader assertion.
1301
+
1302
+ ### Browser hosting
1303
+
951
1304
  For `BrowserServer` from `@spine-event-engine/server/browser`, origins must be unique canonical HTTP(S) origins with no path, query,
952
1305
  fragment, or trailing slash. Requests without an allowed exact `Origin` receive
953
1306
  403 before RPC handling. Allowed responses include credentialed exact-origin
@@ -1010,7 +1363,11 @@ never returns private native data through public subscription responses.
1010
1363
  The durable registry preserves one approved `GatewayAuthenticatedSubscription`
1011
1364
  per public subscription through a process restart. It validates the record ID,
1012
1365
  full Subscription, and expiry before use. The trusted Actor and Tenant remain
1013
- inside the stored Topic and are checked for Activate and Cancel. Create assigns
1366
+ inside the stored Topic; a stable principal ID is stored beside it. Activate and
1367
+ Cancel check the newly admitted reader and Actor/Tenant before stream effects
1368
+ or record mutation. Changed authority facts do not change the principal ID.
1369
+ An explicit anonymous binding remains distinct from missing legacy identity;
1370
+ records with missing identity cannot be claimed by a caller. Create assigns
1014
1371
  the public ID directly; no quota, reservation, fingerprint, or lease is
1015
1372
  persisted. Cleanup remains bounded and restart-safe at the record level. It
1016
1373
  cleans the backend definition before deleting its record. It is not a cleaner
@@ -1021,7 +1378,9 @@ delivery, global update ordering, nor cluster-complete notification delivery.
1021
1378
  ## Delivery and environment
1022
1379
 
1023
1380
  `Inbox`, `InboxStorage`, `ShardIndex`, and `ShardedWorkRegistry` provide the
1024
- local durable-row abstraction. Read limits are 1–1000; work leases are
1381
+ local durable-row abstraction. Inbox and shard storage require a single-tenant
1382
+ Delivery storage context shared by all tenants; the packed signal supplies
1383
+ the dispatch tenant. Read limits are 1–1000; work leases are
1025
1384
  1000–2147483647 ms. Framework replay supports command handling, projection
1026
1385
  updates, and process-manager reactions. Callbacks are at-least-once/replay-safe:
1027
1386
  lost renewal can prevent stale finalization but cannot undo a callback already
@@ -1059,24 +1418,53 @@ without an atomic compare-and-delete guarantee from this client. Pending,
1059
1418
  retryable, non-delivered, and still-protected rows are skipped by cleanup. There
1060
1419
  is no additional retention configuration, timer, or scheduler.
1061
1420
 
1062
- `BoundedContextBuilder.withDeliveryStrategy(strategy)` snapshots a validated
1063
- immutable strategy for its Entity Inbox; the default is one shard. For example,
1064
- use the public builder chain:
1421
+ Configure one Delivery strategy for the environment before setup. It maps
1422
+ targets to shards across all contexts; the default is one shard. For example:
1065
1423
 
1066
1424
  ```ts
1067
- import { BoundedContext, UniformAcrossAllShards } from "@spine-event-engine/server";
1425
+ import {
1426
+ BoundedContext,
1427
+ EnvironmentType,
1428
+ ServerEnvironment,
1429
+ UniformAcrossAllShards,
1430
+ } from "@spine-event-engine/server";
1068
1431
 
1069
- const context = BoundedContext.singleTenant("Tasks")
1070
- .withDeliveryStrategy(UniformAcrossAllShards.forNumber(3))
1071
- .build();
1432
+ ServerEnvironment.when(EnvironmentType.Local).use({
1433
+ deliveryStrategy: UniformAcrossAllShards.forNumber(3),
1434
+ });
1435
+ await ServerEnvironment.instance().completeSetup();
1436
+ const context = await BoundedContext.singleTenant("Tasks").build();
1072
1437
  ```
1073
1438
 
1074
1439
  Aggregate commands and Process Manager or Agent commands/events derive their target shard
1075
1440
  internally and persist their envelope in the target Entity Inbox before any
1076
- handler runs. Local intake can directly drain the persisted Inbox in the
1077
- current request path. Attached `ServerEnvironment` ports acknowledge admission
1078
- and delivery workers replay it through the same path. Projection rows remain
1079
- separate.
1441
+ handler runs. Projection input uses the same environment Delivery and shared
1442
+ Inbox, with its separate recipient identity.
1443
+
1444
+ Local posting waits for the result of that signal's delivery attempt. For an
1445
+ Agent, successful acceptance and Inbox acknowledgement let posting finish while
1446
+ the live handler continues. If Agent execution capacity is unavailable, the input
1447
+ stays pending and the local call reports the existing command-posting error.
1448
+
1449
+ With remote Delivery and its environment supervisor, posting completes after the
1450
+ remote Inbox accepts the input and the shard notification is submitted. Processing
1451
+ may still be pending on another process. For example, importing an Event can return
1452
+ while another process holds its shard; the Projection update arrives after that
1453
+ process can dispatch the Event. Reception alone does not acknowledge delivery,
1454
+ create an Agent acceptance receipt, or prove that a handler ran.
1455
+
1456
+ A rejected remote receive operation rejects posting. If a local notification
1457
+ observer fails after reception succeeds, the failure is logged and the existing
1458
+ notifications and safety scan can find the pending work. The environment selects
1459
+ this behavior from its installed supervision; contexts have no attachment step or
1460
+ completion switch. Supplying custom ports without a source does not install remote
1461
+ supervision. Explicit `Delivery.run()` still returns the actual run result,
1462
+ including `SKIPPED` when another process is handling the shard.
1463
+ For ordinary Entity Inbox work, post-handler output and transition validation
1464
+ failures reach the reception monitor. Pre-handler input and routing errors and
1465
+ storage failures remain outside that monitor. Accepted Agent work has already
1466
+ acknowledged its Inbox row and does not enter this reception action. A detached
1467
+ run that throws emits a contained terminal error without exposing its message.
1080
1468
 
1081
1469
  `DeliveryBuilder` constructs a controlled `Delivery`; `DeliverySupervisor`
1082
1470
  receives `{ source, delivery, onMessage }`, manages bounded shard notifications
@@ -1141,33 +1529,33 @@ work, and then closes buses, subscriptions, Stands, and repository bindings.
1141
1529
  Cleanup failures are aggregated and may be retried. A committed Entity Event,
1142
1530
  reactor or Process Manager Event, and System Event receives one first-publication
1143
1531
  attempt; a contained failure is logged and does not schedule publication again.
1144
- Persisted System Events use a separate fixed storage group. Command acceptance
1532
+ Persisted System Events use a storage group derived from their System Context
1533
+ name and role, separate from domain Event history. Command acceptance
1145
1534
  alone does not promise recipient completion. Processing retries for Inbox rows
1146
1535
  and acknowledgement recovery remain separate Delivery behavior.
1147
1536
 
1148
1537
  `Environment` resolves the Node `local` or `production` profile once from
1149
1538
  `NODE_ENV`. `ServerEnvironment` resolves configured facilities once for that
1150
- profile and exposes its `storageFactory`, optional `delivery`, optional
1151
- `tracerFactory`, `nodeId`, and `close()` lifecycle. Applications do
1152
- not manage internal server attachments through this public API. Neither API
1153
- authenticates requests or supplies a production scheduler, remote topology,
1154
- storage adapter, or deployment policy.
1155
-
1156
- `ServerEnvironmentDelivery` extends the existing closeable facility shape with
1157
- `open()` plus generic `inbox` and `workRegistry` ports. After readiness, the
1158
- environment supplies those ports to both existing delivery paths: direct finite
1159
- `Delivery` construction and the supervisor's `DeliveryBuilder`. The environment
1160
- invokes `open()` once before attachment admission and coalesces concurrent
1161
- callers; rejection admits no attachment and a later attempt retries open. A
1162
- close-only local delivery remains source-compatible. After attachments retire,
1163
- environment close runs delivery, tracer, then storage and preserves retry
1164
- checkpoints for failed phases.
1165
-
1166
- `ServerEnvironmentDelivery.source` is optional. When present, its Admin source
1167
- is used by the environment supervisor for remote snapshots and
1168
- shard-update hints; when absent, the existing local source remains the fallback.
1169
- Applications configure and close only the delivery facility through the
1170
- environment: attachment supervisors and their source reads belong to that facility.
1539
+ profile and exposes its `storageFactory`, `tenantIndex`, `nodeId`, and
1540
+ `close()` lifecycle. A healthy close with active contexts rejects without
1541
+ teardown; after required startup failure, close joins automatic cleanup and
1542
+ reports the original cause plus cleanup failures. After explicit
1543
+ `completeSetup()`, its `delivery` property
1544
+ is the usable shared public `Delivery` facade. A Bounded Context cannot build
1545
+ before setup, and a server does not start setup on the application's behalf.
1546
+ Neither API authenticates requests or supplies remote topology or a deployment
1547
+ policy.
1548
+
1549
+ `ServerEnvironmentDelivery` supplies an optional remote facility with `open()`,
1550
+ `inbox`, and `workRegistry` ports. Setup opens it once before creating the
1551
+ shared Delivery; failure closes acquired facilities. Its optional `source`
1552
+ supports remote shard snapshots and notifications through the environment's
1553
+ single supervisor. Local Delivery uses the environment's configured storage
1554
+ factory for its shared Inbox and work registry; the default factory is in-memory.
1555
+ Contexts register recipients with the same Delivery and never close that shared
1556
+ facility individually. Environment shutdown stops intake, drains local admitted
1557
+ work, then closes shared Delivery and configured facilities. Pending remote rows
1558
+ do not make a closing context wait indefinitely for other processes to finish.
1171
1559
 
1172
1560
  ## Signal identity and Aggregate semantics
1173
1561