@spine-event-engine/server 2.0.0-snapshot.23 → 2.0.0-snapshot.25

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 (300) hide show
  1. package/README.md +38 -11
  2. package/REFERENCE.md +278 -141
  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 +15 -10
  12. package/dist/agent/agent-history.d.ts.map +1 -1
  13. package/dist/agent/agent-history.js +26 -14
  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 +61 -0
  56. package/dist/agent/agent-live-read-runtime.d.ts.map +1 -0
  57. package/dist/agent/agent-live-read-runtime.js +121 -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/bus/command-bus.d.ts +14 -18
  64. package/dist/bus/command-bus.d.ts.map +1 -1
  65. package/dist/bus/command-bus.js +31 -48
  66. package/dist/bus/command-bus.js.map +1 -1
  67. package/dist/bus/event-bus.d.ts +82 -104
  68. package/dist/bus/event-bus.d.ts.map +1 -1
  69. package/dist/bus/event-bus.js +87 -127
  70. package/dist/bus/event-bus.js.map +1 -1
  71. package/dist/context/bounded-context.d.ts +143 -91
  72. package/dist/context/bounded-context.d.ts.map +1 -1
  73. package/dist/context/bounded-context.js +753 -359
  74. package/dist/context/bounded-context.js.map +1 -1
  75. package/dist/context/entity-inbox.d.ts +7 -2
  76. package/dist/context/entity-inbox.d.ts.map +1 -1
  77. package/dist/context/entity-inbox.js +43 -20
  78. package/dist/context/entity-inbox.js.map +1 -1
  79. package/dist/context/local-inbox-handoff.d.ts +35 -34
  80. package/dist/context/local-inbox-handoff.d.ts.map +1 -1
  81. package/dist/context/local-inbox-handoff.js +123 -135
  82. package/dist/context/local-inbox-handoff.js.map +1 -1
  83. package/dist/context/projection-handoff.d.ts +2 -2
  84. package/dist/context/projection-handoff.d.ts.map +1 -1
  85. package/dist/context/projection-handoff.js +12 -8
  86. package/dist/context/projection-handoff.js.map +1 -1
  87. package/dist/context/tenant-index.d.ts +36 -31
  88. package/dist/context/tenant-index.d.ts.map +1 -1
  89. package/dist/context/tenant-index.js +123 -125
  90. package/dist/context/tenant-index.js.map +1 -1
  91. package/dist/context/tenant-unknown-error.d.ts +33 -0
  92. package/dist/context/tenant-unknown-error.d.ts.map +1 -0
  93. package/dist/context/tenant-unknown-error.js +75 -0
  94. package/dist/context/tenant-unknown-error.js.map +1 -0
  95. package/dist/delivery/agent-delivery-scope.d.ts +66 -0
  96. package/dist/delivery/agent-delivery-scope.d.ts.map +1 -0
  97. package/dist/delivery/agent-delivery-scope.js +44 -0
  98. package/dist/delivery/agent-delivery-scope.js.map +1 -0
  99. package/dist/delivery/delivery-builder.d.ts +25 -1
  100. package/dist/delivery/delivery-builder.d.ts.map +1 -1
  101. package/dist/delivery/delivery-builder.js +89 -0
  102. package/dist/delivery/delivery-builder.js.map +1 -1
  103. package/dist/delivery/delivery-monitor.d.ts +12 -9
  104. package/dist/delivery/delivery-monitor.d.ts.map +1 -1
  105. package/dist/delivery/delivery-monitor.js +15 -9
  106. package/dist/delivery/delivery-monitor.js.map +1 -1
  107. package/dist/delivery/delivery-ports.d.ts +6 -13
  108. package/dist/delivery/delivery-ports.d.ts.map +1 -1
  109. package/dist/delivery/delivery-run-control.d.ts +21 -0
  110. package/dist/delivery/delivery-run-control.d.ts.map +1 -1
  111. package/dist/delivery/delivery-run-control.js +10 -0
  112. package/dist/delivery/delivery-run-control.js.map +1 -1
  113. package/dist/delivery/delivery-supervisor.d.ts +33 -5
  114. package/dist/delivery/delivery-supervisor.d.ts.map +1 -1
  115. package/dist/delivery/delivery-supervisor.js +178 -26
  116. package/dist/delivery/delivery-supervisor.js.map +1 -1
  117. package/dist/delivery/delivery-tenant.d.ts +17 -0
  118. package/dist/delivery/delivery-tenant.d.ts.map +1 -0
  119. package/dist/delivery/delivery-tenant.js +50 -0
  120. package/dist/delivery/delivery-tenant.js.map +1 -0
  121. package/dist/delivery/delivery.d.ts +96 -2
  122. package/dist/delivery/delivery.d.ts.map +1 -1
  123. package/dist/delivery/delivery.js +803 -89
  124. package/dist/delivery/delivery.js.map +1 -1
  125. package/dist/delivery/inbox-records.d.ts.map +1 -1
  126. package/dist/delivery/inbox-records.js +9 -16
  127. package/dist/delivery/inbox-records.js.map +1 -1
  128. package/dist/delivery/inbox-storage.d.ts +14 -11
  129. package/dist/delivery/inbox-storage.d.ts.map +1 -1
  130. package/dist/delivery/inbox-storage.js +72 -78
  131. package/dist/delivery/inbox-storage.js.map +1 -1
  132. package/dist/delivery/inbox.d.ts +9 -12
  133. package/dist/delivery/inbox.d.ts.map +1 -1
  134. package/dist/delivery/inbox.js +13 -15
  135. package/dist/delivery/inbox.js.map +1 -1
  136. package/dist/delivery/reception-observation.d.ts +64 -0
  137. package/dist/delivery/reception-observation.d.ts.map +1 -0
  138. package/dist/delivery/reception-observation.js +78 -0
  139. package/dist/delivery/reception-observation.js.map +1 -0
  140. package/dist/delivery/sharded-work-registry.d.ts +6 -0
  141. package/dist/delivery/sharded-work-registry.d.ts.map +1 -1
  142. package/dist/delivery/sharded-work-registry.js +41 -4
  143. package/dist/delivery/sharded-work-registry.js.map +1 -1
  144. package/dist/entity/entity-storage-descriptor.d.ts.map +1 -1
  145. package/dist/entity/entity-storage-descriptor.js +7 -4
  146. package/dist/entity/entity-storage-descriptor.js.map +1 -1
  147. package/dist/index.d.ts +4 -2
  148. package/dist/index.d.ts.map +1 -1
  149. package/dist/index.js +2 -1
  150. package/dist/index.js.map +1 -1
  151. package/dist/integration/external-messages.d.ts.map +1 -1
  152. package/dist/integration/external-messages.js +9 -15
  153. package/dist/integration/external-messages.js.map +1 -1
  154. package/dist/integration/integration-broker.d.ts.map +1 -1
  155. package/dist/integration/integration-broker.js +112 -6
  156. package/dist/integration/integration-broker.js.map +1 -1
  157. package/dist/integration/third-party-context.d.ts.map +1 -1
  158. package/dist/integration/third-party-context.js +7 -10
  159. package/dist/integration/third-party-context.js.map +1 -1
  160. package/dist/repository/primitive-id.js +26 -11
  161. package/dist/repository/primitive-id.js.map +1 -1
  162. package/dist/repository/repository.d.ts +33 -62
  163. package/dist/repository/repository.d.ts.map +1 -1
  164. package/dist/repository/repository.js +1475 -1827
  165. package/dist/repository/repository.js.map +1 -1
  166. package/dist/runtime/runtime.d.ts +24 -0
  167. package/dist/runtime/runtime.d.ts.map +1 -1
  168. package/dist/runtime/runtime.js +31 -0
  169. package/dist/runtime/runtime.js.map +1 -1
  170. package/dist/runtime/signal-metadata.d.ts.map +1 -1
  171. package/dist/runtime/signal-metadata.js +8 -15
  172. package/dist/runtime/signal-metadata.js.map +1 -1
  173. package/dist/runtime/signal-publisher.d.ts +8 -36
  174. package/dist/runtime/signal-publisher.d.ts.map +1 -1
  175. package/dist/runtime/signal-publisher.js +68 -61
  176. package/dist/runtime/signal-publisher.js.map +1 -1
  177. package/dist/runtime/standalone-handler-runtime.d.ts +0 -7
  178. package/dist/runtime/standalone-handler-runtime.d.ts.map +1 -1
  179. package/dist/runtime/standalone-handler-runtime.js +14 -130
  180. package/dist/runtime/standalone-handler-runtime.js.map +1 -1
  181. package/dist/server/managed-delivery-gate.d.ts +34 -0
  182. package/dist/server/managed-delivery-gate.d.ts.map +1 -0
  183. package/dist/server/managed-delivery-gate.js +70 -0
  184. package/dist/server/managed-delivery-gate.js.map +1 -0
  185. package/dist/server/managed-server-application.d.ts +2 -2
  186. package/dist/server/managed-server-application.d.ts.map +1 -1
  187. package/dist/server/managed-server-application.js +471 -178
  188. package/dist/server/managed-server-application.js.map +1 -1
  189. package/dist/server/node-coordinator.d.ts +14 -0
  190. package/dist/server/node-coordinator.d.ts.map +1 -1
  191. package/dist/server/node-coordinator.js +266 -45
  192. package/dist/server/node-coordinator.js.map +1 -1
  193. package/dist/server/server-environment.d.ts +203 -25
  194. package/dist/server/server-environment.d.ts.map +1 -1
  195. package/dist/server/server-environment.js +661 -133
  196. package/dist/server/server-environment.js.map +1 -1
  197. package/dist/server/server-log.d.ts +7 -0
  198. package/dist/server/server-log.d.ts.map +1 -1
  199. package/dist/server/server-log.js +18 -1
  200. package/dist/server/server-log.js.map +1 -1
  201. package/dist/server/server.d.ts +18 -32
  202. package/dist/server/server.d.ts.map +1 -1
  203. package/dist/server/server.js +62 -203
  204. package/dist/server/server.js.map +1 -1
  205. package/dist/services/spine-services.d.ts +1 -1
  206. package/dist/services/spine-services.d.ts.map +1 -1
  207. package/dist/services/spine-services.js +399 -370
  208. package/dist/services/spine-services.js.map +1 -1
  209. package/dist/stand/event-origin-filter.d.ts +16 -0
  210. package/dist/stand/event-origin-filter.d.ts.map +1 -0
  211. package/dist/stand/event-origin-filter.js +124 -0
  212. package/dist/stand/event-origin-filter.js.map +1 -0
  213. package/dist/stand/stand.d.ts +14 -0
  214. package/dist/stand/stand.d.ts.map +1 -1
  215. package/dist/stand/stand.js +53 -9
  216. package/dist/stand/stand.js.map +1 -1
  217. package/dist/stand/subscription-observer.d.ts.map +1 -1
  218. package/dist/stand/subscription-observer.js +61 -40
  219. package/dist/stand/subscription-observer.js.map +1 -1
  220. package/dist/stand/subscription-registry.d.ts +6 -2
  221. package/dist/stand/subscription-registry.d.ts.map +1 -1
  222. package/dist/stand/subscription-registry.js +15 -11
  223. package/dist/stand/subscription-registry.js.map +1 -1
  224. package/dist/stand/subscription-runtime.d.ts +23 -4
  225. package/dist/stand/subscription-runtime.d.ts.map +1 -1
  226. package/dist/stand/subscription-runtime.js +84 -13
  227. package/dist/stand/subscription-runtime.js.map +1 -1
  228. package/dist/testing/index.d.ts.map +1 -1
  229. package/dist/testing/index.js +3 -2
  230. package/dist/testing/index.js.map +1 -1
  231. package/dist/tsconfig.tsbuildinfo +1 -1
  232. package/package.json +15 -15
  233. package/dist/agent/agent-admission.d.ts +0 -80
  234. package/dist/agent/agent-admission.d.ts.map +0 -1
  235. package/dist/agent/agent-admission.js +0 -127
  236. package/dist/agent/agent-admission.js.map +0 -1
  237. package/dist/agent/agent-ai-runtime.d.ts +0 -76
  238. package/dist/agent/agent-ai-runtime.d.ts.map +0 -1
  239. package/dist/agent/agent-ai-runtime.js +0 -1269
  240. package/dist/agent/agent-ai-runtime.js.map +0 -1
  241. package/dist/agent/agent-execution-fault.d.ts +0 -18
  242. package/dist/agent/agent-execution-fault.d.ts.map +0 -1
  243. package/dist/agent/agent-execution-fault.js.map +0 -1
  244. package/dist/agent/agent-execution-session.d.ts +0 -103
  245. package/dist/agent/agent-execution-session.d.ts.map +0 -1
  246. package/dist/agent/agent-execution-session.js +0 -238
  247. package/dist/agent/agent-execution-session.js.map +0 -1
  248. package/dist/agent/agent-interaction-audit.d.ts +0 -58
  249. package/dist/agent/agent-interaction-audit.d.ts.map +0 -1
  250. package/dist/agent/agent-interaction-audit.js +0 -114
  251. package/dist/agent/agent-interaction-audit.js.map +0 -1
  252. package/dist/agent/agent-interaction-events.d.ts +0 -40
  253. package/dist/agent/agent-interaction-events.d.ts.map +0 -1
  254. package/dist/agent/agent-interaction-events.js +0 -129
  255. package/dist/agent/agent-interaction-events.js.map +0 -1
  256. package/dist/agent/agent-mcp-budget.d.ts +0 -125
  257. package/dist/agent/agent-mcp-budget.d.ts.map +0 -1
  258. package/dist/agent/agent-mcp-budget.js +0 -566
  259. package/dist/agent/agent-mcp-budget.js.map +0 -1
  260. package/dist/agent/agent-mcp-host.d.ts +0 -125
  261. package/dist/agent/agent-mcp-host.d.ts.map +0 -1
  262. package/dist/agent/agent-mcp-host.js.map +0 -1
  263. package/dist/agent/agent-mcp-runtime.d.ts.map +0 -1
  264. package/dist/agent/agent-mcp-runtime.js.map +0 -1
  265. package/dist/agent/agent-read-runtime.d.ts +0 -70
  266. package/dist/agent/agent-read-runtime.d.ts.map +0 -1
  267. package/dist/agent/agent-read-runtime.js +0 -320
  268. package/dist/agent/agent-read-runtime.js.map +0 -1
  269. package/dist/agent/agent-revisions.d.ts +0 -35
  270. package/dist/agent/agent-revisions.d.ts.map +0 -1
  271. package/dist/agent/agent-revisions.js +0 -133
  272. package/dist/agent/agent-revisions.js.map +0 -1
  273. package/dist/agent/agent-scheduler.d.ts +0 -99
  274. package/dist/agent/agent-scheduler.d.ts.map +0 -1
  275. package/dist/agent/agent-scheduler.js +0 -398
  276. package/dist/agent/agent-scheduler.js.map +0 -1
  277. package/dist/bus/saved-dispatcher-binding.d.ts +0 -96
  278. package/dist/bus/saved-dispatcher-binding.d.ts.map +0 -1
  279. package/dist/bus/saved-dispatcher-binding.js +0 -35
  280. package/dist/bus/saved-dispatcher-binding.js.map +0 -1
  281. package/dist/delivery/delivery-run-coordinator.d.ts +0 -218
  282. package/dist/delivery/delivery-run-coordinator.d.ts.map +0 -1
  283. package/dist/delivery/delivery-run-coordinator.js +0 -609
  284. package/dist/delivery/delivery-run-coordinator.js.map +0 -1
  285. package/dist/delivery/parked-delivery-obligations.d.ts +0 -182
  286. package/dist/delivery/parked-delivery-obligations.d.ts.map +0 -1
  287. package/dist/delivery/parked-delivery-obligations.js +0 -390
  288. package/dist/delivery/parked-delivery-obligations.js.map +0 -1
  289. package/dist/server/environment-attachment.d.ts +0 -356
  290. package/dist/server/environment-attachment.d.ts.map +0 -1
  291. package/dist/server/environment-attachment.js +0 -2062
  292. package/dist/server/environment-attachment.js.map +0 -1
  293. package/dist/server/environment-delivery-records.d.ts +0 -77
  294. package/dist/server/environment-delivery-records.d.ts.map +0 -1
  295. package/dist/server/environment-delivery-records.js +0 -282
  296. package/dist/server/environment-delivery-records.js.map +0 -1
  297. package/dist/server/environment-delivery-worker.d.ts +0 -161
  298. package/dist/server/environment-delivery-worker.d.ts.map +0 -1
  299. package/dist/server/environment-delivery-worker.js +0 -673
  300. 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),
@@ -521,7 +587,7 @@ The generated record declares `ApproveProjectSchema` as the input and
521
587
  manual decorator materialization, constructs the output-bearing metadata.
522
588
  Application builds emit the record to
523
589
  `generated/handler/generated-handler-registry.js`; those applications use
524
- `buildAsync()` with their compiled package root.
590
+ `build()` with their compiled package root.
525
591
 
526
592
  One `@Where({ eventField, equals })` equality filter may narrow an event- or
527
593
  rejection-consuming `@Subscribe`, `@React`, or `@Command` handler after type
@@ -531,18 +597,24 @@ repeated declarations fail closed. It is not an alternative routing mechanism.
531
597
  Configure logging through `ServerEnvironment` when assembling the server. The
532
598
  server installs that logger into its runtime components, where warnings and
533
599
  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.
600
+ Ordinary Aggregate, Process Manager, and Projection Inbox replay sends persisted
601
+ accepted work through the normal handler path, so those handler effects must be
602
+ replay-safe. An accepted Agent interaction is recorded by its receipt and is
603
+ never re-executed after interruption.
536
604
 
537
605
  ## Context assembly and entities
538
606
 
539
607
  Create a context with `BoundedContext.singleTenant(name)` or
540
608
  `BoundedContext.multitenant(name)`. Names are immutable. Use
541
- `withStorageFactory(factory)` to supply record/event storage.
609
+ `ServerEnvironment.when(type).use({ storageFactory: factory })` before explicit
610
+ environment setup to supply record/event storage to all contexts.
611
+ `withTenantIndex(index)` selects a different live membership directory for one
612
+ context; `context.tenantIndex` and `ServerEnvironment.instance().tenantIndex`
613
+ return the configured objects. Closing a context does not close either index.
542
614
  `withGeneratedRegistryRoot(root)` enables framework discovery of the generated
543
615
  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`,
616
+ `build()` asynchronously performs that discovery and assembly, including
617
+ explicit `Repository` registration. Await it before using the context. A built context contains `CommandBus`,
546
618
  `EventBus`, `Stand`, repositories, and its storage lifecycle.
547
619
  Trusted server-side code can call `context.getRepository(EntityClass)` to obtain
548
620
  the already registered repository for that exact constructor. The lookup does
@@ -654,24 +726,24 @@ start a new autonomous Entity loop.
654
726
  ### Configuration
655
727
 
656
728
  Register a factory-created `AiRegistry`, enable `persistSystemEvents()`, and
657
- configure `agentCodeRevision` plus `ai.models` for each Agent repository. Use
729
+ configure `ai.models` for each Agent repository. Use
658
730
  an empty `models` array when that Agent has no model calls. Readiness requires
659
- indexed Agent history and execution storage from the selected provider.
731
+ indexed Agent history and atomic live Agent commits from the selected provider.
660
732
  The [Support Bounded Context](../../examples/support/src/index.ts) uses generated
661
733
  registration with these options.
662
734
 
663
735
  Configuration has these scopes:
664
736
 
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. |
737
+ | Scope | Setting | Effect |
738
+ | --------------- | ------------------------------------------ | ---------------------------------------------------------------- |
739
+ | Environment | `ServerEnvironment.when(type).use({ ai })` | Default registry for Bounded Contexts. |
740
+ | Bounded Context | `BoundedContextBuilder.withAi(registry)` | Overrides environment AI for one Bounded Context. |
741
+ | Repository | `ai.defaultModels` | Generation and decision defaults before the registry's defaults. |
742
+ | Repository | `ai.allowedModels` | Deployment references the Agent may use. |
743
+ | Repository | `ai.resolveModel` | Optional accepted-source choice before the Agent handler. |
744
+ | Repository | `ai.authorizeSelection` | Authorizes explicit choices and staged preference changes. |
745
+ | Repository | `ai.invocationLimits` | Limits that can narrow the registry's whole-signal limits. |
746
+ | Instance | `this.ai.select(kind, ref)` | A saved preference applied to later accepted signals. |
675
747
 
676
748
  A prebuilt Bounded Context already has its registry; adding it to a server does not
677
749
  reconfigure it. An instance preference takes precedence over its repository
@@ -687,7 +759,7 @@ signal; `undefined` preserves it. This allows an Agent without a configured
687
759
  default to start after a deployment is appended to the bound registry. The
688
760
  runtime checks repository allowlists, capabilities and `authorizeSelection`
689
761
  before saving the selection and connection identity. A saved selection is reused
690
- on continuation. Resolver and authorization callbacks receive linked cancellation
762
+ for the current signal. Resolver and authorization callbacks receive linked cancellation
691
763
  and the smaller of the invocation deadline and registry hook timeout. An
692
764
  effective `this.ai.select()` change, including reset to inheritance, is
693
765
  authorized before the Entity transition and preference Events commit; a no-op
@@ -702,59 +774,30 @@ See [adapter configuration](../ai-vercel-ax/README.md).
702
774
 
703
775
  ### Acceptance and completion
704
776
 
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.
777
+ An accepted signal and recipient are admitted through ordinary Delivery. A
778
+ typed receipt prevents a duplicate signal from starting the same Agent turn.
779
+ Within one process, live capacity serializes turns for one Agent instance and
780
+ permits different instances up to configured limits. The shared registry's
781
+ capacity applies across Bounded Contexts using that registry. A waiting signal
782
+ stays in the ordinary Inbox until capacity can admit it; capacity release wakes
783
+ the ordinary Delivery worker. There is no Agent-specific discovery scheduler.
735
784
 
736
785
  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 original outgoing envelopes are committed under the
741
- same execution claim. A no-op still completes its execution record. Waiting for
742
- a provider does not hold a database transaction open.
743
-
744
- Recovery compares the registered handler, schema and policy with accepted work.
745
- A saved named call can reuse its result; changing that call's input or prepared
746
- request is a mismatch, not a new attempt. Domain code should derive its decisions
747
- from accepted signals and recorded reads. Arbitrary external effects performed
748
- by handler code are outside the model/tool journal.
749
-
750
- After completion, delivery uses the saved outgoing envelopes and recipient
751
- bindings. The producing handler and model are not rerun to deliver them.
752
- Downstream delivery is at least once: a recipient or standalone callback may be
753
- called again with the same envelope. Application effects must account for that.
754
- Generated repository and standalone receivers have the required binding metadata.
755
- Matching raw custom dispatchers without that metadata are rejected for Agent
756
- output; unrelated dispatchers and ordinary non-Agent posting keep their usual
757
- behavior.
786
+ `this.ai.invoke()` through the protected Spine facade. Calls in one handler
787
+ must be sequential and finish before it returns. Requests, results, and
788
+ validation failures are saved as audited history while work progresses. The
789
+ final accepted state, Version, preference changes, and Agent history use an
790
+ atomic live Agent commit. Outgoing Commands enter ordinary command delivery;
791
+ there is no saved Agent-private list to finish after a restart. Emitted domain Events
792
+ enter immutable Agent history before normal EventBus publication. A no-op or
793
+ preference-only turn can commit without a state Version increase. Waiting for a
794
+ provider does not hold a database transaction open.
795
+
796
+ An admitted turn uses a current session and cancellation guard. Shutdown drains
797
+ tracked work and prevents late results from changing Entity state or emitting
798
+ signals. It cannot undo external effects already performed by application code.
799
+ A restarted process can read retained receipts and audit history, but it does
800
+ not replay a model response or re-enter an interrupted Agent handler.
758
801
 
759
802
  ### Retained history
760
803
 
@@ -774,7 +817,7 @@ persistent provider when records must survive process termination.
774
817
  All methods return newest entries first. A request supplies positive `pageSize`
775
818
  and an optional opaque cursor; `nextCursor` continues toward older entries.
776
819
  There is no fixed 100-item or page-byte ceiling. Reads made during a handler count
777
- toward any configured invocation limits for recorded reads and recovery data. Ordering
820
+ toward any configured invocation limits for recorded reads. Ordering
778
821
  uses the full Spine `Time` timestamp, category and existing record ID. There is
779
822
  no repository-managed history counter. Cursors cannot be transferred across
780
823
  Agents, tenants, categories or conversations.
@@ -794,19 +837,15 @@ For a trusted application bridge, `context.getRepository(AgentClass)` returns
794
837
  the registered Agent `Repository`, which exposes
795
838
  `agentHistory(id, scope)` with the same four history methods and page contracts.
796
839
  The scope is explicit: pass `{}` in a single-tenant Bounded Context or
797
- `{ tenantId }` in a multitenant Bounded Context. The repository also exposes
798
- `agentExecution(id, sourceCommandOrEventId, scope)` for the exact recorded phase:
799
- `accepted`, `active`, `completed-pending-delivery`, `completed`, or `terminated`.
800
- An absent record returns `undefined`; it does not establish completion. These
801
- reads use indexed storage without restoring an Agent. The application bridge
802
- must authorize access before calling either method; actor metadata does not
803
- grant read permission.
804
-
805
- If a selected model's `authorizeUse` callback explicitly returns `false` at
806
- Agent claim time, the execution becomes `terminated` with one
807
- `AgentInvocationTerminated` System Event carrying `MODEL_USE_DENIED`. No Agent
808
- handler runs and no application-domain result Event is emitted. Callback
809
- exceptions and infrastructure failures remain distinct from this denial.
840
+ `{ tenantId }` in a multitenant Bounded Context. Reads use indexed storage
841
+ without restoring an Agent. The application bridge must authorize access;
842
+ actor metadata does not grant read permission.
843
+
844
+ If a selected model's `authorizeUse` callback explicitly returns `false`
845
+ before the handler, the turn records one `AgentInvocationTerminated` System
846
+ Event carrying `MODEL_USE_DENIED`. No handler runs, no application-domain
847
+ result Event is invented, and other failures remain distinct. Applications
848
+ may correlate this fact with the original source through paged Agent history.
810
849
 
811
850
  ## Signals, validation, and rejection behavior
812
851
 
@@ -814,8 +853,10 @@ exceptions and infrastructure failures remain distinct from this denial.
814
853
  before dispatcher or repository handler code runs. It raises the framework's
815
854
  command-validation failure, which `SpineServices` maps to
816
855
  `COMMAND_VALIDATION_ERROR` with a packed `spine.validation.ValidationError`.
817
- Entity transition validation failures map to
818
- `COMMAND_STATE_TRANSITION_VALIDATION_FAILED` with the same detail type.
856
+ Entity transition validation failures that escape service processing map to
857
+ `COMMAND_STATE_TRANSITION_VALIDATION_FAILED` with the same detail type. Managed
858
+ reception of ordinary Entity work sends post-handler transition rejection to `DeliveryMonitor`;
859
+ its default action acknowledges the failed input without storing invalid state.
819
860
  Framework-created runtime command and event metadata uses fresh Node secure
820
861
  UUIDs; fixed IDs belong only to existing source envelopes retained through the
821
862
  normal origin chain.
@@ -856,6 +897,21 @@ a starting time, and has no durable operation identity, progress, Inbox
856
897
  catch-up delivery, restart, resumption, or historical/live coordination. It is
857
898
  not JVM-equivalent Projection catch-up.
858
899
 
900
+ Event Topics accept `include_all` or equality filters on the complete
901
+ `context.past_message` Origin. The filter value must be a valid packed
902
+ `spine.core.Origin`; other Event field paths, operators, ID filters, empty
903
+ filter trees, and malformed values are rejected. Existing composite-filter
904
+ limits apply. This is the immediate previous signal, not any ancestor in a
905
+ causal chain. Tenant isolation remains independent of the filter.
906
+
907
+ Origin filters use Protobuf value equality for the entire supported message,
908
+ including actor context and grand-origin. Packed `Any` payloads retain their
909
+ exact type URL and bytes. Expected Origins with unknown fields in their nested
910
+ message structure are unsupported and rejected; actual Origins with such
911
+ unknown fields cannot match. This avoids silently ignoring fields while keeping
912
+ the same equality semantics as Spine JVM for supported filters. The same rule
913
+ applies to direct and stored subscription definitions.
914
+
859
915
  Active subscription streams and queues are process-local. `Stand` serves
860
916
  authoritative queries from current state and Entity subscriptions observe
861
917
  committed `EntityStateChanged` messages on the paired System Context EventBus,
@@ -881,7 +937,8 @@ group of complete server replicas when the framework handles process shutdown.
881
937
  and installs no process signal handlers; that host closes the returned handle.
882
938
  Both require a positive safe-integer
883
939
  `processCount` and an ESM `moduleUrl`; it never derives a process count from
884
- the machine. Its optional `host` and required nonzero `port` bind the public
940
+ the machine. Its optional `host` and required `port` (zero selects an OS-assigned
941
+ port) bind the public
885
942
  Coordinator listener. Every child executes that same module and calls the
886
943
  module's `createServer({ host: "127.0.0.1", port: 0 })`. The child reports its
887
944
  actual loopback endpoint only after its local readiness gates settle. The parent
@@ -900,11 +957,24 @@ inspect CPU availability and does not constrain the application's independently
900
957
  chosen `DeliveryStrategy` or shard count. Direct `Server.run()` and browser
901
958
  hosting remain independent of managed Node deployment.
902
959
 
960
+ Managed close drains Delivery before cancelling subscription relays. Child listeners
961
+ remain available through relay cancellation, and final child close follows relay
962
+ cleanup. A failed cleanup phase can be retried. Private child acknowledgement
963
+ and process reaping retain their finite process-control graces. A permanently
964
+ blocked application effect can keep explicit close pending.
965
+
903
966
  If no child is READY, Command and Query return gRPC `UNAVAILABLE`. The
904
967
  Coordinator does not enter application intake and does not retry the selected
905
968
  call on a sibling child. Subscription fan-out follows current READY members;
906
969
  later and replacement members attach the retained subscription before managed
907
970
  admission.
971
+ Each native child sends a response-only successful activation ACK after its
972
+ listener attaches. The Coordinator waits for every required child ACK before
973
+ emitting one ACK with the logical public subscription ID and Topic; a child
974
+ failure before readiness cancels admitted siblings. Business updates do not
975
+ serve as readiness signals, and later joining children do not emit another
976
+ logical ACK. An ACK confirms attachment, not durable replay or delivery of
977
+ future updates.
908
978
 
909
979
  `ServerOptions` is native-only: it configures contexts, resources, services,
910
980
  and the native listener. It has no `browser` option and the root package does
@@ -991,7 +1061,9 @@ delivery, global update ordering, nor cluster-complete notification delivery.
991
1061
  ## Delivery and environment
992
1062
 
993
1063
  `Inbox`, `InboxStorage`, `ShardIndex`, and `ShardedWorkRegistry` provide the
994
- local durable-row abstraction. Read limits are 1–1000; work leases are
1064
+ local durable-row abstraction. Inbox and shard storage require a single-tenant
1065
+ Delivery storage context shared by all tenants; the packed signal supplies
1066
+ the dispatch tenant. Read limits are 1–1000; work leases are
995
1067
  1000–2147483647 ms. Framework replay supports command handling, projection
996
1068
  updates, and process-manager reactions. Callbacks are at-least-once/replay-safe:
997
1069
  lost renewal can prevent stale finalization but cannot undo a callback already
@@ -1019,31 +1091,63 @@ absent or elapsed (`keepUntil <= now`). Delivery skips per-record mutation check
1019
1091
  and deletion attempts for rows whose deadline is still in the future. Cleanup
1020
1092
  and retained-row duplicate recognition use the same applicable clock. Eligible
1021
1093
  rows still receive final time and shard checks before deletion.
1022
- Direct local storage atomically verifies ownership and
1023
- the exact delivered snapshot during removal. A remote adapter may instead read
1024
- and compare the snapshot before sending a separate best-effort removal request;
1025
- that sequence is not an atomic compare-and-delete guarantee. Pending, retryable,
1026
- non-delivered, and still-protected rows remain. There is no additional retention
1027
- configuration, timer, or scheduler.
1028
-
1029
- `BoundedContextBuilder.withDeliveryStrategy(strategy)` snapshots a validated
1030
- immutable strategy for its Entity Inbox; the default is one shard. For example,
1031
- use the public builder chain:
1094
+ Direct local storage checks the supplied delivered status and deadline again,
1095
+ then deletes by ID while the operation is active. It does not re-read the stored
1096
+ row or compare its snapshot, and the shard session is not checked again after
1097
+ deletion. A row changed between the checks and deletion can therefore be
1098
+ removed. Cancellation stops subsequent cleanup attempts; deletions already
1099
+ completed remain. The remote adapter sends a separate bounded removal request,
1100
+ without an atomic compare-and-delete guarantee from this client. Pending,
1101
+ retryable, non-delivered, and still-protected rows are skipped by cleanup. There
1102
+ is no additional retention configuration, timer, or scheduler.
1103
+
1104
+ Configure one Delivery strategy for the environment before setup. It maps
1105
+ targets to shards across all contexts; the default is one shard. For example:
1032
1106
 
1033
1107
  ```ts
1034
- import { BoundedContext, UniformAcrossAllShards } from "@spine-event-engine/server";
1108
+ import {
1109
+ BoundedContext,
1110
+ EnvironmentType,
1111
+ ServerEnvironment,
1112
+ UniformAcrossAllShards,
1113
+ } from "@spine-event-engine/server";
1035
1114
 
1036
- const context = BoundedContext.singleTenant("Tasks")
1037
- .withDeliveryStrategy(UniformAcrossAllShards.forNumber(3))
1038
- .build();
1115
+ ServerEnvironment.when(EnvironmentType.Local).use({
1116
+ deliveryStrategy: UniformAcrossAllShards.forNumber(3),
1117
+ });
1118
+ await ServerEnvironment.instance().completeSetup();
1119
+ const context = await BoundedContext.singleTenant("Tasks").build();
1039
1120
  ```
1040
1121
 
1041
1122
  Aggregate commands and Process Manager or Agent commands/events derive their target shard
1042
1123
  internally and persist their envelope in the target Entity Inbox before any
1043
- handler runs. Local intake can directly drain the persisted Inbox in the
1044
- current request path. Attached `ServerEnvironment` ports acknowledge admission
1045
- and delivery workers replay it through the same path. Projection rows remain
1046
- separate.
1124
+ handler runs. Projection input uses the same environment Delivery and shared
1125
+ Inbox, with its separate recipient identity.
1126
+
1127
+ Local posting waits for the result of that signal's delivery attempt. For an
1128
+ Agent, successful acceptance and Inbox acknowledgement let posting finish while
1129
+ the live handler continues. If Agent execution capacity is unavailable, the input
1130
+ stays pending and the local call reports the existing command-posting error.
1131
+
1132
+ With remote Delivery and its environment supervisor, posting completes after the
1133
+ remote Inbox accepts the input and the shard notification is submitted. Processing
1134
+ may still be pending on another process. For example, importing an Event can return
1135
+ while another process holds its shard; the Projection update arrives after that
1136
+ process can dispatch the Event. Reception alone does not acknowledge delivery,
1137
+ create an Agent acceptance receipt, or prove that a handler ran.
1138
+
1139
+ A rejected remote receive operation rejects posting. If a local notification
1140
+ observer fails after reception succeeds, the failure is logged and the existing
1141
+ notifications and safety scan can find the pending work. The environment selects
1142
+ this behavior from its installed supervision; contexts have no attachment step or
1143
+ completion switch. Supplying custom ports without a source does not install remote
1144
+ supervision. Explicit `Delivery.run()` still returns the actual run result,
1145
+ including `SKIPPED` when another process is handling the shard.
1146
+ For ordinary Entity Inbox work, post-handler output and transition validation
1147
+ failures reach the reception monitor. Pre-handler input and routing errors and
1148
+ storage failures remain outside that monitor. Accepted Agent work has already
1149
+ acknowledged its Inbox row and does not enter this reception action. A detached
1150
+ run that throws emits a contained terminal error without exposing its message.
1047
1151
 
1048
1152
  `DeliveryBuilder` constructs a controlled `Delivery`; `DeliverySupervisor`
1049
1153
  receives `{ source, delivery, onMessage }`, manages bounded shard notifications
@@ -1053,6 +1157,11 @@ before source client/storage. `DeliverySource` is not configured on
1053
1157
  durable supervisor state, topology failover, exactly-once effects, or automatic
1054
1158
  retry of unknown remote mutations.
1055
1159
 
1160
+ Direct `DeliverySupervisor.close({ graceMs })` stops new admission and source
1161
+ activity. Its `graceMs` defaults to 30,000 ms and bounds active-work grace and
1162
+ release cleanup separately. After those waits, close may still await entered
1163
+ work that has not settled; it is not a hard total close deadline.
1164
+
1056
1165
  Each Inbox read is bounded to one page. That bound does not limit the total
1057
1166
  pending work: an active drain continues from the last row read until that scan
1058
1167
  ends. It restarts from the beginning only if the completed scan delivered
@@ -1073,35 +1182,63 @@ the remote server.
1073
1182
  `DeliveryMonitor` is an instantiable, customizable policy seam exposing
1074
1183
  asynchronous continuation, start/completion, failed-reception, pickup-failure,
1075
1184
  and already-picked hooks.
1076
- `FailedReception` supplies only `markDelivered()` and one immediate
1077
- `repeatDispatching()` action; the framework adds no attempt history, timer,
1078
- backoff, quarantine, dead-letter, receipt, marker, or scheduler policy. A failed
1079
- durable acknowledgement keeps that row pending, blocks later rows for its
1080
- target during the run, and does not prevent independent targets from running.
1185
+ `FailedReception` supplies `markDelivered()` and immediate
1186
+ `repeatDispatching()` actions for failed processing. The default marks a failed
1187
+ reception delivered; independent targets continue. A custom monitor may repeat
1188
+ the dispatch and is consulted again if that attempt fails. Monitor and selected
1189
+ action errors propagate. A successful handler followed by a failed acknowledgement
1190
+ retries acknowledgement up to three times without deliberately rerunning the
1191
+ handler. Exhausted acknowledgement leaves the row pending and does not call the
1192
+ reception monitor. A custom reception action that completes normally completes
1193
+ delivery and the enclosing stage acknowledges the row. An action that rejects
1194
+ propagates its error and leaves the row `TO_DELIVER`. `markDelivered()` does not
1195
+ mean domain processing succeeded.
1196
+ Managed repository replay sends actual handler failures to the monitor while
1197
+ storage and replay infrastructure errors propagate. A direct `onMessage` callback
1198
+ is treated as the endpoint. Handler effects and acknowledgement are separate,
1199
+ so a crash between them may redeliver.
1200
+ The framework adds no persisted attempts, quarantine, dead-letter, receipt, or
1201
+ marker policy. The supervisor rescans pending shards every 10 seconds by default;
1202
+ the stale-session threshold is separately 60 seconds.
1203
+ After a failed finite run, release-generated remote observations of that shard
1204
+ are held locally until the next periodic rescan, preventing an immediate
1205
+ self-triggered retry loop. Explicit notifications remain admissible. A newly
1206
+ enqueued remote row on that shard may wait for the next rescan; other shards
1207
+ continue, and other processes may each attempt the failed row before applying
1208
+ local suppression. This timing is not a delivery deadline.
1209
+
1210
+ `BoundedContext.close()` stops external admission, drains accepted framework
1211
+ work, and then closes buses, subscriptions, Stands, and repository bindings.
1212
+ Cleanup failures are aggregated and may be retried. A committed Entity Event,
1213
+ reactor or Process Manager Event, and System Event receives one first-publication
1214
+ attempt; a contained failure is logged and does not schedule publication again.
1215
+ Persisted System Events use a storage group derived from their System Context
1216
+ name and role, separate from domain Event history. Command acceptance
1217
+ alone does not promise recipient completion. Processing retries for Inbox rows
1218
+ and acknowledgement recovery remain separate Delivery behavior.
1081
1219
 
1082
1220
  `Environment` resolves the Node `local` or `production` profile once from
1083
1221
  `NODE_ENV`. `ServerEnvironment` resolves configured facilities once for that
1084
- profile and exposes its `storageFactory`, optional `delivery`, optional
1085
- `tracerFactory`, `nodeId`, and `close()` lifecycle. Applications do
1086
- not manage internal server attachments through this public API. Neither API
1087
- authenticates requests or supplies a production scheduler, remote topology,
1088
- storage adapter, or deployment policy.
1089
-
1090
- `ServerEnvironmentDelivery` extends the existing closeable facility shape with
1091
- `open()` plus generic `inbox` and `workRegistry` ports. After readiness, the
1092
- environment supplies those ports to both existing delivery paths: direct finite
1093
- `Delivery` construction and the supervisor's `DeliveryBuilder`. The environment
1094
- invokes `open()` once before attachment admission and coalesces concurrent
1095
- callers; rejection admits no attachment and a later attempt retries open. A
1096
- close-only local delivery remains source-compatible. After attachments retire,
1097
- environment close runs delivery, tracer, then storage and preserves retry
1098
- checkpoints for failed phases.
1099
-
1100
- `ServerEnvironmentDelivery.source` is optional. When present, its Admin source
1101
- is used by the environment supervisor for remote snapshots and
1102
- shard-update hints; when absent, the existing local source remains the fallback.
1103
- Applications configure and close only the delivery facility through the
1104
- environment: attachment supervisors and their source reads belong to that facility.
1222
+ profile and exposes its `storageFactory`, `tenantIndex`, `nodeId`, and
1223
+ `close()` lifecycle. A healthy close with active contexts rejects without
1224
+ teardown; after required startup failure, close joins automatic cleanup and
1225
+ reports the original cause plus cleanup failures. After explicit
1226
+ `completeSetup()`, its `delivery` property
1227
+ is the usable shared public `Delivery` facade. A Bounded Context cannot build
1228
+ before setup, and a server does not start setup on the application's behalf.
1229
+ Neither API authenticates requests or supplies remote topology or a deployment
1230
+ policy.
1231
+
1232
+ `ServerEnvironmentDelivery` supplies an optional remote facility with `open()`,
1233
+ `inbox`, and `workRegistry` ports. Setup opens it once before creating the
1234
+ shared Delivery; failure closes acquired facilities. Its optional `source`
1235
+ supports remote shard snapshots and notifications through the environment's
1236
+ single supervisor. Local Delivery uses the environment's configured storage
1237
+ factory for its shared Inbox and work registry; the default factory is in-memory.
1238
+ Contexts register recipients with the same Delivery and never close that shared
1239
+ facility individually. Environment shutdown stops intake, drains local admitted
1240
+ work, then closes shared Delivery and configured facilities. Pending remote rows
1241
+ do not make a closing context wait indefinitely for other processes to finish.
1105
1242
 
1106
1243
  ## Signal identity and Aggregate semantics
1107
1244